• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
cache_type()61   net::CacheType cache_type() const { return cache_type_; }
index()62   SimpleIndex* index() { return index_.get(); }
63 
worker_pool()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