Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: net/disk_cache/simple/simple_index_file.cc

Issue 651063002: Deflake Simple Cache backend on Windows. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add index file Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 #include "net/disk_cache/simple/simple_index_file.h" 5 #include "net/disk_cache/simple/simple_index_file.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/files/file.h"
9 #include "base/files/file_util.h" 10 #include "base/files/file_util.h"
10 #include "base/files/memory_mapped_file.h" 11 #include "base/files/memory_mapped_file.h"
11 #include "base/hash.h" 12 #include "base/hash.h"
12 #include "base/logging.h" 13 #include "base/logging.h"
13 #include "base/pickle.h" 14 #include "base/pickle.h"
14 #include "base/single_thread_task_runner.h" 15 #include "base/single_thread_task_runner.h"
15 #include "base/task_runner_util.h" 16 #include "base/task_runner_util.h"
16 #include "base/threading/thread_restrictions.h" 17 #include "base/threading/thread_restrictions.h"
17 #include "net/disk_cache/simple/simple_backend_version.h" 18 #include "net/disk_cache/simple/simple_backend_version.h"
18 #include "net/disk_cache/simple/simple_entry_format.h" 19 #include "net/disk_cache/simple/simple_entry_format.h"
19 #include "net/disk_cache/simple/simple_histogram_macros.h" 20 #include "net/disk_cache/simple/simple_histogram_macros.h"
20 #include "net/disk_cache/simple/simple_index.h" 21 #include "net/disk_cache/simple/simple_index.h"
21 #include "net/disk_cache/simple/simple_synchronous_entry.h" 22 #include "net/disk_cache/simple/simple_synchronous_entry.h"
22 #include "net/disk_cache/simple/simple_util.h" 23 #include "net/disk_cache/simple/simple_util.h"
23 #include "third_party/zlib/zlib.h" 24 #include "third_party/zlib/zlib.h"
24 25
26 using base::File;
27
25 namespace disk_cache { 28 namespace disk_cache {
26 namespace { 29 namespace {
27 30
28 const int kEntryFilesHashLength = 16; 31 const int kEntryFilesHashLength = 16;
29 const int kEntryFilesSuffixLength = 2; 32 const int kEntryFilesSuffixLength = 2;
30 33
31 const uint64 kMaxEntiresInIndex = 100000000; 34 const uint64 kMaxEntiresInIndex = 100000000;
32 35
33 uint32 CalculatePickleCRC(const Pickle& pickle) { 36 uint32 CalculatePickleCRC(const Pickle& pickle) {
34 return crc32(crc32(0, Z_NULL, 0), 37 return crc32(crc32(0, Z_NULL, 0),
(...skipping 24 matching lines...) Expand all
59 }; 62 };
60 63
61 void UmaRecordIndexInitMethod(IndexInitMethod method, 64 void UmaRecordIndexInitMethod(IndexInitMethod method,
62 net::CacheType cache_type) { 65 net::CacheType cache_type) {
63 SIMPLE_CACHE_UMA(ENUMERATION, 66 SIMPLE_CACHE_UMA(ENUMERATION,
64 "IndexInitializeMethod", cache_type, 67 "IndexInitializeMethod", cache_type,
65 method, INITIALIZE_METHOD_MAX); 68 method, INITIALIZE_METHOD_MAX);
66 } 69 }
67 70
68 bool WritePickleFile(Pickle* pickle, const base::FilePath& file_name) { 71 bool WritePickleFile(Pickle* pickle, const base::FilePath& file_name) {
69 int bytes_written = base::WriteFile( 72 File file(file_name,
70 file_name, static_cast<const char*>(pickle->data()), pickle->size()); 73 File::FLAG_CREATE_ALWAYS | File::FLAG_WRITE |
74 File::FLAG_SHARE_DELETE);
mmenke 2014/10/28 20:07:43 optional: Think it's much clearer that "File::FLA
gavinp 2014/10/28 23:09:39 Done.
75 if (!file.IsValid())
76 return false;
77
78 int bytes_written =
79 file.Write(0, static_cast<const char*>(pickle->data()), pickle->size());
71 if (bytes_written != implicit_cast<int>(pickle->size())) { 80 if (bytes_written != implicit_cast<int>(pickle->size())) {
72 base::DeleteFile(file_name, /* recursive = */ false); 81 simple_util::SimpleCacheDeleteFile(file_name);
73 return false; 82 return false;
74 } 83 }
75 return true; 84 return true;
76 } 85 }
77 86
78 // Called for each cache directory traversal iteration. 87 // Called for each cache directory traversal iteration.
79 void ProcessEntryFile(SimpleIndex::EntrySet* entries, 88 void ProcessEntryFile(SimpleIndex::EntrySet* entries,
80 const base::FilePath& file_path) { 89 const base::FilePath& file_path) {
81 static const size_t kEntryFilesLength = 90 static const size_t kEntryFilesLength =
82 kEntryFilesHashLength + kEntryFilesSuffixLength; 91 kEntryFilesHashLength + kEntryFilesSuffixLength;
83 // Converting to std::string is OK since we never use UTF8 wide chars in our 92 // Converting to std::string is OK since we never use UTF8 wide chars in our
84 // file names. 93 // file names.
85 const base::FilePath::StringType base_name = file_path.BaseName().value(); 94 const base::FilePath::StringType base_name = file_path.BaseName().value();
86 const std::string file_name(base_name.begin(), base_name.end()); 95 const std::string file_name(base_name.begin(), base_name.end());
87 if (file_name.size() != kEntryFilesLength) 96 if (file_name.size() != kEntryFilesLength)
88 return; 97 return;
89 const base::StringPiece hash_string( 98 const base::StringPiece hash_string(
90 file_name.begin(), file_name.begin() + kEntryFilesHashLength); 99 file_name.begin(), file_name.begin() + kEntryFilesHashLength);
91 uint64 hash_key = 0; 100 uint64 hash_key = 0;
92 if (!simple_util::GetEntryHashKeyFromHexString(hash_string, &hash_key)) { 101 if (!simple_util::GetEntryHashKeyFromHexString(hash_string, &hash_key)) {
93 LOG(WARNING) << "Invalid entry hash key filename while restoring index from" 102 LOG(WARNING) << "Invalid entry hash key filename while restoring index from"
94 << " disk: " << file_name; 103 << " disk: " << file_name;
95 return; 104 return;
96 } 105 }
97 106
98 base::File::Info file_info; 107 File::Info file_info;
99 if (!base::GetFileInfo(file_path, &file_info)) { 108 if (!base::GetFileInfo(file_path, &file_info)) {
100 LOG(ERROR) << "Could not get file info for " << file_path.value(); 109 LOG(ERROR) << "Could not get file info for " << file_path.value();
101 return; 110 return;
102 } 111 }
103 base::Time last_used_time; 112 base::Time last_used_time;
104 #if defined(OS_POSIX) 113 #if defined(OS_POSIX)
105 // For POSIX systems, a last access time is available. However, it's not 114 // For POSIX systems, a last access time is available. However, it's not
106 // guaranteed to be more accurate than mtime. It is no worse though. 115 // guaranteed to be more accurate than mtime. It is no worse though.
107 last_used_time = file_info.last_accessed; 116 last_used_time = file_info.last_accessed;
108 #endif 117 #endif
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 out_result->entries.size()); 334 out_result->entries.size());
326 } 335 }
327 } 336 }
328 337
329 // static 338 // static
330 void SimpleIndexFile::SyncLoadFromDisk(const base::FilePath& index_filename, 339 void SimpleIndexFile::SyncLoadFromDisk(const base::FilePath& index_filename,
331 base::Time* out_last_cache_seen_by_index, 340 base::Time* out_last_cache_seen_by_index,
332 SimpleIndexLoadResult* out_result) { 341 SimpleIndexLoadResult* out_result) {
333 out_result->Reset(); 342 out_result->Reset();
334 343
344 File file(index_filename,
345 File::FLAG_OPEN | File::FLAG_READ | File::FLAG_SHARE_DELETE);
346 if (!file.IsValid())
347 return;
348
335 base::MemoryMappedFile index_file_map; 349 base::MemoryMappedFile index_file_map;
336 if (!index_file_map.Initialize(index_filename)) { 350 if (!index_file_map.Initialize(file.Pass())) {
337 LOG(WARNING) << "Could not map Simple Index file."; 351 simple_util::SimpleCacheDeleteFile(index_filename);
338 base::DeleteFile(index_filename, false);
339 return; 352 return;
340 } 353 }
341 354
342 SimpleIndexFile::Deserialize( 355 SimpleIndexFile::Deserialize(
343 reinterpret_cast<const char*>(index_file_map.data()), 356 reinterpret_cast<const char*>(index_file_map.data()),
344 index_file_map.length(), 357 index_file_map.length(),
345 out_last_cache_seen_by_index, 358 out_last_cache_seen_by_index,
346 out_result); 359 out_result);
347 360
348 if (!out_result->did_load) 361 if (!out_result->did_load)
349 base::DeleteFile(index_filename, false); 362 simple_util::SimpleCacheDeleteFile(index_filename);
350 } 363 }
351 364
352 // static 365 // static
353 scoped_ptr<Pickle> SimpleIndexFile::Serialize( 366 scoped_ptr<Pickle> SimpleIndexFile::Serialize(
354 const SimpleIndexFile::IndexMetadata& index_metadata, 367 const SimpleIndexFile::IndexMetadata& index_metadata,
355 const SimpleIndex::EntrySet& entries) { 368 const SimpleIndex::EntrySet& entries) {
356 scoped_ptr<Pickle> pickle(new Pickle(sizeof(SimpleIndexFile::PickleHeader))); 369 scoped_ptr<Pickle> pickle(new Pickle(sizeof(SimpleIndexFile::PickleHeader)));
357 370
358 index_metadata.Serialize(pickle.get()); 371 index_metadata.Serialize(pickle.get());
359 for (SimpleIndex::EntrySet::const_iterator it = entries.begin(); 372 for (SimpleIndex::EntrySet::const_iterator it = entries.begin();
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 440
428 out_result->did_load = true; 441 out_result->did_load = true;
429 } 442 }
430 443
431 // static 444 // static
432 void SimpleIndexFile::SyncRestoreFromDisk( 445 void SimpleIndexFile::SyncRestoreFromDisk(
433 const base::FilePath& cache_directory, 446 const base::FilePath& cache_directory,
434 const base::FilePath& index_file_path, 447 const base::FilePath& index_file_path,
435 SimpleIndexLoadResult* out_result) { 448 SimpleIndexLoadResult* out_result) {
436 VLOG(1) << "Simple Cache Index is being restored from disk."; 449 VLOG(1) << "Simple Cache Index is being restored from disk.";
437 base::DeleteFile(index_file_path, /* recursive = */ false); 450 simple_util::SimpleCacheDeleteFile(index_file_path);
438 out_result->Reset(); 451 out_result->Reset();
439 SimpleIndex::EntrySet* entries = &out_result->entries; 452 SimpleIndex::EntrySet* entries = &out_result->entries;
440 453
441 const bool did_succeed = TraverseCacheDirectory( 454 const bool did_succeed = TraverseCacheDirectory(
442 cache_directory, base::Bind(&ProcessEntryFile, entries)); 455 cache_directory, base::Bind(&ProcessEntryFile, entries));
443 if (!did_succeed) { 456 if (!did_succeed) {
444 LOG(ERROR) << "Could not reconstruct index from disk"; 457 LOG(ERROR) << "Could not reconstruct index from disk";
445 return; 458 return;
446 } 459 }
447 out_result->did_load = true; 460 out_result->did_load = true;
448 // When we restore from disk we write the merged index file to disk right 461 // When we restore from disk we write the merged index file to disk right
449 // away, this might save us from having to restore again next time. 462 // away, this might save us from having to restore again next time.
450 out_result->flush_required = true; 463 out_result->flush_required = true;
451 } 464 }
452 465
453 // static 466 // static
454 bool SimpleIndexFile::LegacyIsIndexFileStale( 467 bool SimpleIndexFile::LegacyIsIndexFileStale(
455 base::Time cache_last_modified, 468 base::Time cache_last_modified,
456 const base::FilePath& index_file_path) { 469 const base::FilePath& index_file_path) {
457 base::Time index_mtime; 470 base::Time index_mtime;
458 if (!simple_util::GetMTime(index_file_path, &index_mtime)) 471 if (!simple_util::GetMTime(index_file_path, &index_mtime))
459 return true; 472 return true;
460 return index_mtime < cache_last_modified; 473 return index_mtime < cache_last_modified;
461 } 474 }
462 475
463 } // namespace disk_cache 476 } // namespace disk_cache
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698