• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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