OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "net/disk_cache/tracing/tracing_cache_backend.h" | |
6 | |
7 #include "net/base/net_errors.h" | |
8 | |
9 namespace disk_cache { | |
10 | |
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> { | |
15 public: | |
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; | |
37 | |
38 private: | |
39 friend class base::RefCountedThreadSafe<EntryProxy>; | |
40 typedef TracingCacheBackend::Operation Operation; | |
41 virtual ~EntryProxy(); | |
42 | |
43 struct RwOpExtra { | |
44 int index; | |
45 int offset; | |
46 int buf_len; | |
47 bool truncate; | |
48 }; | |
49 | |
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, | |
54 int result); | |
55 Entry* entry_; | |
56 base::WeakPtr<TracingCacheBackend> backend_; | |
57 | |
58 DISALLOW_COPY_AND_ASSIGN(EntryProxy); | |
59 }; | |
60 | |
61 EntryProxy::EntryProxy(Entry *entry, TracingCacheBackend* backend) | |
62 : entry_(entry), | |
63 backend_(backend->AsWeakPtr()) { | |
64 } | |
65 | |
66 void EntryProxy::Doom() { | |
67 // TODO(pasko): Record the event. | |
68 entry_->Doom(); | |
69 } | |
70 | |
71 void EntryProxy::Close() { | |
72 // TODO(pasko): Record the event. | |
73 entry_->Close(); | |
74 Release(); | |
75 } | |
76 | |
77 std::string EntryProxy::GetKey() const { | |
78 return entry_->GetKey(); | |
79 } | |
80 | |
81 base::Time EntryProxy::GetLastUsed() const { | |
82 return entry_->GetLastUsed(); | |
83 } | |
84 | |
85 base::Time EntryProxy::GetLastModified() const { | |
86 return entry_->GetLastModified(); | |
87 } | |
88 | |
89 int32 EntryProxy::GetDataSize(int index) const { | |
90 return entry_->GetDataSize(index); | |
91 } | |
92 | |
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(); | |
96 RwOpExtra extra; | |
97 extra.index = index; | |
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); | |
107 } | |
108 return rv; | |
109 } | |
110 | |
111 int EntryProxy::WriteData(int index, int offset, IOBuffer* buf, int buf_len, | |
112 const CompletionCallback& callback, | |
113 bool truncate) { | |
114 base::TimeTicks start_time = base::TimeTicks::Now(); | |
115 RwOpExtra extra; | |
116 extra.index = index; | |
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), | |
123 truncate); | |
124 if (rv != net::ERR_IO_PENDING) { | |
125 RecordEvent(start_time, TracingCacheBackend::OP_WRITE, extra, rv); | |
126 } | |
127 return rv; | |
128 } | |
129 | |
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); | |
134 } | |
135 | |
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); | |
140 } | |
141 | |
142 int EntryProxy::GetAvailableRange(int64 offset, int len, int64* start, | |
143 const CompletionCallback& callback) { | |
144 return entry_->GetAvailableRange(offset, len, start, callback); | |
145 } | |
146 | |
147 bool EntryProxy::CouldBeSparse() const { | |
148 return entry_->CouldBeSparse(); | |
149 } | |
150 | |
151 void EntryProxy::CancelSparseIO() { | |
152 return entry_->CancelSparseIO(); | |
153 } | |
154 | |
155 int EntryProxy::ReadyForSparseIO(const CompletionCallback& callback) { | |
156 return entry_->ReadyForSparseIO(callback); | |
157 } | |
158 | |
159 void EntryProxy::RecordEvent(base::TimeTicks start_time, Operation op, | |
160 RwOpExtra extra, int result_to_record) { | |
161 // TODO(pasko): Implement. | |
162 } | |
163 | |
164 void EntryProxy::EntryOpComplete(base::TimeTicks start_time, Operation op, | |
165 RwOpExtra extra, const CompletionCallback& cb, | |
166 int result) { | |
167 RecordEvent(start_time, op, extra, result); | |
168 if (!cb.is_null()) { | |
169 cb.Run(result); | |
170 } | |
171 } | |
172 | |
173 EntryProxy::~EntryProxy() { | |
174 if (backend_.get()) { | |
175 backend_->OnDeleteEntry(entry_); | |
176 } | |
177 } | |
178 | |
179 TracingCacheBackend::TracingCacheBackend(scoped_ptr<Backend> backend) | |
180 : backend_(backend.Pass()) { | |
181 } | |
182 | |
183 TracingCacheBackend::~TracingCacheBackend() { | |
184 } | |
185 | |
186 net::CacheType TracingCacheBackend::GetCacheType() const { | |
187 return backend_->GetCacheType(); | |
188 } | |
189 | |
190 int32 TracingCacheBackend::GetEntryCount() const { | |
191 return backend_->GetEntryCount(); | |
192 } | |
193 | |
194 void TracingCacheBackend::RecordEvent(base::TimeTicks start_time, Operation op, | |
195 std::string key, Entry* entry, int rv) { | |
196 // TODO(pasko): Implement. | |
197 } | |
198 | |
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(); | |
205 return entry_proxy; | |
206 } | |
207 entry_proxy = new EntryProxy(entry, this); | |
208 entry_proxy->AddRef(); | |
209 open_entries_[entry] = entry_proxy; | |
210 return entry_proxy; | |
211 } | |
212 | |
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); | |
217 } | |
218 } | |
219 | |
220 void TracingCacheBackend::BackendOpComplete(base::TimeTicks start_time, | |
221 Operation op, | |
222 std::string key, | |
223 Entry** entry, | |
224 const CompletionCallback& callback, | |
225 int result) { | |
226 RecordEvent(start_time, op, key, *entry, result); | |
227 if (*entry) { | |
228 *entry = FindOrCreateEntryProxy(*entry); | |
229 } | |
230 if (!callback.is_null()) { | |
231 callback.Run(result); | |
232 } | |
233 } | |
234 | |
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); | |
240 } | |
241 | |
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, | |
248 callback)); | |
249 if (rv != net::ERR_IO_PENDING) { | |
250 RecordEvent(start_time, OP_OPEN, key, *entry, rv); | |
251 if (*entry) { | |
252 *entry = FindOrCreateEntryProxy(*entry); | |
253 } | |
254 } | |
255 return rv; | |
256 } | |
257 | |
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, | |
263 entry, callback)); | |
264 if (rv != net::ERR_IO_PENDING) { | |
265 RecordEvent(start_time, OP_CREATE, key, *entry, rv); | |
266 if (*entry) { | |
267 *entry = FindOrCreateEntryProxy(*entry); | |
268 } | |
269 } | |
270 return rv; | |
271 } | |
272 | |
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, | |
278 callback)); | |
279 if (rv != net::ERR_IO_PENDING) { | |
280 RecordEvent(start_time, OP_DOOM_ENTRY, key, NULL, rv); | |
281 } | |
282 return rv; | |
283 } | |
284 | |
285 int TracingCacheBackend::DoomAllEntries(const CompletionCallback& callback) { | |
286 return backend_->DoomAllEntries(callback); | |
287 } | |
288 | |
289 int TracingCacheBackend::DoomEntriesBetween(base::Time initial_time, | |
290 base::Time end_time, | |
291 const CompletionCallback& cb) { | |
292 return backend_->DoomEntriesBetween(initial_time, end_time, cb); | |
293 } | |
294 | |
295 int TracingCacheBackend::DoomEntriesSince(base::Time initial_time, | |
296 const CompletionCallback& callback) { | |
297 return backend_->DoomEntriesSince(initial_time, callback); | |
298 } | |
299 | |
300 int TracingCacheBackend::OpenNextEntry(void** iter, Entry** next_entry, | |
301 const CompletionCallback& callback) { | |
302 return backend_->OpenNextEntry(iter, next_entry, callback); | |
303 } | |
304 | |
305 void TracingCacheBackend::EndEnumeration(void** iter) { | |
306 return backend_->EndEnumeration(iter); | |
307 } | |
308 | |
309 void TracingCacheBackend::GetStats(StatsItems* stats) { | |
310 return backend_->GetStats(stats); | |
311 } | |
312 | |
313 void TracingCacheBackend::OnExternalCacheHit(const std::string& key) { | |
314 return backend_->OnExternalCacheHit(key); | |
315 } | |
316 | |
317 } // namespace disk_cache | |
OLD | NEW |