diff options
author | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-15 18:50:39 +0000 |
---|---|---|
committer | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-15 18:50:39 +0000 |
commit | aac186e80cc3fee4a7f7631433b7baab944f9239 (patch) | |
tree | 85ae7eb2b2395695f5daab470cfa5152b3a7b358 /net/disk_cache | |
parent | 6b658bf84d667bbaacd59d6337a09ac2e80645a8 (diff) | |
download | chromium_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.h | 2 | ||||
-rw-r--r-- | net/disk_cache/backend_impl.cc | 16 | ||||
-rw-r--r-- | net/disk_cache/backend_unittest.cc | 122 | ||||
-rw-r--r-- | net/disk_cache/block_files.cc | 74 | ||||
-rw-r--r-- | net/disk_cache/block_files.h | 7 | ||||
-rw-r--r-- | net/disk_cache/block_files_unittest.cc | 22 | ||||
-rw-r--r-- | net/disk_cache/disk_cache_test_util.cc | 14 | ||||
-rw-r--r-- | net/disk_cache/disk_cache_test_util.h | 3 |
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(); |