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