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_INDEX_H_ 6 #define NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_H_ 7 8 #include <list> 9 #include <vector> 10 11 #include "base/basictypes.h" 12 #include "base/callback.h" 13 #include "base/containers/hash_tables.h" 14 #include "base/files/file_path.h" 15 #include "base/gtest_prod_util.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/single_thread_task_runner.h" 20 #include "base/threading/thread_checker.h" 21 #include "base/time/time.h" 22 #include "base/timer/timer.h" 23 #include "net/base/cache_type.h" 24 #include "net/base/completion_callback.h" 25 #include "net/base/net_export.h" 26 27 #if defined(OS_ANDROID) 28 #include "base/android/application_status_listener.h" 29 #endif 30 31 class Pickle; 32 class PickleIterator; 33 34 namespace disk_cache { 35 36 class SimpleIndexDelegate; 37 class SimpleIndexFile; 38 struct SimpleIndexLoadResult; 39 40 class NET_EXPORT_PRIVATE EntryMetadata { 41 public: 42 EntryMetadata(); 43 EntryMetadata(base::Time last_used_time, int entry_size); 44 45 base::Time GetLastUsedTime() const; 46 void SetLastUsedTime(const base::Time& last_used_time); 47 GetEntrySize()48 int GetEntrySize() const { return entry_size_; } SetEntrySize(int entry_size)49 void SetEntrySize(int entry_size) { entry_size_ = entry_size; } 50 51 // Serialize the data into the provided pickle. 52 void Serialize(Pickle* pickle) const; 53 bool Deserialize(PickleIterator* it); 54 GetLowerEpsilonForTimeComparisons()55 static base::TimeDelta GetLowerEpsilonForTimeComparisons() { 56 return base::TimeDelta::FromSeconds(1); 57 } GetUpperEpsilonForTimeComparisons()58 static base::TimeDelta GetUpperEpsilonForTimeComparisons() { 59 return base::TimeDelta(); 60 } 61 62 private: 63 friend class SimpleIndexFileTest; 64 65 // When adding new members here, you should update the Serialize() and 66 // Deserialize() methods. 67 68 uint32 last_used_time_seconds_since_epoch_; 69 70 int32 entry_size_; // Storage size in bytes. 71 }; 72 COMPILE_ASSERT(sizeof(EntryMetadata) == 8, metadata_size); 73 74 // This class is not Thread-safe. 75 class NET_EXPORT_PRIVATE SimpleIndex 76 : public base::SupportsWeakPtr<SimpleIndex> { 77 public: 78 typedef std::vector<uint64> HashList; 79 80 SimpleIndex(const scoped_refptr<base::SingleThreadTaskRunner>& io_thread, 81 SimpleIndexDelegate* delegate, 82 net::CacheType cache_type, 83 scoped_ptr<SimpleIndexFile> simple_index_file); 84 85 virtual ~SimpleIndex(); 86 87 void Initialize(base::Time cache_mtime); 88 89 bool SetMaxSize(int max_bytes); max_size()90 int max_size() const { return max_size_; } 91 92 void Insert(uint64 entry_hash); 93 void Remove(uint64 entry_hash); 94 95 // Check whether the index has the entry given the hash of its key. 96 bool Has(uint64 entry_hash) const; 97 98 // Update the last used time of the entry with the given key and return true 99 // iff the entry exist in the index. 100 bool UseIfExists(uint64 entry_hash); 101 102 void WriteToDisk(); 103 104 // Update the size (in bytes) of an entry, in the metadata stored in the 105 // index. This should be the total disk-file size including all streams of the 106 // entry. 107 bool UpdateEntrySize(uint64 entry_hash, int entry_size); 108 109 typedef base::hash_map<uint64, EntryMetadata> EntrySet; 110 111 static void InsertInEntrySet(uint64 entry_hash, 112 const EntryMetadata& entry_metadata, 113 EntrySet* entry_set); 114 115 // Executes the |callback| when the index is ready. Allows multiple callbacks. 116 int ExecuteWhenReady(const net::CompletionCallback& callback); 117 118 // Returns entries from the index that have last accessed time matching the 119 // range between |initial_time| and |end_time| where open intervals are 120 // possible according to the definition given in |DoomEntriesBetween()| in the 121 // disk cache backend interface. 122 scoped_ptr<HashList> GetEntriesBetween(const base::Time initial_time, 123 const base::Time end_time); 124 125 // Returns the list of all entries key hash. 126 scoped_ptr<HashList> GetAllHashes(); 127 128 // Returns number of indexed entries. 129 int32 GetEntryCount() const; 130 131 // Returns whether the index has been initialized yet. initialized()132 bool initialized() const { return initialized_; } 133 134 private: 135 friend class SimpleIndexTest; 136 FRIEND_TEST_ALL_PREFIXES(SimpleIndexTest, IndexSizeCorrectOnMerge); 137 FRIEND_TEST_ALL_PREFIXES(SimpleIndexTest, DiskWriteQueued); 138 FRIEND_TEST_ALL_PREFIXES(SimpleIndexTest, DiskWriteExecuted); 139 FRIEND_TEST_ALL_PREFIXES(SimpleIndexTest, DiskWritePostponed); 140 141 void StartEvictionIfNeeded(); 142 void EvictionDone(int result); 143 144 void PostponeWritingToDisk(); 145 146 void UpdateEntryIteratorSize(EntrySet::iterator* it, int entry_size); 147 148 // Must run on IO Thread. 149 void MergeInitializingSet(scoped_ptr<SimpleIndexLoadResult> load_result); 150 151 #if defined(OS_ANDROID) 152 void OnApplicationStateChange(base::android::ApplicationState state); 153 154 scoped_ptr<base::android::ApplicationStatusListener> app_status_listener_; 155 #endif 156 157 // The owner of |this| must ensure the |delegate_| outlives |this|. 158 SimpleIndexDelegate* delegate_; 159 160 EntrySet entries_set_; 161 162 const net::CacheType cache_type_; 163 uint64 cache_size_; // Total cache storage size in bytes. 164 uint64 max_size_; 165 uint64 high_watermark_; 166 uint64 low_watermark_; 167 bool eviction_in_progress_; 168 base::TimeTicks eviction_start_time_; 169 170 // This stores all the entry_hash of entries that are removed during 171 // initialization. 172 base::hash_set<uint64> removed_entries_; 173 bool initialized_; 174 175 scoped_ptr<SimpleIndexFile> index_file_; 176 177 scoped_refptr<base::SingleThreadTaskRunner> io_thread_; 178 179 // All nonstatic SimpleEntryImpl methods should always be called on the IO 180 // thread, in all cases. |io_thread_checker_| documents and enforces this. 181 base::ThreadChecker io_thread_checker_; 182 183 // Timestamp of the last time we wrote the index to disk. 184 // PostponeWritingToDisk() may give up postponing and allow the write if it 185 // has been a while since last time we wrote. 186 base::TimeTicks last_write_to_disk_; 187 188 base::OneShotTimer<SimpleIndex> write_to_disk_timer_; 189 base::Closure write_to_disk_cb_; 190 191 typedef std::list<net::CompletionCallback> CallbackList; 192 CallbackList to_run_when_initialized_; 193 194 // Set to true when the app is on the background. When the app is in the 195 // background we can write the index much more frequently, to insure fresh 196 // index on next startup. 197 bool app_on_background_; 198 }; 199 200 } // namespace disk_cache 201 202 #endif // NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_H_ 203