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/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   virtual void Doom() OVERRIDE;
     84   virtual void Close() OVERRIDE;
     85   virtual std::string GetKey() const OVERRIDE;
     86   virtual base::Time GetLastUsed() const OVERRIDE;
     87   virtual base::Time GetLastModified() const OVERRIDE;
     88   virtual int32 GetDataSize(int index) const OVERRIDE;
     89   virtual int ReadData(int stream_index,
     90                        int offset,
     91                        net::IOBuffer* buf,
     92                        int buf_len,
     93                        const CompletionCallback& callback) OVERRIDE;
     94   virtual 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   virtual int ReadSparseData(int64 offset,
    101                              net::IOBuffer* buf,
    102                              int buf_len,
    103                              const CompletionCallback& callback) OVERRIDE;
    104   virtual int WriteSparseData(int64 offset,
    105                               net::IOBuffer* buf,
    106                               int buf_len,
    107                               const CompletionCallback& callback) OVERRIDE;
    108   virtual int GetAvailableRange(int64 offset,
    109                                 int len,
    110                                 int64* start,
    111                                 const CompletionCallback& callback) OVERRIDE;
    112   virtual bool CouldBeSparse() const OVERRIDE;
    113   virtual void CancelSparseIO() OVERRIDE;
    114   virtual 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   virtual ~SimpleEntryImpl();
    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_
    380