diff options
Diffstat (limited to 'chromium/net/disk_cache')
-rw-r--r-- | chromium/net/disk_cache/backend_unittest.cc | 2 | ||||
-rw-r--r-- | chromium/net/disk_cache/entry_unittest.cc | 1 | ||||
-rw-r--r-- | chromium/net/disk_cache/simple/simple_entry_impl.cc | 2 | ||||
-rw-r--r-- | chromium/net/disk_cache/simple/simple_index_file.cc | 114 | ||||
-rw-r--r-- | chromium/net/disk_cache/simple/simple_index_file.h | 15 | ||||
-rw-r--r-- | chromium/net/disk_cache/simple/simple_index_file_posix.cc | 52 | ||||
-rw-r--r-- | chromium/net/disk_cache/simple/simple_index_file_win.cc | 33 | ||||
-rw-r--r-- | chromium/net/disk_cache/simple/simple_util.cc | 2 | ||||
-rw-r--r-- | chromium/net/disk_cache/simple/simple_util.h | 3 |
9 files changed, 162 insertions, 62 deletions
diff --git a/chromium/net/disk_cache/backend_unittest.cc b/chromium/net/disk_cache/backend_unittest.cc index 7eeeee1fd83..bc48a2eb203 100644 --- a/chromium/net/disk_cache/backend_unittest.cc +++ b/chromium/net/disk_cache/backend_unittest.cc @@ -313,7 +313,7 @@ TEST_F(DiskCacheBackendTest, CreateBackend_MissingFile) { scoped_ptr<disk_cache::BackendImpl> cache(new disk_cache::BackendImpl( cache_path_, cache_thread.message_loop_proxy().get(), NULL)); int rv = cache->Init(cb.callback()); - EXPECT_EQ(net::ERR_FAILED, cb.GetResult(rv)); + ASSERT_EQ(net::ERR_FAILED, cb.GetResult(rv)); base::ThreadRestrictions::SetIOAllowed(prev); cache.reset(); diff --git a/chromium/net/disk_cache/entry_unittest.cc b/chromium/net/disk_cache/entry_unittest.cc index 7addc85e5a0..857e07f1b7b 100644 --- a/chromium/net/disk_cache/entry_unittest.cc +++ b/chromium/net/disk_cache/entry_unittest.cc @@ -392,6 +392,7 @@ void DiskCacheEntryTest::ExternalSyncIOBackground(disk_cache::Entry* entry) { EXPECT_EQ( 25000, entry->ReadData(1, 0, buffer2.get(), kSize2, net::CompletionCallback())); + EXPECT_EQ(0, memcmp(buffer2->data(), buffer2->data(), 10000)); EXPECT_EQ(5000, entry->ReadData( 1, 30000, buffer2.get(), kSize2, net::CompletionCallback())); diff --git a/chromium/net/disk_cache/simple/simple_entry_impl.cc b/chromium/net/disk_cache/simple/simple_entry_impl.cc index 3c3ec7daff6..cbee6048371 100644 --- a/chromium/net/disk_cache/simple/simple_entry_impl.cc +++ b/chromium/net/disk_cache/simple/simple_entry_impl.cc @@ -496,7 +496,7 @@ int SimpleEntryImpl::ReadyForSparseIO(const CompletionCallback& callback) { DCHECK(io_thread_checker_.CalledOnValidThread()); // TODO(gavinp): Determine if the simple backend should support sparse data. NOTIMPLEMENTED(); - return net::ERR_FAILED; + return net::ERR_NOT_IMPLEMENTED; } SimpleEntryImpl::~SimpleEntryImpl() { diff --git a/chromium/net/disk_cache/simple/simple_index_file.cc b/chromium/net/disk_cache/simple/simple_index_file.cc index 7bcea7cdfa8..0136be1c5a0 100644 --- a/chromium/net/disk_cache/simple/simple_index_file.cc +++ b/chromium/net/disk_cache/simple/simple_index_file.cc @@ -7,7 +7,6 @@ #include <vector> #include "base/file_util.h" -#include "base/files/file_enumerator.h" #include "base/files/memory_mapped_file.h" #include "base/hash.h" #include "base/logging.h" @@ -22,11 +21,17 @@ #include "net/disk_cache/simple/simple_util.h" #include "third_party/zlib/zlib.h" - +namespace disk_cache { namespace { +const int kEntryFilesHashLength = 16; +const int kEntryFilesSuffixLength = 2; + const uint64 kMaxEntiresInIndex = 100000000; +const char kIndexFileName[] = "the-real-index"; +const char kTempIndexFileName[] = "temp-index"; + uint32 CalculatePickleCRC(const Pickle& pickle) { return crc32(crc32(0, Z_NULL, 0), reinterpret_cast<const Bytef*>(pickle.payload()), @@ -67,9 +72,54 @@ void WriteToDiskInternal(const base::FilePath& index_filename, } } -} // namespace +// Called for each cache directory traversal iteration. +void ProcessEntryFile(SimpleIndex::EntrySet* entries, + const base::FilePath& file_path) { + static const size_t kEntryFilesLength = + kEntryFilesHashLength + kEntryFilesSuffixLength; + // Converting to std::string is OK since we never use UTF8 wide chars in our + // file names. + const base::FilePath::StringType base_name = file_path.BaseName().value(); + const std::string file_name(base_name.begin(), base_name.end()); + if (file_name.size() != kEntryFilesLength) + return; + const base::StringPiece hash_string( + file_name.begin(), file_name.begin() + kEntryFilesHashLength); + uint64 hash_key = 0; + if (!simple_util::GetEntryHashKeyFromHexString(hash_string, &hash_key)) { + LOG(WARNING) << "Invalid entry hash key filename while restoring index from" + << " disk: " << file_name; + return; + } -namespace disk_cache { + base::PlatformFileInfo file_info; + if (!file_util::GetFileInfo(file_path, &file_info)) { + LOG(ERROR) << "Could not get file info for " << file_path.value(); + return; + } + base::Time last_used_time; +#if defined(OS_POSIX) + // For POSIX systems, a last access time is available. However, it's not + // guaranteed to be more accurate than mtime. It is no worse though. + last_used_time = file_info.last_accessed; +#endif + if (last_used_time.is_null()) + last_used_time = file_info.last_modified; + + int64 file_size = file_info.size; + SimpleIndex::EntrySet::iterator it = entries->find(hash_key); + if (it == entries->end()) { + SimpleIndex::InsertInEntrySet( + hash_key, + EntryMetadata(last_used_time, file_size), + entries); + } else { + // Summing up the total size of the entry through all the *_[0-2] files + it->second.SetEntrySize(it->second.GetEntrySize() + file_size); + } +} + +} // namespace SimpleIndexLoadResult::SimpleIndexLoadResult() : did_load(false), flush_required(false) { @@ -84,11 +134,6 @@ void SimpleIndexLoadResult::Reset() { entries.clear(); } -// static -const char SimpleIndexFile::kIndexFileName[] = "the-real-index"; -// static -const char SimpleIndexFile::kTempIndexFileName[] = "temp-index"; - SimpleIndexFile::IndexMetadata::IndexMetadata() : magic_number_(kSimpleIndexMagicNumber), version_(kSimpleVersion), @@ -350,7 +395,6 @@ void SimpleIndexFile::SyncRestoreFromDisk( const base::FilePath& index_file_path, SimpleIndexLoadResult* out_result) { LOG(INFO) << "Simple Cache Index is being restored from disk."; - base::DeleteFile(index_file_path, /* recursive = */ false); out_result->Reset(); SimpleIndex::EntrySet* entries = &out_result->entries; @@ -359,53 +403,13 @@ void SimpleIndexFile::SyncRestoreFromDisk( COMPILE_ASSERT(kSimpleEntryFileCount == 3, file_pattern_must_match_file_count); - const int kFileSuffixLength = sizeof("_0") - 1; - const base::FilePath::StringType file_pattern = FILE_PATH_LITERAL("*_[0-2]"); - base::FileEnumerator enumerator(cache_directory, - false /* recursive */, - base::FileEnumerator::FILES, - file_pattern); - for (base::FilePath file_path = enumerator.Next(); !file_path.empty(); - file_path = enumerator.Next()) { - const base::FilePath::StringType base_name = file_path.BaseName().value(); - // Converting to std::string is OK since we never use UTF8 wide chars in our - // file names. - const std::string hash_key_string(base_name.begin(), - base_name.end() - kFileSuffixLength); - uint64 hash_key = 0; - if (!simple_util::GetEntryHashKeyFromHexString( - hash_key_string, &hash_key)) { - LOG(WARNING) << "Invalid Entry Hash Key filename while restoring " - << "Simple Index from disk: " << base_name; - // TODO(felipeg): Should we delete the invalid file here ? - continue; - } - - base::FileEnumerator::FileInfo info = enumerator.GetInfo(); - base::Time last_used_time; -#if defined(OS_POSIX) - // For POSIX systems, a last access time is available. However, it's not - // guaranteed to be more accurate than mtime. It is no worse though. - last_used_time = base::Time::FromTimeT(info.stat().st_atime); -#endif - if (last_used_time.is_null()) - last_used_time = info.GetLastModifiedTime(); - - int64 file_size = info.GetSize(); - SimpleIndex::EntrySet::iterator it = entries->find(hash_key); - if (it == entries->end()) { - SimpleIndex::InsertInEntrySet( - hash_key, - EntryMetadata(last_used_time, file_size), - entries); - } else { - // Summing up the total size of the entry through all the *_[0-2] files - it->second.SetEntrySize(it->second.GetEntrySize() + file_size); - } + const bool did_succeed = TraverseCacheDirectory( + cache_directory, base::Bind(&ProcessEntryFile, entries)); + if (!did_succeed) { + LOG(ERROR) << "Could not reconstruct index from disk"; + return; } - out_result->did_load = true; - // When we restore from disk we write the merged index file to disk right // away, this might save us from having to restore again next time. out_result->flush_required = true; diff --git a/chromium/net/disk_cache/simple/simple_index_file.h b/chromium/net/disk_cache/simple/simple_index_file.h index b536df9a1e7..e5fc85d69a2 100644 --- a/chromium/net/disk_cache/simple/simple_index_file.h +++ b/chromium/net/disk_cache/simple/simple_index_file.h @@ -97,6 +97,9 @@ class NET_EXPORT_PRIVATE SimpleIndexFile { private: friend class WrappedSimpleIndexFile; + // Used for cache directory traversal. + typedef base::Callback<void (const base::FilePath&)> EntryFileCallback; + // When loading the entries from disk, add this many extra hash buckets to // prevent reallocation on the IO thread when merging in new live entries. static const int kExtraSizeForMerge = 512; @@ -123,6 +126,15 @@ class NET_EXPORT_PRIVATE SimpleIndexFile { static void Deserialize(const char* data, int data_len, SimpleIndexLoadResult* out_result); + // Implemented either in simple_index_file_posix.cc or + // simple_index_file_win.cc. base::FileEnumerator turned out to be very + // expensive in terms of memory usage therefore it's used only on non-POSIX + // environments for convenience (for now). Returns whether the traversal + // succeeded. + static bool TraverseCacheDirectory( + const base::FilePath& cache_path, + const EntryFileCallback& entry_file_callback); + // Scan the index directory for entries, returning an EntrySet of all entries // found. static void SyncRestoreFromDisk(const base::FilePath& cache_directory, @@ -144,9 +156,6 @@ class NET_EXPORT_PRIVATE SimpleIndexFile { const base::FilePath index_file_; const base::FilePath temp_index_file_; - static const char kIndexFileName[]; - static const char kTempIndexFileName[]; - DISALLOW_COPY_AND_ASSIGN(SimpleIndexFile); }; diff --git a/chromium/net/disk_cache/simple/simple_index_file_posix.cc b/chromium/net/disk_cache/simple/simple_index_file_posix.cc new file mode 100644 index 00000000000..586699d2a8e --- /dev/null +++ b/chromium/net/disk_cache/simple/simple_index_file_posix.cc @@ -0,0 +1,52 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/disk_cache/simple/simple_index_file.h" + +#include <dirent.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +#include <string> + +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" + +namespace disk_cache { +namespace { + +struct DirCloser { + void operator()(DIR* dir) { closedir(dir); } +}; + +typedef scoped_ptr<DIR, DirCloser> ScopedDir; + +} // namespace + +// static +bool SimpleIndexFile::TraverseCacheDirectory( + const base::FilePath& cache_path, + const EntryFileCallback& entry_file_callback) { + const ScopedDir dir(opendir(cache_path.value().c_str())); + if (!dir) { + PLOG(ERROR) << "opendir " << cache_path.value(); + return false; + } + dirent entry, *result; + while (readdir_r(dir.get(), &entry, &result) == 0) { + if (!result) + return true; // The traversal completed successfully. + const std::string file_name(result->d_name); + if (file_name == "." || file_name == "..") + continue; + const base::FilePath file_path = cache_path.Append( + base::FilePath(file_name)); + entry_file_callback.Run(file_path); + } + PLOG(ERROR) << "readdir_r " << cache_path.value(); + return false; +} + +} // namespace disk_cache diff --git a/chromium/net/disk_cache/simple/simple_index_file_win.cc b/chromium/net/disk_cache/simple/simple_index_file_win.cc new file mode 100644 index 00000000000..051d12deaf7 --- /dev/null +++ b/chromium/net/disk_cache/simple/simple_index_file_win.cc @@ -0,0 +1,33 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/disk_cache/simple/simple_index_file.h" + +#include <string> + +#include "base/files/file_enumerator.h" +#include "base/files/file_path.h" + +namespace disk_cache { + +// static +bool SimpleIndexFile::TraverseCacheDirectory( + const base::FilePath& cache_path, + const EntryFileCallback& entry_file_callback) { + const base::FilePath current_directory(FILE_PATH_LITERAL(".")); + const base::FilePath parent_directory(FILE_PATH_LITERAL("..")); + const base::FilePath::StringType file_pattern = FILE_PATH_LITERAL("*"); + base::FileEnumerator enumerator( + cache_path, false /* recursive */, base::FileEnumerator::FILES, + file_pattern); + for (base::FilePath file_path = enumerator.Next(); !file_path.empty(); + file_path = enumerator.Next()) { + if (file_path == current_directory || file_path == parent_directory) + continue; + entry_file_callback.Run(file_path); + } + return true; +} + +} // namespace disk_cache diff --git a/chromium/net/disk_cache/simple/simple_util.cc b/chromium/net/disk_cache/simple/simple_util.cc index 72a4612271f..e9ec067635a 100644 --- a/chromium/net/disk_cache/simple/simple_util.cc +++ b/chromium/net/disk_cache/simple/simple_util.cc @@ -40,7 +40,7 @@ std::string GetEntryHashKeyAsHexString(const std::string& key) { return hash_key_str; } -bool GetEntryHashKeyFromHexString(const std::string& hash_key, +bool GetEntryHashKeyFromHexString(const base::StringPiece& hash_key, uint64* hash_key_out) { if (hash_key.size() != kEntryHashKeyAsHexStringSize) { return false; diff --git a/chromium/net/disk_cache/simple/simple_util.h b/chromium/net/disk_cache/simple/simple_util.h index 2e92b4a049d..3bb80b95402 100644 --- a/chromium/net/disk_cache/simple/simple_util.h +++ b/chromium/net/disk_cache/simple/simple_util.h @@ -8,6 +8,7 @@ #include <string> #include "base/basictypes.h" +#include "base/strings/string_piece.h" #include "net/base/net_export.h" namespace base { @@ -33,7 +34,7 @@ NET_EXPORT_PRIVATE uint64 GetEntryHashKey(const std::string& key); // Parses the |hash_key| string into a uint64 buffer. // |hash_key| string must be of the form: FFFFFFFFFFFFFFFF . NET_EXPORT_PRIVATE bool GetEntryHashKeyFromHexString( - const std::string& hash_key, + const base::StringPiece& hash_key, uint64* hash_key_out); // Given a |key| for a (potential) entry in the simple backend and the |index| |