OLD | NEW |
| (Empty) |
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/cache_type.h" | |
20 #include "net/base/net_export.h" | |
21 #include "net/disk_cache/simple/simple_index.h" | |
22 | |
23 namespace base { | |
24 class SingleThreadTaskRunner; | |
25 class TaskRunner; | |
26 } | |
27 | |
28 namespace disk_cache { | |
29 | |
30 const uint64 kSimpleIndexMagicNumber = GG_UINT64_C(0x656e74657220796f); | |
31 | |
32 struct NET_EXPORT_PRIVATE SimpleIndexLoadResult { | |
33 SimpleIndexLoadResult(); | |
34 ~SimpleIndexLoadResult(); | |
35 void Reset(); | |
36 | |
37 bool did_load; | |
38 SimpleIndex::EntrySet entries; | |
39 bool flush_required; | |
40 }; | |
41 | |
42 // Simple Index File format is a pickle serialized data of IndexMetadata and | |
43 // EntryMetadata objects. The file format is as follows: one instance of | |
44 // serialized |IndexMetadata| followed serialized |EntryMetadata| entries | |
45 // repeated |number_of_entries| amount of times. To know more about the format, | |
46 // see SimpleIndexFile::Serialize() and SeeSimpleIndexFile::LoadFromDisk() | |
47 // methods. | |
48 // | |
49 // The non-static methods must run on the IO thread. All the real | |
50 // work is done in the static methods, which are run on the cache thread | |
51 // or in worker threads. Synchronization between methods is the | |
52 // responsibility of the caller. | |
53 class NET_EXPORT_PRIVATE SimpleIndexFile { | |
54 public: | |
55 class NET_EXPORT_PRIVATE IndexMetadata { | |
56 public: | |
57 IndexMetadata(); | |
58 IndexMetadata(uint64 number_of_entries, uint64 cache_size); | |
59 | |
60 void Serialize(Pickle* pickle) const; | |
61 bool Deserialize(PickleIterator* it); | |
62 | |
63 bool CheckIndexMetadata(); | |
64 | |
65 uint64 GetNumberOfEntries() { return number_of_entries_; } | |
66 | |
67 private: | |
68 FRIEND_TEST_ALL_PREFIXES(IndexMetadataTest, Basics); | |
69 FRIEND_TEST_ALL_PREFIXES(IndexMetadataTest, Serialize); | |
70 | |
71 uint64 magic_number_; | |
72 uint32 version_; | |
73 uint64 number_of_entries_; | |
74 uint64 cache_size_; // Total cache storage size in bytes. | |
75 }; | |
76 | |
77 SimpleIndexFile( | |
78 const scoped_refptr<base::SingleThreadTaskRunner>& cache_thread, | |
79 const scoped_refptr<base::TaskRunner>& worker_pool, | |
80 net::CacheType cache_type, | |
81 const base::FilePath& cache_directory); | |
82 virtual ~SimpleIndexFile(); | |
83 | |
84 // Get index entries based on current disk context. | |
85 virtual void LoadIndexEntries(base::Time cache_last_modified, | |
86 const base::Closure& callback, | |
87 SimpleIndexLoadResult* out_result); | |
88 | |
89 // Write the specified set of entries to disk. | |
90 virtual void WriteToDisk(const SimpleIndex::EntrySet& entry_set, | |
91 uint64 cache_size, | |
92 const base::TimeTicks& start, | |
93 bool app_on_background, | |
94 const base::Closure& callback); | |
95 | |
96 private: | |
97 friend class WrappedSimpleIndexFile; | |
98 | |
99 // Used for cache directory traversal. | |
100 typedef base::Callback<void (const base::FilePath&)> EntryFileCallback; | |
101 | |
102 // When loading the entries from disk, add this many extra hash buckets to | |
103 // prevent reallocation on the IO thread when merging in new live entries. | |
104 static const int kExtraSizeForMerge = 512; | |
105 | |
106 // Synchronous (IO performing) implementation of LoadIndexEntries. | |
107 static void SyncLoadIndexEntries(net::CacheType cache_type, | |
108 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. | |
114 static void SyncLoadFromDisk(const base::FilePath& index_filename, | |
115 base::Time* out_last_cache_seen_by_index, | |
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. Note: the pickle is not in a consistent state | |
120 // immediately after calling this menthod, one needs to call | |
121 // SerializeFinalData to make it ready to write to a file. | |
122 static scoped_ptr<Pickle> Serialize( | |
123 const SimpleIndexFile::IndexMetadata& index_metadata, | |
124 const SimpleIndex::EntrySet& entries); | |
125 | |
126 // Appends cache modification time data to the serialized format. This is | |
127 // performed on a thread accessing the disk. It is not combined with the main | |
128 // serialization path to avoid extra thread hops or copying the pickle to the | |
129 // worker thread. | |
130 static bool SerializeFinalData(base::Time cache_modified, Pickle* pickle); | |
131 | |
132 // Given the contents of an index file |data| of length |data_len|, returns | |
133 // the corresponding EntrySet. Returns NULL on error. | |
134 static void Deserialize(const char* data, int data_len, | |
135 base::Time* out_cache_last_modified, | |
136 SimpleIndexLoadResult* out_result); | |
137 | |
138 // Implemented either in simple_index_file_posix.cc or | |
139 // simple_index_file_win.cc. base::FileEnumerator turned out to be very | |
140 // expensive in terms of memory usage therefore it's used only on non-POSIX | |
141 // environments for convenience (for now). Returns whether the traversal | |
142 // succeeded. | |
143 static bool TraverseCacheDirectory( | |
144 const base::FilePath& cache_path, | |
145 const EntryFileCallback& entry_file_callback); | |
146 | |
147 // Writes the index file to disk atomically. | |
148 static void SyncWriteToDisk(net::CacheType cache_type, | |
149 const base::FilePath& cache_directory, | |
150 const base::FilePath& index_filename, | |
151 const base::FilePath& temp_index_filename, | |
152 scoped_ptr<Pickle> pickle, | |
153 const base::TimeTicks& start_time, | |
154 bool app_on_background); | |
155 | |
156 // Scan the index directory for entries, returning an EntrySet of all entries | |
157 // found. | |
158 static void SyncRestoreFromDisk(const base::FilePath& cache_directory, | |
159 const base::FilePath& index_file_path, | |
160 SimpleIndexLoadResult* out_result); | |
161 | |
162 // Determines if an index file is stale relative to the time of last | |
163 // modification of the cache directory. Obsolete, used only for a histogram to | |
164 // compare with the new method. | |
165 // TODO(pasko): remove this method after getting enough data. | |
166 static bool LegacyIsIndexFileStale(base::Time cache_last_modified, | |
167 const base::FilePath& index_file_path); | |
168 | |
169 struct PickleHeader : public Pickle::Header { | |
170 uint32 crc; | |
171 }; | |
172 | |
173 const scoped_refptr<base::SingleThreadTaskRunner> cache_thread_; | |
174 const scoped_refptr<base::TaskRunner> worker_pool_; | |
175 const net::CacheType cache_type_; | |
176 const base::FilePath cache_directory_; | |
177 const base::FilePath index_file_; | |
178 const base::FilePath temp_index_file_; | |
179 | |
180 static const char kIndexDirectory[]; | |
181 static const char kIndexFileName[]; | |
182 static const char kTempIndexFileName[]; | |
183 | |
184 DISALLOW_COPY_AND_ASSIGN(SimpleIndexFile); | |
185 }; | |
186 | |
187 | |
188 } // namespace disk_cache | |
189 | |
190 #endif // NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_FILE_H_ | |
OLD | NEW |