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/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 
     21 namespace base {
     22 class TaskRunner;
     23 }
     24 
     25 namespace net {
     26 class IOBuffer;
     27 }
     28 
     29 namespace disk_cache {
     30 
     31 class SimpleBackendImpl;
     32 class SimpleSynchronousEntry;
     33 struct SimpleEntryStat;
     34 struct 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.
     39 class 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