simple_entry_impl.h revision 58537e28ecd584eab876aee8be7156509866d23a
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/memory/weak_ptr.h"
15#include "base/threading/thread_checker.h"
16#include "net/base/cache_type.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
22namespace base {
23class TaskRunner;
24}
25
26namespace net {
27class IOBuffer;
28}
29
30namespace disk_cache {
31
32class SimpleBackendImpl;
33class SimpleSynchronousEntry;
34struct SimpleEntryStat;
35struct SimpleEntryCreationResults;
36
37// SimpleEntryImpl is the IO thread interface to an entry in the very simple
38// disk cache. It proxies for the SimpleSynchronousEntry, which performs IO
39// on the worker thread.
40class SimpleEntryImpl : public Entry, public base::RefCounted<SimpleEntryImpl>,
41    public base::SupportsWeakPtr<SimpleEntryImpl> {
42  friend class base::RefCounted<SimpleEntryImpl>;
43 public:
44  enum OperationsMode {
45    NON_OPTIMISTIC_OPERATIONS,
46    OPTIMISTIC_OPERATIONS,
47  };
48
49  SimpleEntryImpl(net::CacheType cache_type,
50                  const base::FilePath& path,
51                  uint64 entry_hash,
52                  OperationsMode operations_mode,
53                  SimpleBackendImpl* backend,
54                  net::NetLog* net_log);
55
56  // Adds another reader/writer to this entry, if possible, returning |this| to
57  // |entry|.
58  int OpenEntry(Entry** entry, const CompletionCallback& callback);
59
60  // Creates this entry, if possible. Returns |this| to |entry|.
61  int CreateEntry(Entry** entry, const CompletionCallback& callback);
62
63  // Identical to Backend::Doom() except that it accepts a CompletionCallback.
64  int DoomEntry(const CompletionCallback& callback);
65
66  const std::string& key() const { return key_; }
67  uint64 entry_hash() const { return entry_hash_; }
68  void SetKey(const std::string& key);
69
70  // From Entry:
71  virtual void Doom() OVERRIDE;
72  virtual void Close() OVERRIDE;
73  virtual std::string GetKey() const OVERRIDE;
74  virtual base::Time GetLastUsed() const OVERRIDE;
75  virtual base::Time GetLastModified() const OVERRIDE;
76  virtual int32 GetDataSize(int index) const OVERRIDE;
77  virtual int ReadData(int stream_index,
78                       int offset,
79                       net::IOBuffer* buf,
80                       int buf_len,
81                       const CompletionCallback& callback) OVERRIDE;
82  virtual int WriteData(int stream_index,
83                        int offset,
84                        net::IOBuffer* buf,
85                        int buf_len,
86                        const CompletionCallback& callback,
87                        bool truncate) OVERRIDE;
88  virtual int ReadSparseData(int64 offset,
89                             net::IOBuffer* buf,
90                             int buf_len,
91                             const CompletionCallback& callback) OVERRIDE;
92  virtual int WriteSparseData(int64 offset,
93                              net::IOBuffer* buf,
94                              int buf_len,
95                              const CompletionCallback& callback) OVERRIDE;
96  virtual int GetAvailableRange(int64 offset,
97                                int len,
98                                int64* start,
99                                const CompletionCallback& callback) OVERRIDE;
100  virtual bool CouldBeSparse() const OVERRIDE;
101  virtual void CancelSparseIO() OVERRIDE;
102  virtual int ReadyForSparseIO(const CompletionCallback& callback) OVERRIDE;
103
104 private:
105  class ScopedOperationRunner;
106  friend class ScopedOperationRunner;
107
108  enum State {
109    // The state immediately after construction, but before |synchronous_entry_|
110    // has been assigned. This is the state at construction, and is the only
111    // legal state to destruct an entry in.
112    STATE_UNINITIALIZED,
113
114    // This entry is available for regular IO.
115    STATE_READY,
116
117    // IO is currently in flight, operations must wait for completion before
118    // launching.
119    STATE_IO_PENDING,
120
121    // A failure occurred in the current or previous operation. All operations
122    // after that must fail, until we receive a Close().
123    STATE_FAILURE,
124  };
125
126  // Used in histograms, please only add entries at the end.
127  enum CheckCrcResult {
128    CRC_CHECK_NEVER_READ_TO_END = 0,
129    CRC_CHECK_NOT_DONE = 1,
130    CRC_CHECK_DONE = 2,
131    CRC_CHECK_NEVER_READ_AT_ALL = 3,
132    CRC_CHECK_MAX = 4,
133  };
134
135  virtual ~SimpleEntryImpl();
136
137  // Sets entry to STATE_UNINITIALIZED.
138  void MakeUninitialized();
139
140  // Return this entry to a user of the API in |out_entry|. Increments the user
141  // count.
142  void ReturnEntryToCaller(Entry** out_entry);
143
144  // Ensures that |this| is no longer referenced by our |backend_|, this
145  // guarantees that this entry cannot have OpenEntry/CreateEntry called again.
146  void RemoveSelfFromBackend();
147
148  // An error occured, and the SimpleSynchronousEntry should have Doomed
149  // us at this point. We need to remove |this| from the Backend and the
150  // index.
151  void MarkAsDoomed();
152
153  // Runs the next operation in the queue, if any and if there is no other
154  // operation running at the moment.
155  // WARNING: May delete |this|, as an operation in the queue can contain
156  // the last reference.
157  void RunNextOperationIfNeeded();
158
159  void OpenEntryInternal(bool have_index,
160                         const CompletionCallback& callback,
161                         Entry** out_entry);
162
163  void CreateEntryInternal(bool have_index,
164                           const CompletionCallback& callback,
165                           Entry** out_entry);
166
167  void CloseInternal();
168
169  void ReadDataInternal(int index,
170                        int offset,
171                        net::IOBuffer* buf,
172                        int buf_len,
173                        const CompletionCallback& callback);
174
175  void WriteDataInternal(int index,
176                         int offset,
177                         net::IOBuffer* buf,
178                         int buf_len,
179                         const CompletionCallback& callback,
180                         bool truncate);
181
182  void DoomEntryInternal(const CompletionCallback& callback);
183
184  // Called after a SimpleSynchronousEntry has completed CreateEntry() or
185  // OpenEntry(). If |in_sync_entry| is non-NULL, creation is successful and we
186  // can return |this| SimpleEntryImpl to |*out_entry|. Runs
187  // |completion_callback|.
188  void CreationOperationComplete(
189      const CompletionCallback& completion_callback,
190      const base::TimeTicks& start_time,
191      scoped_ptr<SimpleEntryCreationResults> in_results,
192      Entry** out_entry,
193      net::NetLog::EventType end_event_type);
194
195  // Called after we've closed and written the EOF record to our entry. Until
196  // this point it hasn't been safe to OpenEntry() the same entry, but from this
197  // point it is.
198  void CloseOperationComplete();
199
200  // Internal utility method used by other completion methods. Calls
201  // |completion_callback| after updating state and dooming on errors.
202  void EntryOperationComplete(int stream_index,
203                              const CompletionCallback& completion_callback,
204                              const SimpleEntryStat& entry_stat,
205                              scoped_ptr<int> result);
206
207  // Called after an asynchronous read. Updates |crc32s_| if possible.
208  void ReadOperationComplete(int stream_index,
209                             int offset,
210                             const CompletionCallback& completion_callback,
211                             scoped_ptr<uint32> read_crc32,
212                             scoped_ptr<base::Time> last_used,
213                             scoped_ptr<int> result);
214
215  // Called after an asynchronous write completes.
216  void WriteOperationComplete(int stream_index,
217                              const CompletionCallback& completion_callback,
218                              scoped_ptr<SimpleEntryStat> entry_stat,
219                              scoped_ptr<int> result);
220
221  // Called after an asynchronous doom completes.
222  void DoomOperationComplete(const CompletionCallback& callback,
223                             State state_to_restore,
224                             int result);
225
226  // Called after validating the checksums on an entry. Passes through the
227  // original result if successful, propogates the error if the checksum does
228  // not validate.
229  void ChecksumOperationComplete(
230      int stream_index,
231      int orig_result,
232      const CompletionCallback& completion_callback,
233      scoped_ptr<int> result);
234
235  // Called after completion of asynchronous IO and receiving file metadata for
236  // the entry in |entry_stat|. Updates the metadata in the entry and in the
237  // index to make them available on next IO operations.
238  void UpdateDataFromEntryStat(const SimpleEntryStat& entry_stat);
239
240  int64 GetDiskUsage() const;
241
242  // Used to report histograms.
243  void RecordReadIsParallelizable(const SimpleEntryOperation& operation) const;
244  void RecordWriteDependencyType(const SimpleEntryOperation& operation) const;
245
246  // All nonstatic SimpleEntryImpl methods should always be called on the IO
247  // thread, in all cases. |io_thread_checker_| documents and enforces this.
248  base::ThreadChecker io_thread_checker_;
249
250  const base::WeakPtr<SimpleBackendImpl> backend_;
251  const net::CacheType cache_type_;
252  const scoped_refptr<base::TaskRunner> worker_pool_;
253  const base::FilePath path_;
254  const uint64 entry_hash_;
255  const bool use_optimistic_operations_;
256  std::string key_;
257
258  // |last_used_|, |last_modified_| and |data_size_| are copied from the
259  // synchronous entry at the completion of each item of asynchronous IO.
260  // TODO(clamy): Unify last_used_ with data in the index.
261  base::Time last_used_;
262  base::Time last_modified_;
263  int32 data_size_[kSimpleEntryFileCount];
264
265  // Number of times this object has been returned from Backend::OpenEntry() and
266  // Backend::CreateEntry() without subsequent Entry::Close() calls. Used to
267  // notify the backend when this entry not used by any callers.
268  int open_count_;
269
270  bool doomed_;
271
272  State state_;
273
274  // When possible, we compute a crc32, for the data in each entry as we read or
275  // write. For each stream, |crc32s_[index]| is the crc32 of that stream from
276  // [0 .. |crc32s_end_offset_|). If |crc32s_end_offset_[index] == 0| then the
277  // value of |crc32s_[index]| is undefined.
278  int32 crc32s_end_offset_[kSimpleEntryFileCount];
279  uint32 crc32s_[kSimpleEntryFileCount];
280
281  // If |have_written_[index]| is true, we have written to the stream |index|.
282  bool have_written_[kSimpleEntryFileCount];
283
284  // Reflects how much CRC checking has been done with the entry. This state is
285  // reported on closing each entry stream.
286  CheckCrcResult crc_check_state_[kSimpleEntryFileCount];
287
288  // The |synchronous_entry_| is the worker thread object that performs IO on
289  // entries. It's owned by this SimpleEntryImpl whenever |executing_operation_|
290  // is false (i.e. when an operation is not pending on the worker pool). When
291  // an operation is being executed no one owns the synchronous entry. Therefore
292  // SimpleEntryImpl should not be deleted while an operation is running as that
293  // would leak the SimpleSynchronousEntry.
294  SimpleSynchronousEntry* synchronous_entry_;
295
296  std::queue<SimpleEntryOperation> pending_operations_;
297
298  net::BoundNetLog net_log_;
299
300  scoped_ptr<SimpleEntryOperation> executing_operation_;
301};
302
303}  // namespace disk_cache
304
305#endif  // NET_DISK_CACHE_SIMPLE_SIMPLE_ENTRY_IMPL_H_
306