summaryrefslogtreecommitdiff
path: root/chromium/net/disk_cache
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/disk_cache')
-rw-r--r--chromium/net/disk_cache/backend_unittest.cc2
-rw-r--r--chromium/net/disk_cache/entry_unittest.cc1
-rw-r--r--chromium/net/disk_cache/simple/simple_entry_impl.cc2
-rw-r--r--chromium/net/disk_cache/simple/simple_index_file.cc114
-rw-r--r--chromium/net/disk_cache/simple/simple_index_file.h15
-rw-r--r--chromium/net/disk_cache/simple/simple_index_file_posix.cc52
-rw-r--r--chromium/net/disk_cache/simple/simple_index_file_win.cc33
-rw-r--r--chromium/net/disk_cache/simple/simple_util.cc2
-rw-r--r--chromium/net/disk_cache/simple/simple_util.h3
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|