OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef NET_DISK_CACHE_SIMPLE_SIMPLE_SYNCHRONOUS_ENTRY_H_ | 5 #ifndef NET_DISK_CACHE_SIMPLE_SIMPLE_SYNCHRONOUS_ENTRY_H_ |
6 #define NET_DISK_CACHE_SIMPLE_SIMPLE_SYNCHRONOUS_ENTRY_H_ | 6 #define NET_DISK_CACHE_SIMPLE_SIMPLE_SYNCHRONOUS_ENTRY_H_ |
7 | 7 |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
11 #include <map> | 11 #include <map> |
12 #include <memory> | 12 #include <memory> |
13 #include <string> | 13 #include <string> |
14 #include <utility> | 14 #include <utility> |
15 #include <vector> | 15 #include <vector> |
16 | 16 |
17 #include "base/files/file.h" | 17 #include "base/files/file.h" |
18 #include "base/files/file_path.h" | 18 #include "base/files/file_path.h" |
| 19 #include "base/gtest_prod_util.h" |
19 #include "base/memory/ref_counted.h" | 20 #include "base/memory/ref_counted.h" |
20 #include "base/time/time.h" | 21 #include "base/time/time.h" |
21 #include "net/base/cache_type.h" | 22 #include "net/base/cache_type.h" |
22 #include "net/base/net_export.h" | 23 #include "net/base/net_export.h" |
23 #include "net/disk_cache/simple/simple_entry_format.h" | 24 #include "net/disk_cache/simple/simple_entry_format.h" |
24 | 25 |
25 namespace net { | 26 namespace net { |
26 class GrowableIOBuffer; | 27 class GrowableIOBuffer; |
27 class IOBuffer; | 28 class IOBuffer; |
28 } | 29 } |
29 | 30 |
| 31 FORWARD_DECLARE_TEST(DiskCacheBackendTest, SimpleCacheEnumerationLongKeys); |
| 32 |
30 namespace disk_cache { | 33 namespace disk_cache { |
31 | 34 |
32 class SimpleSynchronousEntry; | 35 class SimpleSynchronousEntry; |
33 | 36 |
34 // This class handles the passing of data about the entry between | 37 // This class handles the passing of data about the entry between |
35 // SimpleEntryImplementation and SimpleSynchronousEntry and the computation of | 38 // SimpleEntryImplementation and SimpleSynchronousEntry and the computation of |
36 // file offsets based on the data size for all streams. | 39 // file offsets based on the data size for all streams. |
37 class NET_EXPORT_PRIVATE SimpleEntryStat { | 40 class NET_EXPORT_PRIVATE SimpleEntryStat { |
38 public: | 41 public: |
39 SimpleEntryStat(base::Time last_used, | 42 SimpleEntryStat(base::Time last_used, |
40 base::Time last_modified, | 43 base::Time last_modified, |
41 const int32_t data_size[], | 44 const int32_t data_size[], |
42 const int32_t sparse_data_size); | 45 const int32_t sparse_data_size); |
43 | 46 |
44 int GetOffsetInFile(const std::string& key, | 47 int GetOffsetInFile(size_t key_length, int offset, int stream_index) const; |
45 int offset, | 48 int GetEOFOffsetInFile(size_t key_length, int stream_index) const; |
46 int stream_index) const; | 49 int GetLastEOFOffsetInFile(size_t key_length, int file_index) const; |
47 int GetEOFOffsetInFile(const std::string& key, int stream_index) const; | 50 int64_t GetFileSize(size_t key_length, int file_index) const; |
48 int GetLastEOFOffsetInFile(const std::string& key, int file_index) const; | |
49 int64_t GetFileSize(const std::string& key, int file_index) const; | |
50 | 51 |
51 base::Time last_used() const { return last_used_; } | 52 base::Time last_used() const { return last_used_; } |
52 base::Time last_modified() const { return last_modified_; } | 53 base::Time last_modified() const { return last_modified_; } |
53 void set_last_used(base::Time last_used) { last_used_ = last_used; } | 54 void set_last_used(base::Time last_used) { last_used_ = last_used; } |
54 void set_last_modified(base::Time last_modified) { | 55 void set_last_modified(base::Time last_modified) { |
55 last_modified_ = last_modified; | 56 last_modified_ = last_modified; |
56 } | 57 } |
57 | 58 |
58 int32_t data_size(int stream_index) const { return data_size_[stream_index]; } | 59 int32_t data_size(int stream_index) const { return data_size_[stream_index]; } |
59 void set_data_size(int stream_index, int data_size) { | 60 void set_data_size(int stream_index, int data_size) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 EntryOperationData(int64_t sparse_offset_p, int buf_len_p); | 108 EntryOperationData(int64_t sparse_offset_p, int buf_len_p); |
108 | 109 |
109 int index; | 110 int index; |
110 int offset; | 111 int offset; |
111 int64_t sparse_offset; | 112 int64_t sparse_offset; |
112 int buf_len; | 113 int buf_len; |
113 bool truncate; | 114 bool truncate; |
114 bool doomed; | 115 bool doomed; |
115 }; | 116 }; |
116 | 117 |
| 118 // Opens a disk cache entry on disk. The |key| parameter is optional, if empty |
| 119 // the operation may be slower. The |entry_hash| parameter is required. |
| 120 // |had_index| is provided only for histograms. |
117 static void OpenEntry(net::CacheType cache_type, | 121 static void OpenEntry(net::CacheType cache_type, |
118 const base::FilePath& path, | 122 const base::FilePath& path, |
| 123 const std::string& key, |
119 uint64_t entry_hash, | 124 uint64_t entry_hash, |
120 bool had_index, | 125 bool had_index, |
121 SimpleEntryCreationResults* out_results); | 126 SimpleEntryCreationResults* out_results); |
122 | 127 |
123 static void CreateEntry(net::CacheType cache_type, | 128 static void CreateEntry(net::CacheType cache_type, |
124 const base::FilePath& path, | 129 const base::FilePath& path, |
125 const std::string& key, | 130 const std::string& key, |
126 uint64_t entry_hash, | 131 uint64_t entry_hash, |
127 bool had_index, | 132 bool had_index, |
128 SimpleEntryCreationResults* out_results); | 133 SimpleEntryCreationResults* out_results); |
(...skipping 14 matching lines...) Expand all Loading... |
143 // |key_hashes|. Succeeds only when all entries are deleted. Returns a net | 148 // |key_hashes|. Succeeds only when all entries are deleted. Returns a net |
144 // error code. | 149 // error code. |
145 static int DoomEntrySet(const std::vector<uint64_t>* key_hashes, | 150 static int DoomEntrySet(const std::vector<uint64_t>* key_hashes, |
146 const base::FilePath& path); | 151 const base::FilePath& path); |
147 | 152 |
148 // N.B. ReadData(), WriteData(), CheckEOFRecord() and Close() may block on IO. | 153 // N.B. ReadData(), WriteData(), CheckEOFRecord() and Close() may block on IO. |
149 void ReadData(const EntryOperationData& in_entry_op, | 154 void ReadData(const EntryOperationData& in_entry_op, |
150 net::IOBuffer* out_buf, | 155 net::IOBuffer* out_buf, |
151 uint32_t* out_crc32, | 156 uint32_t* out_crc32, |
152 SimpleEntryStat* entry_stat, | 157 SimpleEntryStat* entry_stat, |
153 int* out_result) const; | 158 int* out_result); |
154 void WriteData(const EntryOperationData& in_entry_op, | 159 void WriteData(const EntryOperationData& in_entry_op, |
155 net::IOBuffer* in_buf, | 160 net::IOBuffer* in_buf, |
156 SimpleEntryStat* out_entry_stat, | 161 SimpleEntryStat* out_entry_stat, |
157 int* out_result); | 162 int* out_result); |
158 void CheckEOFRecord(int index, | 163 void CheckEOFRecord(int index, |
159 const SimpleEntryStat& entry_stat, | 164 const SimpleEntryStat& entry_stat, |
160 uint32_t expected_crc32, | 165 uint32_t expected_crc32, |
161 int* out_result) const; | 166 int* out_result) const; |
162 | 167 |
163 void ReadSparseData(const EntryOperationData& in_entry_op, | 168 void ReadSparseData(const EntryOperationData& in_entry_op, |
(...skipping 12 matching lines...) Expand all Loading... |
176 // Close all streams, and add write EOF records to streams indicated by the | 181 // Close all streams, and add write EOF records to streams indicated by the |
177 // CRCRecord entries in |crc32s_to_write|. | 182 // CRCRecord entries in |crc32s_to_write|. |
178 void Close(const SimpleEntryStat& entry_stat, | 183 void Close(const SimpleEntryStat& entry_stat, |
179 std::unique_ptr<std::vector<CRCRecord>> crc32s_to_write, | 184 std::unique_ptr<std::vector<CRCRecord>> crc32s_to_write, |
180 net::GrowableIOBuffer* stream_0_data); | 185 net::GrowableIOBuffer* stream_0_data); |
181 | 186 |
182 const base::FilePath& path() const { return path_; } | 187 const base::FilePath& path() const { return path_; } |
183 std::string key() const { return key_; } | 188 std::string key() const { return key_; } |
184 | 189 |
185 private: | 190 private: |
| 191 FRIEND_TEST_ALL_PREFIXES(::DiskCacheBackendTest, |
| 192 SimpleCacheEnumerationLongKeys); |
| 193 |
186 enum CreateEntryResult { | 194 enum CreateEntryResult { |
187 CREATE_ENTRY_SUCCESS = 0, | 195 CREATE_ENTRY_SUCCESS = 0, |
188 CREATE_ENTRY_PLATFORM_FILE_ERROR = 1, | 196 CREATE_ENTRY_PLATFORM_FILE_ERROR = 1, |
189 CREATE_ENTRY_CANT_WRITE_HEADER = 2, | 197 CREATE_ENTRY_CANT_WRITE_HEADER = 2, |
190 CREATE_ENTRY_CANT_WRITE_KEY = 3, | 198 CREATE_ENTRY_CANT_WRITE_KEY = 3, |
191 CREATE_ENTRY_MAX = 4, | 199 CREATE_ENTRY_MAX = 4, |
192 }; | 200 }; |
193 | 201 |
194 enum FileRequired { | 202 enum FileRequired { |
195 FILE_NOT_REQUIRED, | 203 FILE_NOT_REQUIRED, |
196 FILE_REQUIRED | 204 FILE_REQUIRED |
197 }; | 205 }; |
198 | 206 |
199 struct SparseRange { | 207 struct SparseRange { |
200 int64_t offset; | 208 int64_t offset; |
201 int64_t length; | 209 int64_t length; |
202 uint32_t data_crc32; | 210 uint32_t data_crc32; |
203 int64_t file_offset; | 211 int64_t file_offset; |
204 | 212 |
205 bool operator<(const SparseRange& other) const { | 213 bool operator<(const SparseRange& other) const { |
206 return offset < other.offset; | 214 return offset < other.offset; |
207 } | 215 } |
208 }; | 216 }; |
209 | 217 |
| 218 // When opening an entry without knowing the key, the header must be read |
| 219 // without knowing the size of the key. This is how much to read initially, to |
| 220 // make it likely the entire key is read. |
| 221 static const size_t kInitialHeaderRead = 64 * 1024; |
| 222 |
210 SimpleSynchronousEntry(net::CacheType cache_type, | 223 SimpleSynchronousEntry(net::CacheType cache_type, |
211 const base::FilePath& path, | 224 const base::FilePath& path, |
212 const std::string& key, | 225 const std::string& key, |
213 uint64_t entry_hash); | 226 uint64_t entry_hash, |
| 227 bool had_index); |
214 | 228 |
215 // Like Entry, the SimpleSynchronousEntry self releases when Close() is | 229 // Like Entry, the SimpleSynchronousEntry self releases when Close() is |
216 // called. | 230 // called. |
217 ~SimpleSynchronousEntry(); | 231 ~SimpleSynchronousEntry(); |
218 | 232 |
219 // Tries to open one of the cache entry files. Succeeds if the open succeeds | 233 // Tries to open one of the cache entry files. Succeeds if the open succeeds |
220 // or if the file was not found and is allowed to be omitted if the | 234 // or if the file was not found and is allowed to be omitted if the |
221 // corresponding stream is empty. | 235 // corresponding stream is empty. |
222 bool MaybeOpenFile(int file_index, | 236 bool MaybeOpenFile(int file_index, |
223 base::File::Error* out_error); | 237 base::File::Error* out_error); |
224 // Creates one of the cache entry files if necessary. If the file is allowed | 238 // Creates one of the cache entry files if necessary. If the file is allowed |
225 // to be omitted if the corresponding stream is empty, and if |file_required| | 239 // to be omitted if the corresponding stream is empty, and if |file_required| |
226 // is FILE_NOT_REQUIRED, then the file is not created; otherwise, it is. | 240 // is FILE_NOT_REQUIRED, then the file is not created; otherwise, it is. |
227 bool MaybeCreateFile(int file_index, | 241 bool MaybeCreateFile(int file_index, |
228 FileRequired file_required, | 242 FileRequired file_required, |
229 base::File::Error* out_error); | 243 base::File::Error* out_error); |
230 bool OpenFiles(bool had_index, | 244 bool OpenFiles(SimpleEntryStat* out_entry_stat); |
231 SimpleEntryStat* out_entry_stat); | 245 bool CreateFiles(SimpleEntryStat* out_entry_stat); |
232 bool CreateFiles(bool had_index, | |
233 SimpleEntryStat* out_entry_stat); | |
234 void CloseFile(int index); | 246 void CloseFile(int index); |
235 void CloseFiles(); | 247 void CloseFiles(); |
236 | 248 |
237 // Returns a net error, i.e. net::OK on success. |had_index| is passed | 249 // Read the header and key at the beginning of the file, and validate that |
238 // from the main entry for metrics purposes, and is true if the index was | 250 // they are correct. If this entry was opened with a key, the key is checked |
239 // initialized when the open operation began. | 251 // for a match. If not, then the |key_| member is set based on the value in |
240 int InitializeForOpen(bool had_index, | 252 // this header. Records histograms if any check is failed. |
241 SimpleEntryStat* out_entry_stat, | 253 bool CheckHeaderAndKey(int file_index); |
| 254 |
| 255 // Returns a net error, i.e. net::OK on success. |
| 256 int InitializeForOpen(SimpleEntryStat* out_entry_stat, |
242 scoped_refptr<net::GrowableIOBuffer>* stream_0_data, | 257 scoped_refptr<net::GrowableIOBuffer>* stream_0_data, |
243 uint32_t* out_stream_0_crc32); | 258 uint32_t* out_stream_0_crc32); |
244 | 259 |
245 // Writes the header and key to a newly-created stream file. |index| is the | 260 // Writes the header and key to a newly-created stream file. |index| is the |
246 // index of the stream. Returns true on success; returns false and sets | 261 // index of the stream. Returns true on success; returns false and sets |
247 // |*out_result| on failure. | 262 // |*out_result| on failure. |
248 bool InitializeCreatedFile(int index, CreateEntryResult* out_result); | 263 bool InitializeCreatedFile(int index, CreateEntryResult* out_result); |
249 | 264 |
250 // Returns a net error, including net::OK on success and net::FILE_EXISTS | 265 // Returns a net error, including net::OK on success and net::FILE_EXISTS |
251 // when the entry already exists. |had_index| is passed from the main entry | 266 // when the entry already exists. |
252 // for metrics purposes, and is true if the index was initialized when the | 267 int InitializeForCreate(SimpleEntryStat* out_entry_stat); |
253 // create operation began. | |
254 int InitializeForCreate(bool had_index, SimpleEntryStat* out_entry_stat); | |
255 | 268 |
256 // Allocates and fills a buffer with stream 0 data in |stream_0_data|, then | 269 // Allocates and fills a buffer with stream 0 data in |stream_0_data|, then |
257 // checks its crc32. | 270 // checks its crc32. |
258 int ReadAndValidateStream0( | 271 int ReadAndValidateStream0( |
259 int total_data_size, | 272 int file_size, |
260 SimpleEntryStat* out_entry_stat, | 273 SimpleEntryStat* out_entry_stat, |
261 scoped_refptr<net::GrowableIOBuffer>* stream_0_data, | 274 scoped_refptr<net::GrowableIOBuffer>* stream_0_data, |
262 uint32_t* out_stream_0_crc32) const; | 275 uint32_t* out_stream_0_crc32); |
263 | 276 |
264 int GetEOFRecordData(int index, | 277 int GetEOFRecordData(int index, |
265 const SimpleEntryStat& entry_stat, | 278 const SimpleEntryStat& entry_stat, |
266 bool* out_has_crc32, | 279 bool* out_has_crc32, |
| 280 bool* out_has_key_sha256, |
267 uint32_t* out_crc32, | 281 uint32_t* out_crc32, |
268 int* out_data_size) const; | 282 int* out_data_size) const; |
269 void Doom() const; | 283 void Doom() const; |
270 | 284 |
271 // Opens the sparse data file and scans it if it exists. | 285 // Opens the sparse data file and scans it if it exists. |
272 bool OpenSparseFileIfExists(int32_t* out_sparse_data_size); | 286 bool OpenSparseFileIfExists(int32_t* out_sparse_data_size); |
273 | 287 |
274 // Creates and initializes the sparse data file. | 288 // Creates and initializes the sparse data file. |
275 bool CreateSparseFile(); | 289 bool CreateSparseFile(); |
276 | 290 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 | 327 |
314 base::FilePath GetFilenameFromFileIndex(int file_index); | 328 base::FilePath GetFilenameFromFileIndex(int file_index); |
315 | 329 |
316 bool sparse_file_open() const { | 330 bool sparse_file_open() const { |
317 return sparse_file_.IsValid(); | 331 return sparse_file_.IsValid(); |
318 } | 332 } |
319 | 333 |
320 const net::CacheType cache_type_; | 334 const net::CacheType cache_type_; |
321 const base::FilePath path_; | 335 const base::FilePath path_; |
322 const uint64_t entry_hash_; | 336 const uint64_t entry_hash_; |
| 337 const bool had_index_; |
323 std::string key_; | 338 std::string key_; |
324 | 339 |
325 bool have_open_files_; | 340 bool have_open_files_; |
326 bool initialized_; | 341 bool initialized_; |
327 | 342 |
| 343 // Normally false. This is set to true when an entry is opened without |
| 344 // checking the file headers. Any subsequent read will perform the check |
| 345 // before completing. |
| 346 bool header_and_key_check_needed_[kSimpleEntryFileCount] = { |
| 347 false, |
| 348 }; |
| 349 |
328 base::File files_[kSimpleEntryFileCount]; | 350 base::File files_[kSimpleEntryFileCount]; |
329 | 351 |
330 // True if the corresponding stream is empty and therefore no on-disk file | 352 // True if the corresponding stream is empty and therefore no on-disk file |
331 // was created to store it. | 353 // was created to store it. |
332 bool empty_file_omitted_[kSimpleEntryFileCount]; | 354 bool empty_file_omitted_[kSimpleEntryFileCount]; |
333 | 355 |
334 typedef std::map<int64_t, SparseRange> SparseRangeOffsetMap; | 356 typedef std::map<int64_t, SparseRange> SparseRangeOffsetMap; |
335 typedef SparseRangeOffsetMap::iterator SparseRangeIterator; | 357 typedef SparseRangeOffsetMap::iterator SparseRangeIterator; |
336 SparseRangeOffsetMap sparse_ranges_; | 358 SparseRangeOffsetMap sparse_ranges_; |
337 base::File sparse_file_; | 359 base::File sparse_file_; |
338 // Offset of the end of the sparse file (where the next sparse range will be | 360 // Offset of the end of the sparse file (where the next sparse range will be |
339 // written). | 361 // written). |
340 int64_t sparse_tail_offset_; | 362 int64_t sparse_tail_offset_; |
341 | 363 |
342 // True if the entry was created, or false if it was opened. Used to log | 364 // True if the entry was created, or false if it was opened. Used to log |
343 // SimpleCache.*.EntryCreatedWithStream2Omitted only for created entries. | 365 // SimpleCache.*.EntryCreatedWithStream2Omitted only for created entries. |
344 bool files_created_; | 366 bool files_created_; |
345 }; | 367 }; |
346 | 368 |
347 } // namespace disk_cache | 369 } // namespace disk_cache |
348 | 370 |
349 #endif // NET_DISK_CACHE_SIMPLE_SIMPLE_SYNCHRONOUS_ENTRY_H_ | 371 #endif // NET_DISK_CACHE_SIMPLE_SIMPLE_SYNCHRONOUS_ENTRY_H_ |
OLD | NEW |