simple_index_file.h 8.5 KB

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