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/compiler_specific.h" 13 #include "base/containers/hash_tables.h" 14 #include "base/files/file_path.h" 15 #include "base/memory/ref_counted.h" 16 #include "base/memory/scoped_ptr.h" 17 #include "base/memory/weak_ptr.h" 18 #include "base/task_runner.h" 19 #include "base/time/time.h" 20 #include "net/base/cache_type.h" 21 #include "net/disk_cache/disk_cache.h" 22 #include "net/disk_cache/simple/simple_entry_impl.h" 23 24 namespace base { 25 class SingleThreadTaskRunner; 26 class TaskRunner; 27 } 28 29 namespace disk_cache { 30 31 // SimpleBackendImpl is a new cache backend that stores entries in individual 32 // files. 33 // See http://www.chromium.org/developers/design-documents/network-stack/disk-cache/very-simple-backend 34 // 35 // The non-static functions below must be called on the IO thread unless 36 // otherwise stated. 37 38 class SimpleEntryImpl; 39 class SimpleIndex; 40 41 class NET_EXPORT_PRIVATE SimpleBackendImpl : public Backend, 42 public base::SupportsWeakPtr<SimpleBackendImpl> { 43 public: 44 SimpleBackendImpl(const base::FilePath& path, int max_bytes, 45 net::CacheType type, 46 base::SingleThreadTaskRunner* cache_thread, 47 net::NetLog* net_log); 48 49 virtual ~SimpleBackendImpl(); 50 51 SimpleIndex* index() { return index_.get(); } 52 53 base::TaskRunner* worker_pool() { return worker_pool_.get(); } 54 55 int Init(const CompletionCallback& completion_callback); 56 57 // Sets the maximum size for the total amount of data stored by this instance. 58 bool SetMaxSize(int max_bytes); 59 60 // Returns the maximum file size permitted in this backend. 61 int GetMaxFileSize() const; 62 63 // Removes |entry| from the |active_entries_| set, forcing future Open/Create 64 // operations to construct a new object. 65 void OnDeactivated(const SimpleEntryImpl* entry); 66 67 // Backend: 68 virtual net::CacheType GetCacheType() const OVERRIDE; 69 virtual int32 GetEntryCount() const OVERRIDE; 70 virtual int OpenEntry(const std::string& key, Entry** entry, 71 const CompletionCallback& callback) OVERRIDE; 72 virtual int CreateEntry(const std::string& key, Entry** entry, 73 const CompletionCallback& callback) OVERRIDE; 74 virtual int DoomEntry(const std::string& key, 75 const CompletionCallback& callback) OVERRIDE; 76 virtual int DoomAllEntries(const CompletionCallback& callback) OVERRIDE; 77 virtual int DoomEntriesBetween(base::Time initial_time, 78 base::Time end_time, 79 const CompletionCallback& callback) OVERRIDE; 80 virtual int DoomEntriesSince(base::Time initial_time, 81 const CompletionCallback& callback) OVERRIDE; 82 virtual int OpenNextEntry(void** iter, Entry** next_entry, 83 const CompletionCallback& callback) OVERRIDE; 84 virtual void EndEnumeration(void** iter) OVERRIDE; 85 virtual void GetStats( 86 std::vector<std::pair<std::string, std::string> >* stats) OVERRIDE; 87 virtual void OnExternalCacheHit(const std::string& key) OVERRIDE; 88 89 private: 90 typedef base::hash_map<uint64, base::WeakPtr<SimpleEntryImpl> > EntryMap; 91 92 typedef base::Callback<void(base::Time mtime, uint64 max_size, int result)> 93 InitializeIndexCallback; 94 95 // Return value of InitCacheStructureOnDisk(). 96 struct DiskStatResult { 97 base::Time cache_dir_mtime; 98 uint64 max_size; 99 bool detected_magic_number_mismatch; 100 int net_error; 101 }; 102 103 void InitializeIndex(const CompletionCallback& callback, 104 const DiskStatResult& result); 105 106 // Dooms all entries previously accessed between |initial_time| and 107 // |end_time|. Invoked when the index is ready. 108 void IndexReadyForDoom(base::Time initial_time, 109 base::Time end_time, 110 const CompletionCallback& callback, 111 int result); 112 113 // Try to create the directory if it doesn't exist. This must run on the IO 114 // thread. 115 static DiskStatResult InitCacheStructureOnDisk(const base::FilePath& path, 116 uint64 suggested_max_size); 117 118 // Searches |active_entries_| for the entry corresponding to |key|. If found, 119 // returns the found entry. Otherwise, creates a new entry and returns that. 120 scoped_refptr<SimpleEntryImpl> CreateOrFindActiveEntry( 121 const std::string& key); 122 123 // Given a hash, will try to open the corresponding Entry. If we have an Entry 124 // corresponding to |hash| in the map of active entries, opens it. Otherwise, 125 // a new empty Entry will be created, opened and filled with information from 126 // the disk. 127 int OpenEntryFromHash(uint64 hash, 128 Entry** entry, 129 const CompletionCallback& callback); 130 131 // Called when the index is initilized to find the next entry in the iterator 132 // |iter|. If there are no more hashes in the iterator list, net::ERR_FAILED 133 // is returned. Otherwise, calls OpenEntryFromHash. 134 void GetNextEntryInIterator(void** iter, 135 Entry** next_entry, 136 const CompletionCallback& callback, 137 int error_code); 138 139 // Called when we tried to open an entry with hash alone. When a blank entry 140 // has been created and filled in with information from the disk - based on a 141 // hash alone - this checks that a duplicate active entry was not created 142 // using a key in the meantime. 143 void OnEntryOpenedFromHash(uint64 hash, 144 Entry** entry, 145 scoped_refptr<SimpleEntryImpl> simple_entry, 146 const CompletionCallback& callback, 147 int error_code); 148 149 // Called when we tried to open an entry from key. When the entry has been 150 // opened, a check for key mismatch is performed. 151 void OnEntryOpenedFromKey(const std::string key, 152 Entry** entry, 153 scoped_refptr<SimpleEntryImpl> simple_entry, 154 const CompletionCallback& callback, 155 int error_code); 156 157 // Called at the end of the asynchronous operation triggered by 158 // OpenEntryFromHash. Makes sure to continue iterating if the open entry was 159 // not a success. 160 void CheckIterationReturnValue(void** iter, 161 Entry** entry, 162 const CompletionCallback& callback, 163 int error_code); 164 165 const base::FilePath path_; 166 scoped_ptr<SimpleIndex> index_; 167 const scoped_refptr<base::SingleThreadTaskRunner> cache_thread_; 168 scoped_refptr<base::TaskRunner> worker_pool_; 169 170 int orig_max_size_; 171 const SimpleEntryImpl::OperationsMode entry_operations_mode_; 172 173 // TODO(gavinp): Store the entry_hash in SimpleEntryImpl, and index this map 174 // by hash. This will save memory, and make IndexReadyForDoom easier. 175 EntryMap active_entries_; 176 177 net::NetLog* const net_log_; 178 }; 179 180 } // namespace disk_cache 181 182 #endif // NET_DISK_CACHE_SIMPLE_SIMPLE_BACKEND_IMPL_H_ 183