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

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

Issue 22927018: Avoid fragmenting the heap too much while reconstructing the index. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 4 months 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 | Annotate | Revision Log
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/basictypes.h"
9 #include "base/file_util.h" 10 #include "base/file_util.h"
10 #include "base/files/file_enumerator.h"
11 #include "base/files/memory_mapped_file.h" 11 #include "base/files/memory_mapped_file.h"
12 #include "base/hash.h" 12 #include "base/hash.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
15 #include "base/pickle.h" 15 #include "base/pickle.h"
16 #include "base/single_thread_task_runner.h" 16 #include "base/single_thread_task_runner.h"
17 #include "base/task_runner_util.h" 17 #include "base/task_runner_util.h"
18 #include "base/threading/thread_restrictions.h" 18 #include "base/threading/thread_restrictions.h"
19 #include "net/disk_cache/simple/simple_entry_format.h" 19 #include "net/disk_cache/simple/simple_entry_format.h"
20 #include "net/disk_cache/simple/simple_index.h" 20 #include "net/disk_cache/simple/simple_index.h"
21 #include "net/disk_cache/simple/simple_synchronous_entry.h" 21 #include "net/disk_cache/simple/simple_synchronous_entry.h"
22 #include "net/disk_cache/simple/simple_util.h" 22 #include "net/disk_cache/simple/simple_util.h"
23 #include "third_party/zlib/zlib.h" 23 #include "third_party/zlib/zlib.h"
24 24
25 25
26 namespace { 26 namespace {
27 27
28 const int kEntryFilesHashLength = 16;
29 const int kEntryFilesSuffixLength = 2;
30
28 const uint64 kMaxEntiresInIndex = 100000000; 31 const uint64 kMaxEntiresInIndex = 100000000;
29 32
30 uint32 CalculatePickleCRC(const Pickle& pickle) { 33 uint32 CalculatePickleCRC(const Pickle& pickle) {
31 return crc32(crc32(0, Z_NULL, 0), 34 return crc32(crc32(0, Z_NULL, 0),
32 reinterpret_cast<const Bytef*>(pickle.payload()), 35 reinterpret_cast<const Bytef*>(pickle.payload()),
33 pickle.payload_size()); 36 pickle.payload_size());
34 } 37 }
35 38
36 void DoomEntrySetReply(const net::CompletionCallback& reply_callback, 39 void DoomEntrySetReply(const net::CompletionCallback& reply_callback,
37 int result) { 40 int result) {
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 entries->clear(); 341 entries->clear();
339 return; 342 return;
340 } 343 }
341 SimpleIndex::InsertInEntrySet(hash_key, entry_metadata, entries); 344 SimpleIndex::InsertInEntrySet(hash_key, entry_metadata, entries);
342 } 345 }
343 346
344 out_result->did_load = true; 347 out_result->did_load = true;
345 } 348 }
346 349
347 // static 350 // static
351 void SimpleIndexFile::ProcessEntryFile(const std::string& cache_path,
352 std::string* buffer,
353 SimpleIndex::EntrySet* entries,
354 const std::string& file_name) {
355 static const size_t kEntryFilesLength =
356 kEntryFilesHashLength + kEntryFilesSuffixLength;
357 if (file_name.length() != kEntryFilesLength) {
358 if (file_name != "index" && file_name != "fake_index")
359 LOG(ERROR) << "unexpected file " << file_name;
360 return;
361 }
362 buffer->assign(file_name.c_str(), kEntryFilesHashLength);
363 uint64 hash_key = 0;
364 if (!simple_util::GetEntryHashKeyFromHexString(
365 *buffer, &hash_key)) {
366 LOG(WARNING) << "Invalid Entry Hash Key filename while restoring "
367 << "Simple Index from disk: " << *buffer;
368 // TODO(felipeg): Should we delete the invalid file here ?
369 return;
370 }
371
372 buffer->assign(cache_path);
373 buffer->append(&base::FilePath::kSeparators[0], 1);
374 buffer->append(file_name);
gavinp 2013/08/20 20:13:45 I know that we've set capacity(), but I'm still sc
Philippe 2013/08/21 09:37:33 Yeah. I replaced the string with a vector.
375
376 base::FilePath file_path(*buffer);
gavinp 2013/08/20 20:13:45 Does this compile on Win32? More concerning: this
Philippe 2013/08/21 09:37:33 I got rid of FilePath here as we discussed offline
377 base::PlatformFileInfo file_info;
378 if (!file_util::GetFileInfo(file_path, &file_info)) {
379 LOG(INFO) << "Could not get file info for path " << file_path.value();
380 return;
381 }
382 base::Time last_used_time;
383 #if defined(OS_POSIX)
384 // For POSIX systems, a last access time is available. However, it's not
385 // guaranteed to be more accurate than mtime. It is no worse though.
386 last_used_time = file_info.last_accessed;
387 #endif
388 if (last_used_time.is_null())
389 last_used_time = file_info.last_modified;
390
391 int64 file_size = file_info.size;
392 SimpleIndex::EntrySet::iterator it = entries->find(hash_key);
393 if (it == entries->end()) {
394 SimpleIndex::InsertInEntrySet(
395 hash_key,
396 EntryMetadata(last_used_time, file_size),
397 entries);
398 } else {
399 // Summing up the total size of the entry through all the *_[0-2] files
400 it->second.SetEntrySize(it->second.GetEntrySize() + file_size);
401 }
402 }
403
404 // static
348 void SimpleIndexFile::SyncRestoreFromDisk( 405 void SimpleIndexFile::SyncRestoreFromDisk(
349 const base::FilePath& cache_directory, 406 const base::FilePath& cache_directory,
350 const base::FilePath& index_file_path, 407 const base::FilePath& index_file_path,
351 SimpleIndexLoadResult* out_result) { 408 SimpleIndexLoadResult* out_result) {
352 LOG(INFO) << "Simple Cache Index is being restored from disk."; 409 LOG(INFO) << "Simple Cache Index is being restored from disk.";
353
354 base::DeleteFile(index_file_path, /* recursive = */ false); 410 base::DeleteFile(index_file_path, /* recursive = */ false);
355 out_result->Reset(); 411 out_result->Reset();
356 SimpleIndex::EntrySet* entries = &out_result->entries; 412 SimpleIndex::EntrySet* entries = &out_result->entries;
357 413
358 // TODO(felipeg,gavinp): Fix this once we have a one-file per entry format. 414 // TODO(felipeg,gavinp): Fix this once we have a one-file per entry format.
359 COMPILE_ASSERT(kSimpleEntryFileCount == 3, 415 COMPILE_ASSERT(kSimpleEntryFileCount == 3,
360 file_pattern_must_match_file_count); 416 file_pattern_must_match_file_count);
361 417
362 const int kFileSuffixLength = sizeof("_0") - 1; 418 const std::string cache_path = cache_directory.value();
363 const base::FilePath::StringType file_pattern = FILE_PATH_LITERAL("*_[0-2]"); 419 std::string buffer;
364 base::FileEnumerator enumerator(cache_directory, 420 const bool did_succeed = TraverseCacheDirectory(
365 false /* recursive */, 421 cache_path,
366 base::FileEnumerator::FILES, 422 base::Bind(&SimpleIndexFile::ProcessEntryFile, cache_path, &buffer,
367 file_pattern); 423 entries));
368 for (base::FilePath file_path = enumerator.Next(); !file_path.empty(); 424 if (!did_succeed) {
369 file_path = enumerator.Next()) { 425 LOG(ERROR) << "Could not reconstruct index from disk";
370 const base::FilePath::StringType base_name = file_path.BaseName().value(); 426 return;
371 // Converting to std::string is OK since we never use UTF8 wide chars in our
372 // file names.
373 const std::string hash_key_string(base_name.begin(),
374 base_name.end() - kFileSuffixLength);
375 uint64 hash_key = 0;
376 if (!simple_util::GetEntryHashKeyFromHexString(
377 hash_key_string, &hash_key)) {
378 LOG(WARNING) << "Invalid Entry Hash Key filename while restoring "
379 << "Simple Index from disk: " << base_name;
380 // TODO(felipeg): Should we delete the invalid file here ?
381 continue;
382 }
383
384 base::FileEnumerator::FileInfo info = enumerator.GetInfo();
385 base::Time last_used_time;
386 #if defined(OS_POSIX)
387 // For POSIX systems, a last access time is available. However, it's not
388 // guaranteed to be more accurate than mtime. It is no worse though.
389 last_used_time = base::Time::FromTimeT(info.stat().st_atime);
390 #endif
391 if (last_used_time.is_null())
392 last_used_time = info.GetLastModifiedTime();
393
394 int64 file_size = info.GetSize();
395 SimpleIndex::EntrySet::iterator it = entries->find(hash_key);
396 if (it == entries->end()) {
397 SimpleIndex::InsertInEntrySet(
398 hash_key,
399 EntryMetadata(last_used_time, file_size),
400 entries);
401 } else {
402 // Summing up the total size of the entry through all the *_[0-2] files
403 it->second.SetEntrySize(it->second.GetEntrySize() + file_size);
404 }
405 } 427 }
406
407 out_result->did_load = true; 428 out_result->did_load = true;
408
409 // When we restore from disk we write the merged index file to disk right 429 // When we restore from disk we write the merged index file to disk right
410 // away, this might save us from having to restore again next time. 430 // away, this might save us from having to restore again next time.
411 out_result->flush_required = true; 431 out_result->flush_required = true;
412 } 432 }
413 433
414 // static 434 // static
415 bool SimpleIndexFile::IsIndexFileStale(base::Time cache_last_modified, 435 bool SimpleIndexFile::IsIndexFileStale(base::Time cache_last_modified,
416 const base::FilePath& index_file_path) { 436 const base::FilePath& index_file_path) {
417 base::Time index_mtime; 437 base::Time index_mtime;
418 if (!simple_util::GetMTime(index_file_path, &index_mtime)) 438 if (!simple_util::GetMTime(index_file_path, &index_mtime))
419 return true; 439 return true;
420 return index_mtime < cache_last_modified; 440 return index_mtime < cache_last_modified;
421 } 441 }
422 442
423 } // namespace disk_cache 443 } // namespace disk_cache
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698