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