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 SimpleBackendImpl provides safe iteration; mutating entries during
     38 // iteration cannot cause a crash. It is undefined whether entries created or
     39 // destroyed during the iteration will be included in any pre-existing
     40 // iterations.
     41 //
     42 // The non-static functions below must be called on the IO thread unless
     43 // otherwise stated.
     44 
     45 class SimpleEntryImpl;
     46 class SimpleIndex;
     47 
     48 class NET_EXPORT_PRIVATE SimpleBackendImpl : public Backend,
     49     public SimpleIndexDelegate,
     50     public base::SupportsWeakPtr<SimpleBackendImpl> {
     51  public:
     52   SimpleBackendImpl(
     53       const base::FilePath& path,
     54       int max_bytes,
     55       net::CacheType cache_type,
     56       const scoped_refptr<base::SingleThreadTaskRunner>& cache_thread,
     57       net::NetLog* net_log);
     58 
     59   virtual ~SimpleBackendImpl();
     60 
     61   net::CacheType cache_type() const { return cache_type_; }
     62   SimpleIndex* index() { return index_.get(); }
     63 
     64   base::TaskRunner* worker_pool() { return worker_pool_.get(); }
     65 
     66   int Init(const CompletionCallback& completion_callback);
     67 
     68   // Sets the maximum size for the total amount of data stored by this instance.
     69   bool SetMaxSize(int max_bytes);
     70 
     71   // Returns the maximum file size permitted in this backend.
     72   int GetMaxFileSize() const;
     73 
     74   // Flush our SequencedWorkerPool.
     75   static void FlushWorkerPoolForTesting();
     76 
     77   // The entry for |entry_hash| is being doomed; the backend will not attempt
     78   // run new operations for this |entry_hash| until the Doom is completed.
     79   void OnDoomStart(uint64 entry_hash);
     80 
     81   // The entry for |entry_hash| has been successfully doomed, we can now allow
     82   // operations on this entry, and we can run any operations enqueued while the
     83   // doom completed.
     84   void OnDoomComplete(uint64 entry_hash);
     85 
     86   // SimpleIndexDelegate:
     87   virtual void DoomEntries(std::vector<uint64>* entry_hashes,
     88                            const CompletionCallback& callback) OVERRIDE;
     89 
     90   // Backend:
     91   virtual net::CacheType GetCacheType() const OVERRIDE;
     92   virtual int32 GetEntryCount() const OVERRIDE;
     93   virtual int OpenEntry(const std::string& key, Entry** entry,
     94                         const CompletionCallback& callback) OVERRIDE;
     95   virtual int CreateEntry(const std::string& key, Entry** entry,
     96                           const CompletionCallback& callback) OVERRIDE;
     97   virtual int DoomEntry(const std::string& key,
     98                         const CompletionCallback& callback) OVERRIDE;
     99   virtual int DoomAllEntries(const CompletionCallback& callback) OVERRIDE;
    100   virtual int DoomEntriesBetween(base::Time initial_time,
    101                                  base::Time end_time,
    102                                  const CompletionCallback& callback) OVERRIDE;
    103   virtual int DoomEntriesSince(base::Time initial_time,
    104                                const CompletionCallback& callback) OVERRIDE;
    105   virtual scoped_ptr<Iterator> CreateIterator() OVERRIDE;
    106   virtual void GetStats(
    107       std::vector<std::pair<std::string, std::string> >* stats) OVERRIDE;
    108   virtual void OnExternalCacheHit(const std::string& key) OVERRIDE;
    109 
    110  private:
    111   class SimpleIterator;
    112   friend class SimpleIterator;
    113 
    114   typedef base::hash_map<uint64, SimpleEntryImpl*> EntryMap;
    115 
    116   typedef base::Callback<void(base::Time mtime, uint64 max_size, int result)>
    117       InitializeIndexCallback;
    118 
    119   class ActiveEntryProxy;
    120   friend class ActiveEntryProxy;
    121 
    122   // Return value of InitCacheStructureOnDisk().
    123   struct DiskStatResult {
    124     base::Time cache_dir_mtime;
    125     uint64 max_size;
    126     bool detected_magic_number_mismatch;
    127     int net_error;
    128   };
    129 
    130   void InitializeIndex(const CompletionCallback& callback,
    131                        const DiskStatResult& result);
    132 
    133   // Dooms all entries previously accessed between |initial_time| and
    134   // |end_time|. Invoked when the index is ready.
    135   void IndexReadyForDoom(base::Time initial_time,
    136                          base::Time end_time,
    137                          const CompletionCallback& callback,
    138                          int result);
    139 
    140   // Try to create the directory if it doesn't exist. This must run on the IO
    141   // thread.
    142   static DiskStatResult InitCacheStructureOnDisk(const base::FilePath& path,
    143                                                  uint64 suggested_max_size);
    144 
    145   // Searches |active_entries_| for the entry corresponding to |key|. If found,
    146   // returns the found entry. Otherwise, creates a new entry and returns that.
    147   scoped_refptr<SimpleEntryImpl> CreateOrFindActiveEntry(
    148       uint64 entry_hash,
    149       const std::string& key);
    150 
    151   // Given a hash, will try to open the corresponding Entry. If we have an Entry
    152   // corresponding to |hash| in the map of active entries, opens it. Otherwise,
    153   // a new empty Entry will be created, opened and filled with information from
    154   // the disk.
    155   int OpenEntryFromHash(uint64 entry_hash,
    156                         Entry** entry,
    157                         const CompletionCallback& callback);
    158 
    159   // Doom the entry corresponding to |entry_hash|, if it's active or currently
    160   // pending doom. This function does not block if there is an active entry,
    161   // which is very important to prevent races in DoomEntries() above.
    162   int DoomEntryFromHash(uint64 entry_hash, const CompletionCallback & callback);
    163 
    164   // Called when we tried to open an entry with hash alone. When a blank entry
    165   // has been created and filled in with information from the disk - based on a
    166   // hash alone - this checks that a duplicate active entry was not created
    167   // using a key in the meantime.
    168   void OnEntryOpenedFromHash(uint64 hash,
    169                              Entry** entry,
    170                              const scoped_refptr<SimpleEntryImpl>& simple_entry,
    171                              const CompletionCallback& callback,
    172                              int error_code);
    173 
    174   // Called when we tried to open an entry from key. When the entry has been
    175   // opened, a check for key mismatch is performed.
    176   void OnEntryOpenedFromKey(const std::string key,
    177                             Entry** entry,
    178                             const scoped_refptr<SimpleEntryImpl>& simple_entry,
    179                             const CompletionCallback& callback,
    180                             int error_code);
    181 
    182   // A callback thunk used by DoomEntries to clear the |entries_pending_doom_|
    183   // after a mass doom.
    184   void DoomEntriesComplete(scoped_ptr<std::vector<uint64> > entry_hashes,
    185                            const CompletionCallback& callback,
    186                            int result);
    187 
    188   const base::FilePath path_;
    189   const net::CacheType cache_type_;
    190   scoped_ptr<SimpleIndex> index_;
    191   const scoped_refptr<base::SingleThreadTaskRunner> cache_thread_;
    192   scoped_refptr<base::TaskRunner> worker_pool_;
    193 
    194   int orig_max_size_;
    195   const SimpleEntryImpl::OperationsMode entry_operations_mode_;
    196 
    197   EntryMap active_entries_;
    198 
    199   // The set of all entries which are currently being doomed. To avoid races,
    200   // these entries cannot have Doom/Create/Open operations run until the doom
    201   // is complete. The base::Closure map target is used to store deferred
    202   // operations to be run at the completion of the Doom.
    203   base::hash_map<uint64, std::vector<base::Closure> > entries_pending_doom_;
    204 
    205   net::NetLog* const net_log_;
    206 };
    207 
    208 }  // namespace disk_cache
    209 
    210 #endif  // NET_DISK_CACHE_SIMPLE_SIMPLE_BACKEND_IMPL_H_
    211