1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/disk_cache/tracing_cache_backend.h"
7 #include "net/base/net_errors.h"
11 // Proxies entry objects created by the real underlying backend. Backend users
12 // will only see the proxy entries. It is necessary for recording the backend
13 // operations since often non-trivial work is invoked directly on entries.
14 class EntryProxy
: public Entry
, public base::RefCountedThreadSafe
<EntryProxy
> {
16 EntryProxy(Entry
*entry
, TracingCacheBackend
* backend
);
17 virtual void Doom() OVERRIDE
;
18 virtual void Close() OVERRIDE
;
19 virtual std::string
GetKey() const OVERRIDE
;
20 virtual base::Time
GetLastUsed() const OVERRIDE
;
21 virtual base::Time
GetLastModified() const OVERRIDE
;
22 virtual int32
GetDataSize(int index
) const OVERRIDE
;
23 virtual int ReadData(int index
, int offset
, IOBuffer
* buf
, int buf_len
,
24 const CompletionCallback
& callback
) OVERRIDE
;
25 virtual int WriteData(int index
, int offset
, IOBuffer
* buf
, int buf_len
,
26 const CompletionCallback
& callback
,
27 bool truncate
) OVERRIDE
;
28 virtual int ReadSparseData(int64 offset
, IOBuffer
* buf
, int buf_len
,
29 const CompletionCallback
& callback
) OVERRIDE
;
30 virtual int WriteSparseData(int64 offset
, IOBuffer
* buf
, int buf_len
,
31 const CompletionCallback
& callback
) OVERRIDE
;
32 virtual int GetAvailableRange(int64 offset
, int len
, int64
* start
,
33 const CompletionCallback
& callback
) OVERRIDE
;
34 virtual bool CouldBeSparse() const OVERRIDE
;
35 virtual void CancelSparseIO() OVERRIDE
;
36 virtual int ReadyForSparseIO(const CompletionCallback
& callback
) OVERRIDE
;
39 friend class base::RefCountedThreadSafe
<EntryProxy
>;
40 typedef TracingCacheBackend::Operation Operation
;
41 virtual ~EntryProxy();
50 void RecordEvent(base::TimeTicks start_time
, Operation op
, RwOpExtra extra
,
51 int result_to_record
);
52 void EntryOpComplete(base::TimeTicks start_time
, Operation op
,
53 RwOpExtra extra
, const CompletionCallback
& cb
,
56 base::WeakPtr
<TracingCacheBackend
> backend_
;
58 DISALLOW_COPY_AND_ASSIGN(EntryProxy
);
61 EntryProxy::EntryProxy(Entry
*entry
, TracingCacheBackend
* backend
)
63 backend_(backend
->AsWeakPtr()) {
66 void EntryProxy::Doom() {
67 // TODO(pasko): Record the event.
71 void EntryProxy::Close() {
72 // TODO(pasko): Record the event.
77 std::string
EntryProxy::GetKey() const {
78 return entry_
->GetKey();
81 base::Time
EntryProxy::GetLastUsed() const {
82 return entry_
->GetLastUsed();
85 base::Time
EntryProxy::GetLastModified() const {
86 return entry_
->GetLastModified();
89 int32
EntryProxy::GetDataSize(int index
) const {
90 return entry_
->GetDataSize(index
);
93 int EntryProxy::ReadData(int index
, int offset
, IOBuffer
* buf
, int buf_len
,
94 const CompletionCallback
& callback
) {
95 base::TimeTicks start_time
= base::TimeTicks::Now();
98 extra
.offset
= offset
;
99 extra
.buf_len
= buf_len
;
100 extra
.truncate
= false;
101 int rv
= entry_
->ReadData(
102 index
, offset
, buf
, buf_len
,
103 base::Bind(&EntryProxy::EntryOpComplete
, this, start_time
,
104 TracingCacheBackend::OP_READ
, extra
, callback
));
105 if (rv
!= net::ERR_IO_PENDING
) {
106 RecordEvent(start_time
, TracingCacheBackend::OP_READ
, extra
, rv
);
111 int EntryProxy::WriteData(int index
, int offset
, IOBuffer
* buf
, int buf_len
,
112 const CompletionCallback
& callback
,
114 base::TimeTicks start_time
= base::TimeTicks::Now();
117 extra
.offset
= offset
;
118 extra
.buf_len
= buf_len
;
119 extra
.truncate
= truncate
;
120 int rv
= entry_
->WriteData(index
, offset
, buf
, buf_len
,
121 base::Bind(&EntryProxy::EntryOpComplete
, this, start_time
,
122 TracingCacheBackend::OP_WRITE
, extra
, callback
),
124 if (rv
!= net::ERR_IO_PENDING
) {
125 RecordEvent(start_time
, TracingCacheBackend::OP_WRITE
, extra
, rv
);
130 int EntryProxy::ReadSparseData(int64 offset
, IOBuffer
* buf
, int buf_len
,
131 const CompletionCallback
& callback
) {
132 // TODO(pasko): Record the event.
133 return entry_
->ReadSparseData(offset
, buf
, buf_len
, callback
);
136 int EntryProxy::WriteSparseData(int64 offset
, IOBuffer
* buf
, int buf_len
,
137 const CompletionCallback
& callback
) {
138 // TODO(pasko): Record the event.
139 return entry_
->WriteSparseData(offset
, buf
, buf_len
, callback
);
142 int EntryProxy::GetAvailableRange(int64 offset
, int len
, int64
* start
,
143 const CompletionCallback
& callback
) {
144 return entry_
->GetAvailableRange(offset
, len
, start
, callback
);
147 bool EntryProxy::CouldBeSparse() const {
148 return entry_
->CouldBeSparse();
151 void EntryProxy::CancelSparseIO() {
152 return entry_
->CancelSparseIO();
155 int EntryProxy::ReadyForSparseIO(const CompletionCallback
& callback
) {
156 return entry_
->ReadyForSparseIO(callback
);
159 void EntryProxy::RecordEvent(base::TimeTicks start_time
, Operation op
,
160 RwOpExtra extra
, int result_to_record
) {
161 // TODO(pasko): Implement.
164 void EntryProxy::EntryOpComplete(base::TimeTicks start_time
, Operation op
,
165 RwOpExtra extra
, const CompletionCallback
& cb
,
167 RecordEvent(start_time
, op
, extra
, result
);
173 EntryProxy::~EntryProxy() {
174 if (backend_
.get()) {
175 backend_
->OnDeleteEntry(entry_
);
179 TracingCacheBackend::TracingCacheBackend(Backend
* backend
)
180 : backend_(backend
) {
183 TracingCacheBackend::~TracingCacheBackend() {
186 net::CacheType
TracingCacheBackend::GetCacheType() const {
187 return backend_
->GetCacheType();
190 int32
TracingCacheBackend::GetEntryCount() const {
191 return backend_
->GetEntryCount();
194 void TracingCacheBackend::RecordEvent(base::TimeTicks start_time
, Operation op
,
195 std::string key
, Entry
* entry
, int rv
) {
196 // TODO(pasko): Implement.
199 EntryProxy
* TracingCacheBackend::FindOrCreateEntryProxy(Entry
* entry
) {
200 EntryProxy
* entry_proxy
;
201 EntryToProxyMap::iterator it
= open_entries_
.find(entry
);
202 if (it
!= open_entries_
.end()) {
203 entry_proxy
= it
->second
;
204 entry_proxy
->AddRef();
207 entry_proxy
= new EntryProxy(entry
, this);
208 entry_proxy
->AddRef();
209 open_entries_
[entry
] = entry_proxy
;
213 void TracingCacheBackend::OnDeleteEntry(Entry
* entry
) {
214 EntryToProxyMap::iterator it
= open_entries_
.find(entry
);
215 if (it
!= open_entries_
.end()) {
216 open_entries_
.erase(it
);
220 void TracingCacheBackend::BackendOpComplete(base::TimeTicks start_time
,
224 const CompletionCallback
& callback
,
226 RecordEvent(start_time
, op
, key
, *entry
, result
);
228 *entry
= FindOrCreateEntryProxy(*entry
);
230 if (!callback
.is_null()) {
231 callback
.Run(result
);
235 net::CompletionCallback
TracingCacheBackend::BindCompletion(
236 Operation op
, base::TimeTicks start_time
, const std::string
& key
,
237 Entry
**entry
, const net::CompletionCallback
& cb
) {
238 return base::Bind(&TracingCacheBackend::BackendOpComplete
,
239 AsWeakPtr(), start_time
, op
, key
, entry
, cb
);
242 int TracingCacheBackend::OpenEntry(const std::string
& key
, Entry
** entry
,
243 const CompletionCallback
& callback
) {
244 DCHECK(*entry
== NULL
);
245 base::TimeTicks start_time
= base::TimeTicks::Now();
246 int rv
= backend_
->OpenEntry(key
, entry
,
247 BindCompletion(OP_OPEN
, start_time
, key
, entry
,
249 if (rv
!= net::ERR_IO_PENDING
) {
250 RecordEvent(start_time
, OP_OPEN
, key
, *entry
, rv
);
252 *entry
= FindOrCreateEntryProxy(*entry
);
258 int TracingCacheBackend::CreateEntry(const std::string
& key
, Entry
** entry
,
259 const CompletionCallback
& callback
) {
260 base::TimeTicks start_time
= base::TimeTicks::Now();
261 int rv
= backend_
->CreateEntry(key
, entry
,
262 BindCompletion(OP_CREATE
, start_time
, key
,
264 if (rv
!= net::ERR_IO_PENDING
) {
265 RecordEvent(start_time
, OP_CREATE
, key
, *entry
, rv
);
267 *entry
= FindOrCreateEntryProxy(*entry
);
273 int TracingCacheBackend::DoomEntry(const std::string
& key
,
274 const CompletionCallback
& callback
) {
275 base::TimeTicks start_time
= base::TimeTicks::Now();
276 int rv
= backend_
->DoomEntry(key
, BindCompletion(OP_DOOM_ENTRY
,
277 start_time
, key
, NULL
,
279 if (rv
!= net::ERR_IO_PENDING
) {
280 RecordEvent(start_time
, OP_DOOM_ENTRY
, key
, NULL
, rv
);
285 int TracingCacheBackend::DoomAllEntries(const CompletionCallback
& callback
) {
286 return backend_
->DoomAllEntries(callback
);
289 int TracingCacheBackend::DoomEntriesBetween(base::Time initial_time
,
291 const CompletionCallback
& cb
) {
292 return backend_
->DoomEntriesBetween(initial_time
, end_time
, cb
);
295 int TracingCacheBackend::DoomEntriesSince(base::Time initial_time
,
296 const CompletionCallback
& callback
) {
297 return backend_
->DoomEntriesSince(initial_time
, callback
);
300 int TracingCacheBackend::OpenNextEntry(void** iter
, Entry
** next_entry
,
301 const CompletionCallback
& callback
) {
302 return backend_
->OpenNextEntry(iter
, next_entry
, callback
);
305 void TracingCacheBackend::EndEnumeration(void** iter
) {
306 return backend_
->EndEnumeration(iter
);
309 void TracingCacheBackend::GetStats(StatsItems
* stats
) {
310 return backend_
->GetStats(stats
);
313 void TracingCacheBackend::OnExternalCacheHit(const std::string
& key
) {
314 return backend_
->OnExternalCacheHit(key
);
317 } // namespace disk_cache