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