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