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_FILE_H_ 6 #define NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_FILE_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/basictypes.h" 12 #include "base/containers/hash_tables.h" 13 #include "base/files/file_path.h" 14 #include "base/gtest_prod_util.h" 15 #include "base/logging.h" 16 #include "base/memory/scoped_ptr.h" 17 #include "base/pickle.h" 18 #include "base/port.h" 19 #include "net/base/net_export.h" 20 #include "net/disk_cache/simple/simple_index.h" 21 22 namespace base { 23 class SingleThreadTaskRunner; 24 class TaskRunner; 25 } 26 27 namespace disk_cache { 28 29 const uint64 kSimpleIndexMagicNumber = GG_UINT64_C(0x656e74657220796f); 30 31 struct NET_EXPORT_PRIVATE SimpleIndexLoadResult { 32 SimpleIndexLoadResult(); 33 ~SimpleIndexLoadResult(); 34 void Reset(); 35 36 bool did_load; 37 SimpleIndex::EntrySet entries; 38 bool flush_required; 39 }; 40 41 // Simple Index File format is a pickle serialized data of IndexMetadata and 42 // EntryMetadata objects. The file format is as follows: one instance of 43 // serialized |IndexMetadata| followed serialized |EntryMetadata| entries 44 // repeated |number_of_entries| amount of times. To know more about the format, 45 // see SimpleIndexFile::Serialize() and SeeSimpleIndexFile::LoadFromDisk() 46 // methods. 47 // 48 // The non-static methods must run on the IO thread. All the real 49 // work is done in the static methods, which are run on the cache thread 50 // or in worker threads. Synchronization between methods is the 51 // responsibility of the caller. 52 class NET_EXPORT_PRIVATE SimpleIndexFile { 53 public: 54 class NET_EXPORT_PRIVATE IndexMetadata { 55 public: 56 IndexMetadata(); 57 IndexMetadata(uint64 number_of_entries, uint64 cache_size); 58 59 void Serialize(Pickle* pickle) const; 60 bool Deserialize(PickleIterator* it); 61 62 bool CheckIndexMetadata(); 63 64 uint64 GetNumberOfEntries() { return number_of_entries_; } 65 66 private: 67 FRIEND_TEST_ALL_PREFIXES(IndexMetadataTest, Basics); 68 FRIEND_TEST_ALL_PREFIXES(IndexMetadataTest, Serialize); 69 70 uint64 magic_number_; 71 uint32 version_; 72 uint64 number_of_entries_; 73 uint64 cache_size_; // Total cache storage size in bytes. 74 }; 75 76 SimpleIndexFile(base::SingleThreadTaskRunner* cache_thread, 77 base::TaskRunner* worker_pool, 78 const base::FilePath& cache_directory); 79 virtual ~SimpleIndexFile(); 80 81 // Get index entries based on current disk context. 82 virtual void LoadIndexEntries(base::Time cache_last_modified, 83 const base::Closure& callback, 84 SimpleIndexLoadResult* out_result); 85 86 // Write the specified set of entries to disk. 87 virtual void WriteToDisk(const SimpleIndex::EntrySet& entry_set, 88 uint64 cache_size, 89 const base::TimeTicks& start, 90 bool app_on_background); 91 92 // Doom the entries specified in |entry_hashes|, calling |reply_callback| 93 // with the result on the current thread when done. 94 virtual void DoomEntrySet(scoped_ptr<std::vector<uint64> > entry_hashes, 95 const base::Callback<void(int)>& reply_callback); 96 97 private: 98 friend class WrappedSimpleIndexFile; 99 100 // Used for cache directory traversal. 101 typedef base::Callback<void (const base::FilePath&)> EntryFileCallback; 102 103 // When loading the entries from disk, add this many extra hash buckets to 104 // prevent reallocation on the IO thread when merging in new live entries. 105 static const int kExtraSizeForMerge = 512; 106 107 // Synchronous (IO performing) implementation of LoadIndexEntries. 108 static void SyncLoadIndexEntries(base::Time cache_last_modified, 109 const base::FilePath& cache_directory, 110 const base::FilePath& index_file_path, 111 SimpleIndexLoadResult* out_result); 112 113 // Load the index file from disk returning an EntrySet. Upon failure, returns 114 // NULL. 115 static void SyncLoadFromDisk(const base::FilePath& index_filename, 116 SimpleIndexLoadResult* out_result); 117 118 // Returns a scoped_ptr for a newly allocated Pickle containing the serialized 119 // data to be written to a file. 120 static scoped_ptr<Pickle> Serialize( 121 const SimpleIndexFile::IndexMetadata& index_metadata, 122 const SimpleIndex::EntrySet& entries); 123 124 // Given the contents of an index file |data| of length |data_len|, returns 125 // the corresponding EntrySet. Returns NULL on error. 126 static void Deserialize(const char* data, int data_len, 127 SimpleIndexLoadResult* out_result); 128 129 // Implemented either in simple_index_file_posix.cc or 130 // simple_index_file_win.cc. base::FileEnumerator turned out to be very 131 // expensive in terms of memory usage therefore it's used only on non-POSIX 132 // environments for convenience (for now). Returns whether the traversal 133 // succeeded. 134 static bool TraverseCacheDirectory( 135 const base::FilePath& cache_path, 136 const EntryFileCallback& entry_file_callback); 137 138 // Scan the index directory for entries, returning an EntrySet of all entries 139 // found. 140 static void SyncRestoreFromDisk(const base::FilePath& cache_directory, 141 const base::FilePath& index_file_path, 142 SimpleIndexLoadResult* out_result); 143 144 // Determines if an index file is stale relative to the time of last 145 // modification of the cache directory. 146 static bool IsIndexFileStale(base::Time cache_last_modified, 147 const base::FilePath& index_file_path); 148 149 struct PickleHeader : public Pickle::Header { 150 uint32 crc; 151 }; 152 153 const scoped_refptr<base::SingleThreadTaskRunner> cache_thread_; 154 const scoped_refptr<base::TaskRunner> worker_pool_; 155 const base::FilePath cache_directory_; 156 const base::FilePath index_file_; 157 const base::FilePath temp_index_file_; 158 159 DISALLOW_COPY_AND_ASSIGN(SimpleIndexFile); 160 }; 161 162 163 } // namespace disk_cache 164 165 #endif // NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_FILE_H_ 166