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