1 // Copyright 2013 The Chromium Authors 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_FILE_H_ 6 #define NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_FILE_H_ 7 8 #include <stdint.h> 9 10 #include <memory> 11 #include <vector> 12 13 #include "base/files/file_path.h" 14 #include "base/gtest_prod_util.h" 15 #include "base/pickle.h" 16 #include "net/base/cache_type.h" 17 #include "net/base/net_export.h" 18 #include "net/disk_cache/simple/simple_backend_version.h" 19 #include "net/disk_cache/simple/simple_index.h" 20 21 namespace base { 22 class SequencedTaskRunner; 23 } 24 25 namespace disk_cache { 26 class BackendFileOperations; 27 class BackendFileOperationsFactory; 28 29 const uint64_t kSimpleIndexMagicNumber = UINT64_C(0x656e74657220796f); 30 31 struct NET_EXPORT_PRIVATE SimpleIndexLoadResult { 32 SimpleIndexLoadResult(); 33 ~SimpleIndexLoadResult(); 34 void Reset(); 35 36 bool did_load = false; 37 SimpleIndex::EntrySet entries; 38 SimpleIndex::IndexWriteToDiskReason index_write_reason = 39 SimpleIndex::INDEX_WRITE_REASON_MAX; 40 SimpleIndex::IndexInitMethod init_method; 41 bool flush_required = false; 42 }; 43 44 // Simple Index File format is a pickle of IndexMetadata and EntryMetadata 45 // objects. The file format is as follows: one instance of |IndexMetadata| 46 // followed by |EntryMetadata| repeated |entry_count| times. To learn more about 47 // the format see |SimpleIndexFile::Serialize()| and 48 // |SimpleIndexFile::LoadFromDisk()|. 49 // 50 // The non-static methods must run on the source creation sequence. All the real 51 // work is done in the static methods, which are run on the cache thread 52 // or in worker threads. Synchronization between methods is the 53 // responsibility of the caller. 54 class NET_EXPORT_PRIVATE SimpleIndexFile { 55 public: 56 class NET_EXPORT_PRIVATE IndexMetadata { 57 public: 58 IndexMetadata(); 59 IndexMetadata(SimpleIndex::IndexWriteToDiskReason reason, 60 uint64_t entry_count, 61 uint64_t cache_size); 62 63 virtual void Serialize(base::Pickle* pickle) const; 64 bool Deserialize(base::PickleIterator* it); 65 66 bool CheckIndexMetadata(); 67 reason()68 SimpleIndex::IndexWriteToDiskReason reason() const { return reason_; } entry_count()69 uint64_t entry_count() const { return entry_count_; } has_entry_in_memory_data()70 bool has_entry_in_memory_data() const { return version_ >= 8; } app_cache_has_trailer_prefetch_size()71 bool app_cache_has_trailer_prefetch_size() const { return version_ >= 9; } 72 73 private: 74 FRIEND_TEST_ALL_PREFIXES(IndexMetadataTest, Basics); 75 FRIEND_TEST_ALL_PREFIXES(IndexMetadataTest, Serialize); 76 FRIEND_TEST_ALL_PREFIXES(IndexMetadataTest, ReadV6Format); 77 FRIEND_TEST_ALL_PREFIXES(SimpleIndexFileTest, ReadV7Format); 78 FRIEND_TEST_ALL_PREFIXES(SimpleIndexFileTest, ReadV8Format); 79 FRIEND_TEST_ALL_PREFIXES(SimpleIndexFileTest, ReadV8FormatAppCache); 80 friend class V6IndexMetadataForTest; 81 friend class V7IndexMetadataForTest; 82 friend class V8IndexMetadataForTest; 83 84 uint64_t magic_number_ = kSimpleIndexMagicNumber; 85 uint32_t version_ = kSimpleVersion; 86 SimpleIndex::IndexWriteToDiskReason reason_; 87 uint64_t entry_count_; 88 uint64_t cache_size_; // Total cache storage size in bytes. 89 }; 90 91 SimpleIndexFile( 92 scoped_refptr<base::SequencedTaskRunner> cache_runner, 93 scoped_refptr<BackendFileOperationsFactory> file_operations_factory, 94 net::CacheType cache_type, 95 const base::FilePath& cache_directory); 96 97 SimpleIndexFile(const SimpleIndexFile&) = delete; 98 SimpleIndexFile& operator=(const SimpleIndexFile&) = delete; 99 100 virtual ~SimpleIndexFile(); 101 102 // Gets index entries based on current disk context. On error it may leave 103 // |out_result.did_load| untouched, but still return partial and consistent 104 // results in |out_result.entries|. 105 virtual void LoadIndexEntries(base::Time cache_last_modified, 106 base::OnceClosure callback, 107 SimpleIndexLoadResult* out_result); 108 109 // Writes the specified set of entries to disk. 110 virtual void WriteToDisk(net::CacheType cache_type, 111 SimpleIndex::IndexWriteToDiskReason reason, 112 const SimpleIndex::EntrySet& entry_set, 113 uint64_t cache_size, 114 base::OnceClosure callback); 115 116 private: 117 friend class WrappedSimpleIndexFile; 118 119 // Used for cache directory traversal. 120 using EntryFileCallback = 121 base::RepeatingCallback<void(const base::FilePath&, 122 base::Time last_accessed, 123 base::Time last_modified, 124 int64_t size)>; 125 126 // When loading the entries from disk, add this many extra hash buckets to 127 // prevent reallocation on the creation sequence when merging in new live 128 // entries. 129 static const int kExtraSizeForMerge = 512; 130 131 // Synchronous (IO performing) implementation of LoadIndexEntries. 132 static void SyncLoadIndexEntries( 133 std::unique_ptr<BackendFileOperations> file_operations, 134 net::CacheType cache_type, 135 base::Time cache_last_modified, 136 const base::FilePath& cache_directory, 137 const base::FilePath& index_file_path, 138 SimpleIndexLoadResult* out_result); 139 140 // Load the index file from disk returning an EntrySet. 141 static void SyncLoadFromDisk(BackendFileOperations* file_operations, 142 net::CacheType cache_type, 143 const base::FilePath& index_filename, 144 base::Time* out_last_cache_seen_by_index, 145 SimpleIndexLoadResult* out_result); 146 147 // Returns a scoped_ptr for a newly allocated base::Pickle containing the 148 // serialized 149 // data to be written to a file. Note: the pickle is not in a consistent state 150 // immediately after calling this menthod, one needs to call 151 // SerializeFinalData to make it ready to write to a file. 152 static std::unique_ptr<base::Pickle> Serialize( 153 net::CacheType cache_type, 154 const SimpleIndexFile::IndexMetadata& index_metadata, 155 const SimpleIndex::EntrySet& entries); 156 157 // Appends cache modification time data to the serialized format. This is 158 // performed on a thread accessing the disk. It is not combined with the main 159 // serialization path to avoid extra thread hops or copying the pickle to the 160 // worker thread. 161 static void SerializeFinalData(base::Time cache_modified, 162 base::Pickle* pickle); 163 164 // Given the contents of an index file |data| of length |data_len|, returns 165 // the corresponding EntrySet. Returns NULL on error. 166 static void Deserialize(net::CacheType cache_type, 167 const char* data, 168 int data_len, 169 base::Time* out_cache_last_modified, 170 SimpleIndexLoadResult* out_result); 171 172 // Writes the index file to disk atomically. 173 static void SyncWriteToDisk( 174 std::unique_ptr<BackendFileOperations> file_operations, 175 net::CacheType cache_type, 176 const base::FilePath& cache_directory, 177 const base::FilePath& index_filename, 178 const base::FilePath& temp_index_filename, 179 std::unique_ptr<base::Pickle> pickle); 180 181 // Scan the index directory for entries, returning an EntrySet of all entries 182 // found. 183 static void SyncRestoreFromDisk(BackendFileOperations* file_operations, 184 net::CacheType cache_type, 185 const base::FilePath& cache_directory, 186 const base::FilePath& index_file_path, 187 SimpleIndexLoadResult* out_result); 188 189 // Determines if an index file is stale relative to the time of last 190 // modification of the cache directory. Obsolete, used only for a histogram to 191 // compare with the new method. 192 // TODO(pasko): remove this method after getting enough data. 193 static bool LegacyIsIndexFileStale(BackendFileOperations* file_operations, 194 base::Time cache_last_modified, 195 const base::FilePath& index_file_path); 196 197 const scoped_refptr<base::SequencedTaskRunner> cache_runner_; 198 const scoped_refptr<BackendFileOperationsFactory> file_operations_factory_; 199 const net::CacheType cache_type_; 200 const base::FilePath cache_directory_; 201 const base::FilePath index_file_; 202 const base::FilePath temp_index_file_; 203 204 static const char kIndexDirectory[]; 205 static const char kIndexFileName[]; 206 static const char kTempIndexFileName[]; 207 }; 208 209 } // namespace disk_cache 210 211 #endif // NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_FILE_H_ 212