summaryrefslogtreecommitdiffstats
path: root/net/disk_cache
diff options
context:
space:
mode:
authorrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-15 18:50:39 +0000
committerrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-15 18:50:39 +0000
commitaac186e80cc3fee4a7f7631433b7baab944f9239 (patch)
tree85ae7eb2b2395695f5daab470cfa5152b3a7b358 /net/disk_cache
parent6b658bf84d667bbaacd59d6337a09ac2e80645a8 (diff)
downloadchromium_src-aac186e80cc3fee4a7f7631433b7baab944f9239.zip
chromium_src-aac186e80cc3fee4a7f7631433b7baab944f9239.tar.gz
chromium_src-aac186e80cc3fee4a7f7631433b7baab944f9239.tar.bz2
Disk cache: Read the index and data_0 files in a single
operation to reduce multiple IO operations generated by on-demand paging. Also, generate extra histograms and improve the scale of some others. BUG=none TEST=net_unittests Review URL: http://codereview.chromium.org/2891022 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@52506 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/disk_cache')
-rw-r--r--net/disk_cache/addr.h2
-rw-r--r--net/disk_cache/backend_impl.cc16
-rw-r--r--net/disk_cache/backend_unittest.cc122
-rw-r--r--net/disk_cache/block_files.cc74
-rw-r--r--net/disk_cache/block_files.h7
-rw-r--r--net/disk_cache/block_files_unittest.cc22
-rw-r--r--net/disk_cache/disk_cache_test_util.cc14
-rw-r--r--net/disk_cache/disk_cache_test_util.h3
8 files changed, 174 insertions, 86 deletions
diff --git a/net/disk_cache/addr.h b/net/disk_cache/addr.h
index a504019..938a442 100644
--- a/net/disk_cache/addr.h
+++ b/net/disk_cache/addr.h
@@ -23,7 +23,7 @@ enum FileType {
const int kMaxBlockSize = 4096 * 4;
const int kMaxBlockFile = 255;
const int kMaxNumBlocks = 4;
-const int kFirstAdditionlBlockFile = 4;
+const int kFirstAdditionalBlockFile = 4;
// Defines a storage address for a cache record
//
diff --git a/net/disk_cache/backend_impl.cc b/net/disk_cache/backend_impl.cc
index 0194bb9..94e0b08 100644
--- a/net/disk_cache/backend_impl.cc
+++ b/net/disk_cache/backend_impl.cc
@@ -1719,12 +1719,12 @@ void BackendImpl::LogStats() {
void BackendImpl::ReportStats() {
CACHE_UMA(COUNTS, "Entries", 0, data_->header.num_entries);
- CACHE_UMA(COUNTS, "Size", 0, data_->header.num_bytes / (1024 * 1024));
- CACHE_UMA(COUNTS, "MaxSize", 0, max_size_ / (1024 * 1024));
+ CACHE_UMA(COUNTS_10000, "Size2", 0, data_->header.num_bytes / (1024 * 1024));
+ CACHE_UMA(COUNTS_10000, "MaxSize2", 0, max_size_ / (1024 * 1024));
- CACHE_UMA(COUNTS, "AverageOpenEntries", 0,
+ CACHE_UMA(COUNTS_10000, "AverageOpenEntries2", 0,
static_cast<int>(stats_.GetCounter(Stats::OPEN_ENTRIES)));
- CACHE_UMA(COUNTS, "MaxOpenEntries", 0,
+ CACHE_UMA(COUNTS_10000, "MaxOpenEntries2", 0,
static_cast<int>(stats_.GetCounter(Stats::MAX_ENTRIES)));
stats_.SetCounter(Stats::MAX_ENTRIES, 0);
@@ -1756,6 +1756,7 @@ void BackendImpl::ReportStats() {
int avg_size = data_->header.num_bytes / GetEntryCount();
CACHE_UMA(COUNTS, "EntrySize", 0, avg_size);
+ CACHE_UMA(COUNTS, "EntriesFull", 0, data_->header.num_entries);
CACHE_UMA(PERCENTAGE, "IndexLoad", 0,
data_->header.num_entries * 100 / (mask_ + 1));
@@ -1778,6 +1779,9 @@ void BackendImpl::ReportStats() {
stats_.ResetRatios();
stats_.SetCounter(Stats::TRIM_ENTRY, 0);
+
+ if (cache_type_ == net::DISK_CACHE)
+ block_files_.ReportStats();
}
void BackendImpl::UpgradeTo2_1() {
@@ -1844,7 +1848,9 @@ bool BackendImpl::CheckIndex() {
if (!mask_)
mask_ = data_->header.table_len - 1;
- return true;
+ // Load the table into memory with a single read.
+ scoped_array<char> buf(new char[current_size]);
+ return index_->Read(buf.get(), current_size, 0);
}
int BackendImpl::CheckAllEntries() {
diff --git a/net/disk_cache/backend_unittest.cc b/net/disk_cache/backend_unittest.cc
index a9ab2a2..58d8da9 100644
--- a/net/disk_cache/backend_unittest.cc
+++ b/net/disk_cache/backend_unittest.cc
@@ -4,7 +4,6 @@
#include "base/basictypes.h"
#include "base/file_util.h"
-#include "base/path_service.h"
#include "base/platform_thread.h"
#include "base/string_util.h"
#include "net/base/io_buffer.h"
@@ -20,25 +19,6 @@
using base::Time;
-namespace {
-
-// Copies a set of cache files from the data folder to the test folder.
-bool CopyTestCache(const std::wstring& name) {
- FilePath path;
- PathService::Get(base::DIR_SOURCE_ROOT, &path);
- path = path.AppendASCII("net");
- path = path.AppendASCII("data");
- path = path.AppendASCII("cache_tests");
- path = path.Append(FilePath::FromWStringHack(name));
-
- FilePath dest = GetCacheFilePath();
- if (!DeleteCache(dest))
- return false;
- return file_util::CopyDirectory(path, dest, false);
-}
-
-} // namespace
-
// Tests that can run with different types of caches.
class DiskCacheBackendTest : public DiskCacheTestWithCache {
protected:
@@ -58,11 +38,11 @@ class DiskCacheBackendTest : public DiskCacheTestWithCache {
void BackendFixEnumerators();
void BackendDoomRecent();
void BackendDoomBetween();
- void BackendTransaction(const std::wstring& name, int num_entries, bool load);
+ void BackendTransaction(const std::string& name, int num_entries, bool load);
void BackendRecoverInsert();
void BackendRecoverRemove();
void BackendInvalidEntry2();
- void BackendNotMarkedButDirty(const std::wstring& name);
+ void BackendNotMarkedButDirty(const std::string& name);
void BackendDoomAll();
void BackendDoomAll2();
void BackendInvalidRankings();
@@ -1087,7 +1067,7 @@ TEST_F(DiskCacheBackendTest, MemoryOnlyDoomBetween) {
BackendDoomBetween();
}
-void DiskCacheBackendTest::BackendTransaction(const std::wstring& name,
+void DiskCacheBackendTest::BackendTransaction(const std::string& name,
int num_entries, bool load) {
success_ = false;
ASSERT_TRUE(CopyTestCache(name));
@@ -1127,25 +1107,25 @@ void DiskCacheBackendTest::BackendTransaction(const std::wstring& name,
void DiskCacheBackendTest::BackendRecoverInsert() {
// Tests with an empty cache.
- BackendTransaction(L"insert_empty1", 0, false);
+ BackendTransaction("insert_empty1", 0, false);
ASSERT_TRUE(success_) << "insert_empty1";
- BackendTransaction(L"insert_empty2", 0, false);
+ BackendTransaction("insert_empty2", 0, false);
ASSERT_TRUE(success_) << "insert_empty2";
- BackendTransaction(L"insert_empty3", 0, false);
+ BackendTransaction("insert_empty3", 0, false);
ASSERT_TRUE(success_) << "insert_empty3";
// Tests with one entry on the cache.
- BackendTransaction(L"insert_one1", 1, false);
+ BackendTransaction("insert_one1", 1, false);
ASSERT_TRUE(success_) << "insert_one1";
- BackendTransaction(L"insert_one2", 1, false);
+ BackendTransaction("insert_one2", 1, false);
ASSERT_TRUE(success_) << "insert_one2";
- BackendTransaction(L"insert_one3", 1, false);
+ BackendTransaction("insert_one3", 1, false);
ASSERT_TRUE(success_) << "insert_one3";
// Tests with one hundred entries on the cache, tiny index.
- BackendTransaction(L"insert_load1", 100, true);
+ BackendTransaction("insert_load1", 100, true);
ASSERT_TRUE(success_) << "insert_load1";
- BackendTransaction(L"insert_load2", 100, true);
+ BackendTransaction("insert_load2", 100, true);
ASSERT_TRUE(success_) << "insert_load2";
}
@@ -1160,42 +1140,42 @@ TEST_F(DiskCacheBackendTest, NewEvictionRecoverInsert) {
void DiskCacheBackendTest::BackendRecoverRemove() {
// Removing the only element.
- BackendTransaction(L"remove_one1", 0, false);
+ BackendTransaction("remove_one1", 0, false);
ASSERT_TRUE(success_) << "remove_one1";
- BackendTransaction(L"remove_one2", 0, false);
+ BackendTransaction("remove_one2", 0, false);
ASSERT_TRUE(success_) << "remove_one2";
- BackendTransaction(L"remove_one3", 0, false);
+ BackendTransaction("remove_one3", 0, false);
ASSERT_TRUE(success_) << "remove_one3";
// Removing the head.
- BackendTransaction(L"remove_head1", 1, false);
+ BackendTransaction("remove_head1", 1, false);
ASSERT_TRUE(success_) << "remove_head1";
- BackendTransaction(L"remove_head2", 1, false);
+ BackendTransaction("remove_head2", 1, false);
ASSERT_TRUE(success_) << "remove_head2";
- BackendTransaction(L"remove_head3", 1, false);
+ BackendTransaction("remove_head3", 1, false);
ASSERT_TRUE(success_) << "remove_head3";
// Removing the tail.
- BackendTransaction(L"remove_tail1", 1, false);
+ BackendTransaction("remove_tail1", 1, false);
ASSERT_TRUE(success_) << "remove_tail1";
- BackendTransaction(L"remove_tail2", 1, false);
+ BackendTransaction("remove_tail2", 1, false);
ASSERT_TRUE(success_) << "remove_tail2";
- BackendTransaction(L"remove_tail3", 1, false);
+ BackendTransaction("remove_tail3", 1, false);
ASSERT_TRUE(success_) << "remove_tail3";
// Removing with one hundred entries on the cache, tiny index.
- BackendTransaction(L"remove_load1", 100, true);
+ BackendTransaction("remove_load1", 100, true);
ASSERT_TRUE(success_) << "remove_load1";
- BackendTransaction(L"remove_load2", 100, true);
+ BackendTransaction("remove_load2", 100, true);
ASSERT_TRUE(success_) << "remove_load2";
- BackendTransaction(L"remove_load3", 100, true);
+ BackendTransaction("remove_load3", 100, true);
ASSERT_TRUE(success_) << "remove_load3";
#ifdef NDEBUG
// This case cannot be reverted, so it will assert on debug builds.
- BackendTransaction(L"remove_one4", 0, false);
+ BackendTransaction("remove_one4", 0, false);
ASSERT_TRUE(success_) << "remove_one4";
- BackendTransaction(L"remove_head4", 1, false);
+ BackendTransaction("remove_head4", 1, false);
ASSERT_TRUE(success_) << "remove_head4";
#endif
}
@@ -1211,7 +1191,7 @@ TEST_F(DiskCacheBackendTest, NewEvictionRecoverRemove) {
// Tests dealing with cache files that cannot be recovered.
TEST_F(DiskCacheTest, DeleteOld) {
- ASSERT_TRUE(CopyTestCache(L"wrong_version"));
+ ASSERT_TRUE(CopyTestCache("wrong_version"));
FilePath path = GetCacheFilePath();
base::Thread cache_thread("CacheThread");
ASSERT_TRUE(cache_thread.StartWithOptions(
@@ -1234,7 +1214,7 @@ TEST_F(DiskCacheTest, DeleteOld) {
// We want to be able to deal with messed up entries on disk.
void DiskCacheBackendTest::BackendInvalidEntry2() {
- ASSERT_TRUE(CopyTestCache(L"bad_entry"));
+ ASSERT_TRUE(CopyTestCache("bad_entry"));
DisableFirstCleanup();
InitCache();
@@ -1257,7 +1237,7 @@ TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntry2) {
}
// We want to be able to deal with abnormal dirty entries.
-void DiskCacheBackendTest::BackendNotMarkedButDirty(const std::wstring& name) {
+void DiskCacheBackendTest::BackendNotMarkedButDirty(const std::string& name) {
ASSERT_TRUE(CopyTestCache(name));
DisableFirstCleanup();
InitCache();
@@ -1269,26 +1249,26 @@ void DiskCacheBackendTest::BackendNotMarkedButDirty(const std::wstring& name) {
}
TEST_F(DiskCacheBackendTest, NotMarkedButDirty) {
- BackendNotMarkedButDirty(L"dirty_entry");
+ BackendNotMarkedButDirty("dirty_entry");
}
TEST_F(DiskCacheBackendTest, NewEvictionNotMarkedButDirty) {
SetNewEviction();
- BackendNotMarkedButDirty(L"dirty_entry");
+ BackendNotMarkedButDirty("dirty_entry");
}
TEST_F(DiskCacheBackendTest, NotMarkedButDirty2) {
- BackendNotMarkedButDirty(L"dirty_entry2");
+ BackendNotMarkedButDirty("dirty_entry2");
}
TEST_F(DiskCacheBackendTest, NewEvictionNotMarkedButDirty2) {
SetNewEviction();
- BackendNotMarkedButDirty(L"dirty_entry2");
+ BackendNotMarkedButDirty("dirty_entry2");
}
// We want to be able to deal with messed up entries on disk.
void DiskCacheBackendTest::BackendInvalidRankings2() {
- ASSERT_TRUE(CopyTestCache(L"bad_rankings"));
+ ASSERT_TRUE(CopyTestCache("bad_rankings"));
FilePath path = GetCacheFilePath();
DisableFirstCleanup();
InitCache();
@@ -1325,7 +1305,7 @@ void DiskCacheBackendTest::BackendInvalidRankings() {
}
TEST_F(DiskCacheBackendTest, InvalidRankingsSuccess) {
- ASSERT_TRUE(CopyTestCache(L"bad_rankings"));
+ ASSERT_TRUE(CopyTestCache("bad_rankings"));
DisableFirstCleanup();
SetDirectMode();
InitCache();
@@ -1333,7 +1313,7 @@ TEST_F(DiskCacheBackendTest, InvalidRankingsSuccess) {
}
TEST_F(DiskCacheBackendTest, NewEvictionInvalidRankingsSuccess) {
- ASSERT_TRUE(CopyTestCache(L"bad_rankings"));
+ ASSERT_TRUE(CopyTestCache("bad_rankings"));
DisableFirstCleanup();
SetDirectMode();
SetNewEviction();
@@ -1342,7 +1322,7 @@ TEST_F(DiskCacheBackendTest, NewEvictionInvalidRankingsSuccess) {
}
TEST_F(DiskCacheBackendTest, InvalidRankingsFailure) {
- ASSERT_TRUE(CopyTestCache(L"bad_rankings"));
+ ASSERT_TRUE(CopyTestCache("bad_rankings"));
DisableFirstCleanup();
SetDirectMode();
InitCache();
@@ -1351,7 +1331,7 @@ TEST_F(DiskCacheBackendTest, InvalidRankingsFailure) {
}
TEST_F(DiskCacheBackendTest, NewEvictionInvalidRankingsFailure) {
- ASSERT_TRUE(CopyTestCache(L"bad_rankings"));
+ ASSERT_TRUE(CopyTestCache("bad_rankings"));
DisableFirstCleanup();
SetDirectMode();
SetNewEviction();
@@ -1378,7 +1358,7 @@ void DiskCacheBackendTest::BackendDisable() {
}
TEST_F(DiskCacheBackendTest, DisableSuccess) {
- ASSERT_TRUE(CopyTestCache(L"bad_rankings"));
+ ASSERT_TRUE(CopyTestCache("bad_rankings"));
DisableFirstCleanup();
SetDirectMode();
InitCache();
@@ -1386,7 +1366,7 @@ TEST_F(DiskCacheBackendTest, DisableSuccess) {
}
TEST_F(DiskCacheBackendTest, NewEvictionDisableSuccess) {
- ASSERT_TRUE(CopyTestCache(L"bad_rankings"));
+ ASSERT_TRUE(CopyTestCache("bad_rankings"));
DisableFirstCleanup();
SetDirectMode();
SetNewEviction();
@@ -1395,7 +1375,7 @@ TEST_F(DiskCacheBackendTest, NewEvictionDisableSuccess) {
}
TEST_F(DiskCacheBackendTest, DisableFailure) {
- ASSERT_TRUE(CopyTestCache(L"bad_rankings"));
+ ASSERT_TRUE(CopyTestCache("bad_rankings"));
DisableFirstCleanup();
SetDirectMode();
InitCache();
@@ -1404,7 +1384,7 @@ TEST_F(DiskCacheBackendTest, DisableFailure) {
}
TEST_F(DiskCacheBackendTest, NewEvictionDisableFailure) {
- ASSERT_TRUE(CopyTestCache(L"bad_rankings"));
+ ASSERT_TRUE(CopyTestCache("bad_rankings"));
DisableFirstCleanup();
SetDirectMode();
SetNewEviction();
@@ -1432,7 +1412,7 @@ void DiskCacheBackendTest::BackendDisable2() {
}
TEST_F(DiskCacheBackendTest, DisableSuccess2) {
- ASSERT_TRUE(CopyTestCache(L"list_loop"));
+ ASSERT_TRUE(CopyTestCache("list_loop"));
DisableFirstCleanup();
SetDirectMode();
InitCache();
@@ -1440,7 +1420,7 @@ TEST_F(DiskCacheBackendTest, DisableSuccess2) {
}
TEST_F(DiskCacheBackendTest, NewEvictionDisableSuccess2) {
- ASSERT_TRUE(CopyTestCache(L"list_loop"));
+ ASSERT_TRUE(CopyTestCache("list_loop"));
DisableFirstCleanup();
SetNewEviction();
SetDirectMode();
@@ -1449,7 +1429,7 @@ TEST_F(DiskCacheBackendTest, NewEvictionDisableSuccess2) {
}
TEST_F(DiskCacheBackendTest, DisableFailure2) {
- ASSERT_TRUE(CopyTestCache(L"list_loop"));
+ ASSERT_TRUE(CopyTestCache("list_loop"));
DisableFirstCleanup();
SetDirectMode();
InitCache();
@@ -1458,7 +1438,7 @@ TEST_F(DiskCacheBackendTest, DisableFailure2) {
}
TEST_F(DiskCacheBackendTest, NewEvictionDisableFailure2) {
- ASSERT_TRUE(CopyTestCache(L"list_loop"));
+ ASSERT_TRUE(CopyTestCache("list_loop"));
DisableFirstCleanup();
SetDirectMode();
SetNewEviction();
@@ -1485,7 +1465,7 @@ void DiskCacheBackendTest::BackendDisable3() {
}
TEST_F(DiskCacheBackendTest, DisableSuccess3) {
- ASSERT_TRUE(CopyTestCache(L"bad_rankings2"));
+ ASSERT_TRUE(CopyTestCache("bad_rankings2"));
DisableFirstCleanup();
SetMaxSize(20 * 1024 * 1024);
InitCache();
@@ -1493,7 +1473,7 @@ TEST_F(DiskCacheBackendTest, DisableSuccess3) {
}
TEST_F(DiskCacheBackendTest, NewEvictionDisableSuccess3) {
- ASSERT_TRUE(CopyTestCache(L"bad_rankings2"));
+ ASSERT_TRUE(CopyTestCache("bad_rankings2"));
DisableFirstCleanup();
SetMaxSize(20 * 1024 * 1024);
SetNewEviction();
@@ -1551,7 +1531,7 @@ void DiskCacheBackendTest::BackendDisable4() {
}
TEST_F(DiskCacheBackendTest, DisableSuccess4) {
- ASSERT_TRUE(CopyTestCache(L"bad_rankings"));
+ ASSERT_TRUE(CopyTestCache("bad_rankings"));
DisableFirstCleanup();
SetDirectMode();
InitCache();
@@ -1559,7 +1539,7 @@ TEST_F(DiskCacheBackendTest, DisableSuccess4) {
}
TEST_F(DiskCacheBackendTest, NewEvictionDisableSuccess4) {
- ASSERT_TRUE(CopyTestCache(L"bad_rankings"));
+ ASSERT_TRUE(CopyTestCache("bad_rankings"));
DisableFirstCleanup();
SetDirectMode();
SetNewEviction();
@@ -1655,7 +1635,7 @@ void DiskCacheBackendTest::BackendDoomAll2() {
}
TEST_F(DiskCacheBackendTest, DoomAll2) {
- ASSERT_TRUE(CopyTestCache(L"bad_rankings2"));
+ ASSERT_TRUE(CopyTestCache("bad_rankings2"));
DisableFirstCleanup();
SetMaxSize(20 * 1024 * 1024);
InitCache();
@@ -1663,7 +1643,7 @@ TEST_F(DiskCacheBackendTest, DoomAll2) {
}
TEST_F(DiskCacheBackendTest, NewEvictionDoomAll2) {
- ASSERT_TRUE(CopyTestCache(L"bad_rankings2"));
+ ASSERT_TRUE(CopyTestCache("bad_rankings2"));
DisableFirstCleanup();
SetMaxSize(20 * 1024 * 1024);
SetNewEviction();
diff --git a/net/disk_cache/block_files.cc b/net/disk_cache/block_files.cc
index 3a87731..1ce48ba 100644
--- a/net/disk_cache/block_files.cc
+++ b/net/disk_cache/block_files.cc
@@ -172,8 +172,8 @@ bool BlockFiles::Init(bool create_files) {
if (init_)
return false;
- block_files_.resize(kFirstAdditionlBlockFile);
- for (int i = 0; i < kFirstAdditionlBlockFile; i++) {
+ block_files_.resize(kFirstAdditionalBlockFile);
+ for (int i = 0; i < kFirstAdditionalBlockFile; i++) {
if (create_files)
if (!CreateBlockFile(i, static_cast<FileType>(i + 1), true))
return false;
@@ -200,11 +200,21 @@ void BlockFiles::CloseFiles() {
block_files_.clear();
}
-FilePath BlockFiles::Name(int index) {
- // The file format allows for 256 files.
- DCHECK(index < 256 || index >= 0);
- std::string tmp = StringPrintf("%s%d", kBlockName, index);
- return path_.AppendASCII(tmp);
+void BlockFiles::ReportStats() {
+ int used_blocks[kFirstAdditionalBlockFile];
+ int load[kFirstAdditionalBlockFile];
+ for (int i = 0; i < kFirstAdditionalBlockFile; i++) {
+ GetFileStats(i, &used_blocks[i], &load[i]);
+ }
+ UMA_HISTOGRAM_COUNTS("Blocks_0", used_blocks[0]);
+ UMA_HISTOGRAM_COUNTS("Blocks_1", used_blocks[1]);
+ UMA_HISTOGRAM_COUNTS("Blocks_2", used_blocks[2]);
+ UMA_HISTOGRAM_COUNTS("Blocks_3", used_blocks[3]);
+
+ UMA_HISTOGRAM_ENUMERATION("BlockLoad_0", load[0], 101);
+ UMA_HISTOGRAM_ENUMERATION("BlockLoad_1", load[1], 101);
+ UMA_HISTOGRAM_ENUMERATION("BlockLoad_2", load[2], 101);
+ UMA_HISTOGRAM_ENUMERATION("BlockLoad_3", load[3], 101);
}
bool BlockFiles::CreateBlockFile(int index, FileType file_type, bool force) {
@@ -241,7 +251,8 @@ bool BlockFiles::OpenBlockFile(int index) {
return false;
}
- if (file->GetLength() < static_cast<size_t>(kBlockHeaderSize)) {
+ size_t file_len = file->GetLength();
+ if (file_len < static_cast<size_t>(kBlockHeaderSize)) {
LOG(ERROR) << "File too small " << name.value();
return false;
}
@@ -258,6 +269,13 @@ bool BlockFiles::OpenBlockFile(int index) {
return false;
}
+ if (index == 0) {
+ // Load the links file into memory with a single read.
+ scoped_array<char> buf(new char[file_len]);
+ if (!file->Read(buf.get(), file_len, 0))
+ return false;
+ }
+
DCHECK(!block_files_[index]);
file.swap(&block_files_[index]);
return true;
@@ -356,7 +374,7 @@ MappedFile* BlockFiles::NextFile(const MappedFile* file) {
}
int BlockFiles::CreateNextBlockFile(FileType block_type) {
- for (int i = kFirstAdditionlBlockFile; i <= kMaxBlockFile; i++) {
+ for (int i = kFirstAdditionalBlockFile; i <= kMaxBlockFile; i++) {
if (CreateBlockFile(i, block_type, false))
return i;
}
@@ -485,4 +503,42 @@ bool BlockFiles::FixBlockFileHeader(MappedFile* file) {
return true;
}
+// We are interested in the total number of block used by this file type, and
+// the max number of blocks that we can store (reported as the percentage of
+// used blocks). In order to find out the number of used blocks, we have to
+// substract the empty blocks from the total blocks for each file in the chain.
+void BlockFiles::GetFileStats(int index, int* used_count, int* load) {
+ int max_blocks = 0;
+ *used_count = 0;
+ *load = 0;
+ for (;;) {
+ if (!block_files_[index] && !OpenBlockFile(index))
+ return;
+
+ BlockFileHeader* header =
+ reinterpret_cast<BlockFileHeader*>(block_files_[index]->buffer());
+
+ max_blocks += header->max_entries;
+ int used = header->max_entries;
+ for (int i = 0; i < 4; i++) {
+ used -= header->empty[i] * (i + 1);
+ DCHECK_GE(used, 0);
+ }
+ *used_count += used;
+
+ if (!header->next_file)
+ break;
+ index = header->next_file;
+ }
+ if (max_blocks)
+ *load = *used_count * 100 / max_blocks;
+}
+
+FilePath BlockFiles::Name(int index) {
+ // The file format allows for 256 files.
+ DCHECK(index < 256 || index >= 0);
+ std::string tmp = StringPrintf("%s%d", kBlockName, index);
+ return path_.AppendASCII(tmp);
+}
+
} // namespace disk_cache
diff --git a/net/disk_cache/block_files.h b/net/disk_cache/block_files.h
index 5a3e9af..3ed19de 100644
--- a/net/disk_cache/block_files.h
+++ b/net/disk_cache/block_files.h
@@ -46,6 +46,9 @@ class BlockFiles {
// cache is being purged.
void CloseFiles();
+ // Sends UMA stats.
+ void ReportStats();
+
private:
// Set force to true to overwrite the file if it exists.
bool CreateBlockFile(int index, FileType file_type, bool force);
@@ -69,6 +72,9 @@ class BlockFiles {
// Restores the header of a potentially inconsistent file.
bool FixBlockFileHeader(MappedFile* file);
+ // Retrieves stats for the given file index.
+ void GetFileStats(int index, int* used_count, int* load);
+
// Returns the filename for a given file index.
FilePath Name(int index);
@@ -79,6 +85,7 @@ class BlockFiles {
FRIEND_TEST(DiskCacheTest, BlockFiles_ZeroSizeFile);
FRIEND_TEST(DiskCacheTest, BlockFiles_InvalidFile);
+ FRIEND_TEST(DiskCacheTest, BlockFiles_Stats);
DISALLOW_COPY_AND_ASSIGN(BlockFiles);
};
diff --git a/net/disk_cache/block_files_unittest.cc b/net/disk_cache/block_files_unittest.cc
index 054641c..2c87179 100644
--- a/net/disk_cache/block_files_unittest.cc
+++ b/net/disk_cache/block_files_unittest.cc
@@ -203,4 +203,26 @@ TEST_F(DiskCacheTest, BlockFiles_InvalidFile) {
EXPECT_TRUE(NULL == files.GetFile(addr));
}
+// Tests that we generate the correct file stats.
+TEST_F(DiskCacheTest, BlockFiles_Stats) {
+ ASSERT_TRUE(CopyTestCache("remove_load1"));
+ FilePath path = GetCacheFilePath();
+
+ BlockFiles files(path);
+ ASSERT_TRUE(files.Init(false));
+ int used, load;
+
+ files.GetFileStats(0, &used, &load);
+ EXPECT_EQ(101, used);
+ EXPECT_EQ(9, load);
+
+ files.GetFileStats(1, &used, &load);
+ EXPECT_EQ(203, used);
+ EXPECT_EQ(19, load);
+
+ files.GetFileStats(2, &used, &load);
+ EXPECT_EQ(0, used);
+ EXPECT_EQ(0, load);
+}
+
} // namespace disk_cache
diff --git a/net/disk_cache/disk_cache_test_util.cc b/net/disk_cache/disk_cache_test_util.cc
index 480ba1d..e480ef2 100644
--- a/net/disk_cache/disk_cache_test_util.cc
+++ b/net/disk_cache/disk_cache_test_util.cc
@@ -77,6 +77,20 @@ bool DeleteCache(const FilePath& path) {
return true;
}
+bool CopyTestCache(const std::string& name) {
+ FilePath path;
+ PathService::Get(base::DIR_SOURCE_ROOT, &path);
+ path = path.AppendASCII("net");
+ path = path.AppendASCII("data");
+ path = path.AppendASCII("cache_tests");
+ path = path.AppendASCII(name);
+
+ FilePath dest = GetCacheFilePath();
+ if (!DeleteCache(dest))
+ return false;
+ return file_util::CopyDirectory(path, dest, false);
+}
+
bool CheckCacheIntegrity(const FilePath& path, bool new_eviction) {
scoped_ptr<disk_cache::BackendImpl> cache(new disk_cache::BackendImpl(
path, base::MessageLoopProxy::CreateForCurrentThread()));
diff --git a/net/disk_cache/disk_cache_test_util.h b/net/disk_cache/disk_cache_test_util.h
index ad7db75..7249ee0 100644
--- a/net/disk_cache/disk_cache_test_util.h
+++ b/net/disk_cache/disk_cache_test_util.h
@@ -21,6 +21,9 @@ bool CreateCacheTestFile(const FilePath& name);
// Deletes all file son the cache.
bool DeleteCache(const FilePath& path);
+// Copies a set of cache files from the data folder to the test folder.
+bool CopyTestCache(const std::string& name);
+
// Gets the path to the cache test folder.
FilePath GetCacheFilePath();