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.
5 #ifndef NET_DISK_CACHE_SIMPLE_SIMPLE_BACKEND_IMPL_H_
6 #define NET_DISK_CACHE_SIMPLE_SIMPLE_BACKEND_IMPL_H_
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"
27 class SingleThreadTaskRunner;
31 namespace disk_cache {
33 // SimpleBackendImpl is a new cache backend that stores entries in individual
35 // See http://www.chromium.org/developers/design-documents/network-stack/disk-cache/very-simple-backend
37 // The non-static functions below must be called on the IO thread unless
40 class SimpleEntryImpl;
43 class NET_EXPORT_PRIVATE SimpleBackendImpl : public Backend,
44 public SimpleIndexDelegate,
45 public base::SupportsWeakPtr<SimpleBackendImpl> {
47 SimpleBackendImpl(const base::FilePath& path, int max_bytes,
48 net::CacheType cache_type,
49 base::SingleThreadTaskRunner* cache_thread,
50 net::NetLog* net_log);
52 virtual ~SimpleBackendImpl();
54 net::CacheType cache_type() const { return cache_type_; }
55 SimpleIndex* index() { return index_.get(); }
57 base::TaskRunner* worker_pool() { return worker_pool_.get(); }
59 int Init(const CompletionCallback& completion_callback);
61 // Sets the maximum size for the total amount of data stored by this instance.
62 bool SetMaxSize(int max_bytes);
64 // Returns the maximum file size permitted in this backend.
65 int GetMaxFileSize() const;
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);
71 // Flush our SequencedWorkerPool.
72 static void FlushWorkerPoolForTesting();
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);
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
81 void OnDoomComplete(uint64 entry_hash);
83 // SimpleIndexDelegate:
84 virtual void DoomEntries(std::vector<uint64>* entry_hashes,
85 const CompletionCallback& callback) OVERRIDE;
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,
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;
110 typedef base::hash_map<uint64, base::WeakPtr<SimpleEntryImpl> > EntryMap;
112 typedef base::Callback<void(base::Time mtime, uint64 max_size, int result)>
113 InitializeIndexCallback;
115 // Return value of InitCacheStructureOnDisk().
116 struct DiskStatResult {
117 base::Time cache_dir_mtime;
119 bool detected_magic_number_mismatch;
123 void InitializeIndex(const CompletionCallback& callback,
124 const DiskStatResult& result);
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,
130 const CompletionCallback& callback,
133 // Try to create the directory if it doesn't exist. This must run on the IO
135 static DiskStatResult InitCacheStructureOnDisk(const base::FilePath& path,
136 uint64 suggested_max_size);
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(
142 const std::string& key);
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
148 int OpenEntryFromHash(uint64 entry_hash,
150 const CompletionCallback& callback);
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);
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,
162 const CompletionCallback& callback,
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,
171 scoped_refptr<SimpleEntryImpl> simple_entry,
172 const CompletionCallback& callback,
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,
179 scoped_refptr<SimpleEntryImpl> simple_entry,
180 const CompletionCallback& callback,
183 // Called at the end of the asynchronous operation triggered by
184 // OpenEntryFromHash. Makes sure to continue iterating if the open entry was
186 void CheckIterationReturnValue(void** iter,
188 const CompletionCallback& callback,
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,
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_;
204 const SimpleEntryImpl::OperationsMode entry_operations_mode_;
206 EntryMap active_entries_;
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_;
214 net::NetLog* const net_log_;
217 } // namespace disk_cache
219 #endif // NET_DISK_CACHE_SIMPLE_SIMPLE_BACKEND_IMPL_H_