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 #ifndef NET_DISK_CACHE_SIMPLE_SIMPLE_ENTRY_IMPL_H_ | |
6 #define NET_DISK_CACHE_SIMPLE_SIMPLE_ENTRY_IMPL_H_ | |
7 | |
8 #include <queue> | |
9 #include <string> | |
10 | |
11 #include "base/files/file_path.h" | |
12 #include "base/memory/ref_counted.h" | |
13 #include "base/memory/scoped_ptr.h" | |
14 #include "base/threading/thread_checker.h" | |
15 #include "net/base/cache_type.h" | |
16 #include "net/base/net_export.h" | |
17 #include "net/base/net_log.h" | |
18 #include "net/disk_cache/disk_cache.h" | |
19 #include "net/disk_cache/simple/simple_entry_format.h" | |
20 #include "net/disk_cache/simple/simple_entry_operation.h" | |
21 | |
22 namespace base { | |
23 class TaskRunner; | |
24 } | |
25 | |
26 namespace net { | |
27 class GrowableIOBuffer; | |
28 class IOBuffer; | |
29 } | |
30 | |
31 namespace disk_cache { | |
32 | |
33 class SimpleBackendImpl; | |
34 class SimpleSynchronousEntry; | |
35 class SimpleEntryStat; | |
36 struct SimpleEntryCreationResults; | |
37 | |
38 // SimpleEntryImpl is the IO thread interface to an entry in the very simple | |
39 // disk cache. It proxies for the SimpleSynchronousEntry, which performs IO | |
40 // on the worker thread. | |
41 class NET_EXPORT_PRIVATE SimpleEntryImpl : public Entry, | |
42 public base::RefCounted<SimpleEntryImpl> { | |
43 friend class base::RefCounted<SimpleEntryImpl>; | |
44 public: | |
45 enum OperationsMode { | |
46 NON_OPTIMISTIC_OPERATIONS, | |
47 OPTIMISTIC_OPERATIONS, | |
48 }; | |
49 | |
50 // The Backend provides an |ActiveEntryProxy| instance to this entry when it | |
51 // is active, meaning it's the canonical entry for this |entry_hash_|. The | |
52 // entry can make itself inactive by deleting its proxy. | |
53 class ActiveEntryProxy { | |
54 public: | |
55 virtual ~ActiveEntryProxy() = 0; | |
56 }; | |
57 | |
58 SimpleEntryImpl(net::CacheType cache_type, | |
59 const base::FilePath& path, | |
60 uint64 entry_hash, | |
61 OperationsMode operations_mode, | |
62 SimpleBackendImpl* backend, | |
63 net::NetLog* net_log); | |
64 | |
65 void SetActiveEntryProxy( | |
66 scoped_ptr<ActiveEntryProxy> active_entry_proxy); | |
67 | |
68 // Adds another reader/writer to this entry, if possible, returning |this| to | |
69 // |entry|. | |
70 int OpenEntry(Entry** entry, const CompletionCallback& callback); | |
71 | |
72 // Creates this entry, if possible. Returns |this| to |entry|. | |
73 int CreateEntry(Entry** entry, const CompletionCallback& callback); | |
74 | |
75 // Identical to Backend::Doom() except that it accepts a CompletionCallback. | |
76 int DoomEntry(const CompletionCallback& callback); | |
77 | |
78 const std::string& key() const { return key_; } | |
79 uint64 entry_hash() const { return entry_hash_; } | |
80 void SetKey(const std::string& key); | |
81 | |
82 // From Entry: | |
83 void Doom() override; | |
84 void Close() override; | |
85 std::string GetKey() const override; | |
86 base::Time GetLastUsed() const override; | |
87 base::Time GetLastModified() const override; | |
88 int32 GetDataSize(int index) const override; | |
89 int ReadData(int stream_index, | |
90 int offset, | |
91 net::IOBuffer* buf, | |
92 int buf_len, | |
93 const CompletionCallback& callback) override; | |
94 int WriteData(int stream_index, | |
95 int offset, | |
96 net::IOBuffer* buf, | |
97 int buf_len, | |
98 const CompletionCallback& callback, | |
99 bool truncate) override; | |
100 int ReadSparseData(int64 offset, | |
101 net::IOBuffer* buf, | |
102 int buf_len, | |
103 const CompletionCallback& callback) override; | |
104 int WriteSparseData(int64 offset, | |
105 net::IOBuffer* buf, | |
106 int buf_len, | |
107 const CompletionCallback& callback) override; | |
108 int GetAvailableRange(int64 offset, | |
109 int len, | |
110 int64* start, | |
111 const CompletionCallback& callback) override; | |
112 bool CouldBeSparse() const override; | |
113 void CancelSparseIO() override; | |
114 int ReadyForSparseIO(const CompletionCallback& callback) override; | |
115 | |
116 private: | |
117 class ScopedOperationRunner; | |
118 friend class ScopedOperationRunner; | |
119 | |
120 enum State { | |
121 // The state immediately after construction, but before |synchronous_entry_| | |
122 // has been assigned. This is the state at construction, and is the only | |
123 // legal state to destruct an entry in. | |
124 STATE_UNINITIALIZED, | |
125 | |
126 // This entry is available for regular IO. | |
127 STATE_READY, | |
128 | |
129 // IO is currently in flight, operations must wait for completion before | |
130 // launching. | |
131 STATE_IO_PENDING, | |
132 | |
133 // A failure occurred in the current or previous operation. All operations | |
134 // after that must fail, until we receive a Close(). | |
135 STATE_FAILURE, | |
136 }; | |
137 | |
138 // Used in histograms, please only add entries at the end. | |
139 enum CheckCrcResult { | |
140 CRC_CHECK_NEVER_READ_TO_END = 0, | |
141 CRC_CHECK_NOT_DONE = 1, | |
142 CRC_CHECK_DONE = 2, | |
143 CRC_CHECK_NEVER_READ_AT_ALL = 3, | |
144 CRC_CHECK_MAX = 4, | |
145 }; | |
146 | |
147 ~SimpleEntryImpl() override; | |
148 | |
149 // Must be used to invoke a client-provided completion callback for an | |
150 // operation initiated through the backend (e.g. create, open) so that clients | |
151 // don't get notified after they deleted the backend (which they would not | |
152 // expect). | |
153 void PostClientCallback(const CompletionCallback& callback, int result); | |
154 | |
155 // Sets entry to STATE_UNINITIALIZED. | |
156 void MakeUninitialized(); | |
157 | |
158 // Return this entry to a user of the API in |out_entry|. Increments the user | |
159 // count. | |
160 void ReturnEntryToCaller(Entry** out_entry); | |
161 | |
162 // An error occured, and the SimpleSynchronousEntry should have Doomed | |
163 // us at this point. We need to remove |this| from the Backend and the | |
164 // index. | |
165 void MarkAsDoomed(); | |
166 | |
167 // Runs the next operation in the queue, if any and if there is no other | |
168 // operation running at the moment. | |
169 // WARNING: May delete |this|, as an operation in the queue can contain | |
170 // the last reference. | |
171 void RunNextOperationIfNeeded(); | |
172 | |
173 void OpenEntryInternal(bool have_index, | |
174 const CompletionCallback& callback, | |
175 Entry** out_entry); | |
176 | |
177 void CreateEntryInternal(bool have_index, | |
178 const CompletionCallback& callback, | |
179 Entry** out_entry); | |
180 | |
181 void CloseInternal(); | |
182 | |
183 void ReadDataInternal(int index, | |
184 int offset, | |
185 net::IOBuffer* buf, | |
186 int buf_len, | |
187 const CompletionCallback& callback); | |
188 | |
189 void WriteDataInternal(int index, | |
190 int offset, | |
191 net::IOBuffer* buf, | |
192 int buf_len, | |
193 const CompletionCallback& callback, | |
194 bool truncate); | |
195 | |
196 void ReadSparseDataInternal(int64 sparse_offset, | |
197 net::IOBuffer* buf, | |
198 int buf_len, | |
199 const CompletionCallback& callback); | |
200 | |
201 void WriteSparseDataInternal(int64 sparse_offset, | |
202 net::IOBuffer* buf, | |
203 int buf_len, | |
204 const CompletionCallback& callback); | |
205 | |
206 void GetAvailableRangeInternal(int64 sparse_offset, | |
207 int len, | |
208 int64* out_start, | |
209 const CompletionCallback& callback); | |
210 | |
211 void DoomEntryInternal(const CompletionCallback& callback); | |
212 | |
213 // Called after a SimpleSynchronousEntry has completed CreateEntry() or | |
214 // OpenEntry(). If |in_sync_entry| is non-NULL, creation is successful and we | |
215 // can return |this| SimpleEntryImpl to |*out_entry|. Runs | |
216 // |completion_callback|. | |
217 void CreationOperationComplete( | |
218 const CompletionCallback& completion_callback, | |
219 const base::TimeTicks& start_time, | |
220 scoped_ptr<SimpleEntryCreationResults> in_results, | |
221 Entry** out_entry, | |
222 net::NetLog::EventType end_event_type); | |
223 | |
224 // Called after we've closed and written the EOF record to our entry. Until | |
225 // this point it hasn't been safe to OpenEntry() the same entry, but from this | |
226 // point it is. | |
227 void CloseOperationComplete(); | |
228 | |
229 // Internal utility method used by other completion methods. Calls | |
230 // |completion_callback| after updating state and dooming on errors. | |
231 void EntryOperationComplete(const CompletionCallback& completion_callback, | |
232 const SimpleEntryStat& entry_stat, | |
233 scoped_ptr<int> result); | |
234 | |
235 // Called after an asynchronous read. Updates |crc32s_| if possible. | |
236 void ReadOperationComplete(int stream_index, | |
237 int offset, | |
238 const CompletionCallback& completion_callback, | |
239 scoped_ptr<uint32> read_crc32, | |
240 scoped_ptr<SimpleEntryStat> entry_stat, | |
241 scoped_ptr<int> result); | |
242 | |
243 // Called after an asynchronous write completes. | |
244 void WriteOperationComplete(int stream_index, | |
245 const CompletionCallback& completion_callback, | |
246 scoped_ptr<SimpleEntryStat> entry_stat, | |
247 scoped_ptr<int> result); | |
248 | |
249 void ReadSparseOperationComplete( | |
250 const CompletionCallback& completion_callback, | |
251 scoped_ptr<base::Time> last_used, | |
252 scoped_ptr<int> result); | |
253 | |
254 void WriteSparseOperationComplete( | |
255 const CompletionCallback& completion_callback, | |
256 scoped_ptr<SimpleEntryStat> entry_stat, | |
257 scoped_ptr<int> result); | |
258 | |
259 void GetAvailableRangeOperationComplete( | |
260 const CompletionCallback& completion_callback, | |
261 scoped_ptr<int> result); | |
262 | |
263 // Called after an asynchronous doom completes. | |
264 void DoomOperationComplete(const CompletionCallback& callback, | |
265 State state_to_restore, | |
266 int result); | |
267 | |
268 // Called after validating the checksums on an entry. Passes through the | |
269 // original result if successful, propogates the error if the checksum does | |
270 // not validate. | |
271 void ChecksumOperationComplete( | |
272 int stream_index, | |
273 int orig_result, | |
274 const CompletionCallback& completion_callback, | |
275 scoped_ptr<int> result); | |
276 | |
277 // Called after completion of asynchronous IO and receiving file metadata for | |
278 // the entry in |entry_stat|. Updates the metadata in the entry and in the | |
279 // index to make them available on next IO operations. | |
280 void UpdateDataFromEntryStat(const SimpleEntryStat& entry_stat); | |
281 | |
282 int64 GetDiskUsage() const; | |
283 | |
284 // Used to report histograms. | |
285 void RecordReadIsParallelizable(const SimpleEntryOperation& operation) const; | |
286 void RecordWriteDependencyType(const SimpleEntryOperation& operation) const; | |
287 | |
288 // Reads from the stream 0 data kept in memory. | |
289 int ReadStream0Data(net::IOBuffer* buf, int offset, int buf_len); | |
290 | |
291 // Copies data from |buf| to the internal in-memory buffer for stream 0. If | |
292 // |truncate| is set to true, the target buffer will be truncated at |offset| | |
293 // + |buf_len| before being written. | |
294 int SetStream0Data(net::IOBuffer* buf, | |
295 int offset, int buf_len, | |
296 bool truncate); | |
297 | |
298 // Updates |crc32s_| and |crc32s_end_offset_| for a write of the data in | |
299 // |buffer| on |stream_index|, starting at |offset| and of length |length|. | |
300 void AdvanceCrc(net::IOBuffer* buffer, | |
301 int offset, | |
302 int length, | |
303 int stream_index); | |
304 | |
305 scoped_ptr<ActiveEntryProxy> active_entry_proxy_; | |
306 | |
307 // All nonstatic SimpleEntryImpl methods should always be called on the IO | |
308 // thread, in all cases. |io_thread_checker_| documents and enforces this. | |
309 base::ThreadChecker io_thread_checker_; | |
310 | |
311 const base::WeakPtr<SimpleBackendImpl> backend_; | |
312 const net::CacheType cache_type_; | |
313 const scoped_refptr<base::TaskRunner> worker_pool_; | |
314 const base::FilePath path_; | |
315 const uint64 entry_hash_; | |
316 const bool use_optimistic_operations_; | |
317 std::string key_; | |
318 | |
319 // |last_used_|, |last_modified_| and |data_size_| are copied from the | |
320 // synchronous entry at the completion of each item of asynchronous IO. | |
321 // TODO(clamy): Unify last_used_ with data in the index. | |
322 base::Time last_used_; | |
323 base::Time last_modified_; | |
324 int32 data_size_[kSimpleEntryStreamCount]; | |
325 int32 sparse_data_size_; | |
326 | |
327 // Number of times this object has been returned from Backend::OpenEntry() and | |
328 // Backend::CreateEntry() without subsequent Entry::Close() calls. Used to | |
329 // notify the backend when this entry not used by any callers. | |
330 int open_count_; | |
331 | |
332 bool doomed_; | |
333 | |
334 State state_; | |
335 | |
336 // When possible, we compute a crc32, for the data in each entry as we read or | |
337 // write. For each stream, |crc32s_[index]| is the crc32 of that stream from | |
338 // [0 .. |crc32s_end_offset_|). If |crc32s_end_offset_[index] == 0| then the | |
339 // value of |crc32s_[index]| is undefined. | |
340 int32 crc32s_end_offset_[kSimpleEntryStreamCount]; | |
341 uint32 crc32s_[kSimpleEntryStreamCount]; | |
342 | |
343 // If |have_written_[index]| is true, we have written to the file that | |
344 // contains stream |index|. | |
345 bool have_written_[kSimpleEntryStreamCount]; | |
346 | |
347 // Reflects how much CRC checking has been done with the entry. This state is | |
348 // reported on closing each entry stream. | |
349 CheckCrcResult crc_check_state_[kSimpleEntryStreamCount]; | |
350 | |
351 // The |synchronous_entry_| is the worker thread object that performs IO on | |
352 // entries. It's owned by this SimpleEntryImpl whenever |executing_operation_| | |
353 // is false (i.e. when an operation is not pending on the worker pool). When | |
354 // an operation is being executed no one owns the synchronous entry. Therefore | |
355 // SimpleEntryImpl should not be deleted while an operation is running as that | |
356 // would leak the SimpleSynchronousEntry. | |
357 SimpleSynchronousEntry* synchronous_entry_; | |
358 | |
359 std::queue<SimpleEntryOperation> pending_operations_; | |
360 | |
361 net::BoundNetLog net_log_; | |
362 | |
363 scoped_ptr<SimpleEntryOperation> executing_operation_; | |
364 | |
365 // Unlike other streams, stream 0 data is read from the disk when the entry is | |
366 // opened, and then kept in memory. All read/write operations on stream 0 | |
367 // affect the |stream_0_data_| buffer. When the entry is closed, | |
368 // |stream_0_data_| is written to the disk. | |
369 // Stream 0 is kept in memory because it is stored in the same file as stream | |
370 // 1 on disk, to reduce the number of file descriptors and save disk space. | |
371 // This strategy allows stream 1 to change size easily. Since stream 0 is only | |
372 // used to write HTTP headers, the memory consumption of keeping it in memory | |
373 // is acceptable. | |
374 scoped_refptr<net::GrowableIOBuffer> stream_0_data_; | |
375 }; | |
376 | |
377 } // namespace disk_cache | |
378 | |
379 #endif // NET_DISK_CACHE_SIMPLE_SIMPLE_ENTRY_IMPL_H_ | |
OLD | NEW |