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_BACKEND_IMPL_H_
      6 #define NET_DISK_CACHE_SIMPLE_SIMPLE_BACKEND_IMPL_H_
      7 
      8 #include <string>
      9 #include <utility>
     10 #include <vector>
     11 
     12 #include "base/callback_forward.h"
     13 #include "base/compiler_specific.h"
     14 #include "base/containers/hash_tables.h"
     15 #include "base/files/file_path.h"
     16 #include "base/memory/ref_counted.h"
     17 #include "base/memory/scoped_ptr.h"
     18 #include "base/memory/weak_ptr.h"
     19 #include "base/task_runner.h"
     20 #include "base/time/time.h"
     21 #include "net/base/cache_type.h"
     22 #include "net/disk_cache/disk_cache.h"
     23 #include "net/disk_cache/simple/simple_entry_impl.h"
     24 #include "net/disk_cache/simple/simple_index_delegate.h"
     25 
     26 namespace base {
     27 class SingleThreadTaskRunner;
     28 class TaskRunner;
     29 }
     30 
     31 namespace disk_cache {
     32 
     33 // SimpleBackendImpl is a new cache backend that stores entries in individual
     34 // files.
     35 // See http://www.chromium.org/developers/design-documents/network-stack/disk-cache/very-simple-backend
     36 //
     37 // The non-static functions below must be called on the IO thread unless
     38 // otherwise stated.
     39 
     40 class SimpleEntryImpl;
     41 class SimpleIndex;
     42 
     43 class NET_EXPORT_PRIVATE SimpleBackendImpl : public Backend,
     44     public SimpleIndexDelegate,
     45     public base::SupportsWeakPtr<SimpleBackendImpl> {
     46  public:
     47   SimpleBackendImpl(const base::FilePath& path, int max_bytes,
     48                     net::CacheType cache_type,
     49                     base::SingleThreadTaskRunner* cache_thread,
     50                     net::NetLog* net_log);
     51 
     52   virtual ~SimpleBackendImpl();
     53 
     54   net::CacheType cache_type() const { return cache_type_; }
     55   SimpleIndex* index() { return index_.get(); }
     56 
     57   base::TaskRunner* worker_pool() { return worker_pool_.get(); }
     58 
     59   int Init(const CompletionCallback& completion_callback);
     60 
     61   // Sets the maximum size for the total amount of data stored by this instance.
     62   bool SetMaxSize(int max_bytes);
     63 
     64   // Returns the maximum file size permitted in this backend.
     65   int GetMaxFileSize() const;
     66 
     67   // Removes |entry| from the |active_entries_| set, forcing future Open/Create
     68   // operations to construct a new object.
     69   void OnDeactivated(const SimpleEntryImpl* entry);
     70 
     71   // Flush our SequencedWorkerPool.
     72   static void FlushWorkerPoolForTesting();
     73 
     74   // The entry for |entry_hash| is being doomed; the backend will not attempt
     75   // run new operations for this |entry_hash| until the Doom is completed.
     76   void OnDoomStart(uint64 entry_hash);
     77 
     78   // The entry for |entry_hash| has been successfully doomed, we can now allow
     79   // operations on this entry, and we can run any operations enqueued while the
     80   // doom completed.
     81   void OnDoomComplete(uint64 entry_hash);
     82 
     83   // SimpleIndexDelegate:
     84   virtual void DoomEntries(std::vector<uint64>* entry_hashes,
     85                            const CompletionCallback& callback) OVERRIDE;
     86 
     87   // Backend:
     88   virtual net::CacheType GetCacheType() const OVERRIDE;
     89   virtual int32 GetEntryCount() const OVERRIDE;
     90   virtual int OpenEntry(const std::string& key, Entry** entry,
     91                         const CompletionCallback& callback) OVERRIDE;
     92   virtual int CreateEntry(const std::string& key, Entry** entry,
     93                           const CompletionCallback& callback) OVERRIDE;
     94   virtual int DoomEntry(const std::string& key,
     95                         const CompletionCallback& callback) OVERRIDE;
     96   virtual int DoomAllEntries(const CompletionCallback& callback) OVERRIDE;
     97   virtual int DoomEntriesBetween(base::Time initial_time,
     98                                  base::Time end_time,
     99                                  const CompletionCallback& callback) OVERRIDE;
    100   virtual int DoomEntriesSince(base::Time initial_time,
    101                                const CompletionCallback& callback) OVERRIDE;
    102   virtual int OpenNextEntry(void** iter, Entry** next_entry,
    103                             const CompletionCallback& callback) OVERRIDE;
    104   virtual void EndEnumeration(void** iter) OVERRIDE;
    105   virtual void GetStats(
    106       std::vector<std::pair<std::string, std::string> >* stats) OVERRIDE;
    107   virtual void OnExternalCacheHit(const std::string& key) OVERRIDE;
    108 
    109  private:
    110   typedef base::hash_map<uint64, base::WeakPtr<SimpleEntryImpl> > EntryMap;
    111 
    112   typedef base::Callback<void(base::Time mtime, uint64 max_size, int result)>
    113       InitializeIndexCallback;
    114 
    115   // Return value of InitCacheStructureOnDisk().
    116   struct DiskStatResult {
    117     base::Time cache_dir_mtime;
    118     uint64 max_size;
    119     bool detected_magic_number_mismatch;
    120     int net_error;
    121   };
    122 
    123   void InitializeIndex(const CompletionCallback& callback,
    124                        const DiskStatResult& result);
    125 
    126   // Dooms all entries previously accessed between |initial_time| and
    127   // |end_time|. Invoked when the index is ready.
    128   void IndexReadyForDoom(base::Time initial_time,
    129                          base::Time end_time,
    130                          const CompletionCallback& callback,
    131                          int result);
    132 
    133   // Try to create the directory if it doesn't exist. This must run on the IO
    134   // thread.
    135   static DiskStatResult InitCacheStructureOnDisk(const base::FilePath& path,
    136                                                  uint64 suggested_max_size);
    137 
    138   // Searches |active_entries_| for the entry corresponding to |key|. If found,
    139   // returns the found entry. Otherwise, creates a new entry and returns that.
    140   scoped_refptr<SimpleEntryImpl> CreateOrFindActiveEntry(
    141       uint64 entry_hash,
    142       const std::string& key);
    143 
    144   // Given a hash, will try to open the corresponding Entry. If we have an Entry
    145   // corresponding to |hash| in the map of active entries, opens it. Otherwise,
    146   // a new empty Entry will be created, opened and filled with information from
    147   // the disk.
    148   int OpenEntryFromHash(uint64 entry_hash,
    149                         Entry** entry,
    150                         const CompletionCallback& callback);
    151 
    152   // Doom the entry corresponding to |entry_hash|, if it's active or currently
    153   // pending doom. This function does not block if there is an active entry,
    154   // which is very important to prevent races in DoomEntries() above.
    155   int DoomEntryFromHash(uint64 entry_hash, const CompletionCallback & callback);
    156 
    157   // Called when the index is initilized to find the next entry in the iterator
    158   // |iter|. If there are no more hashes in the iterator list, net::ERR_FAILED
    159   // is returned. Otherwise, calls OpenEntryFromHash.
    160   void GetNextEntryInIterator(void** iter,
    161                               Entry** next_entry,
    162                               const CompletionCallback& callback,
    163                               int error_code);
    164 
    165   // Called when we tried to open an entry with hash alone. When a blank entry
    166   // has been created and filled in with information from the disk - based on a
    167   // hash alone - this checks that a duplicate active entry was not created
    168   // using a key in the meantime.
    169   void OnEntryOpenedFromHash(uint64 hash,
    170                              Entry** entry,
    171                              scoped_refptr<SimpleEntryImpl> simple_entry,
    172                              const CompletionCallback& callback,
    173                              int error_code);
    174 
    175   // Called when we tried to open an entry from key. When the entry has been
    176   // opened, a check for key mismatch is performed.
    177   void OnEntryOpenedFromKey(const std::string key,
    178                             Entry** entry,
    179                             scoped_refptr<SimpleEntryImpl> simple_entry,
    180                             const CompletionCallback& callback,
    181                             int error_code);
    182 
    183   // Called at the end of the asynchronous operation triggered by
    184   // OpenEntryFromHash. Makes sure to continue iterating if the open entry was
    185   // not a success.
    186   void CheckIterationReturnValue(void** iter,
    187                                  Entry** entry,
    188                                  const CompletionCallback& callback,
    189                                  int error_code);
    190 
    191   // A callback thunk used by DoomEntries to clear the |entries_pending_doom_|
    192   // after a mass doom.
    193   void DoomEntriesComplete(scoped_ptr<std::vector<uint64> > entry_hashes,
    194                            const CompletionCallback& callback,
    195                            int result);
    196 
    197   const base::FilePath path_;
    198   const net::CacheType cache_type_;
    199   scoped_ptr<SimpleIndex> index_;
    200   const scoped_refptr<base::SingleThreadTaskRunner> cache_thread_;
    201   scoped_refptr<base::TaskRunner> worker_pool_;
    202 
    203   int orig_max_size_;
    204   const SimpleEntryImpl::OperationsMode entry_operations_mode_;
    205 
    206   EntryMap active_entries_;
    207 
    208   // The set of all entries which are currently being doomed. To avoid races,
    209   // these entries cannot have Doom/Create/Open operations run until the doom
    210   // is complete. The base::Closure map target is used to store deferred
    211   // operations to be run at the completion of the Doom.
    212   base::hash_map<uint64, std::vector<base::Closure> > entries_pending_doom_;
    213 
    214   net::NetLog* const net_log_;
    215 };
    216 
    217 }  // namespace disk_cache
    218 
    219 #endif  // NET_DISK_CACHE_SIMPLE_SIMPLE_BACKEND_IMPL_H_
    220