summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrvargas <rvargas@chromium.org>2015-03-04 19:35:04 -0800
committerCommit bot <commit-bot@chromium.org>2015-03-05 03:35:52 +0000
commit4f2eab7cd613d87c79a192bfc5183f79483d95bf (patch)
treec5168a97a3becc6bc3f1d6d88ddaffa7832486f0
parentea82a5686c5810a40d610ae6439e29d994fe9f35 (diff)
downloadchromium_src-4f2eab7cd613d87c79a192bfc5183f79483d95bf.zip
chromium_src-4f2eab7cd613d87c79a192bfc5183f79483d95bf.tar.gz
chromium_src-4f2eab7cd613d87c79a192bfc5183f79483d95bf.tar.bz2
Disk cache: Re-initialize stats counters if they are zero on-disk.
Stats are saved to disk every five minutes. If a client is initializing the cache, and it crashes before saving the stats for the first time, the next run will see an empty stats storage, and will discard the cache because it may indicate that the storage address was invalid. Now, we check the contents to see if the storage was empty and re-initialize things as needed. BUG=none TEST=net_unittests Review URL: https://codereview.chromium.org/980003002 Cr-Commit-Position: refs/heads/master@{#319204}
-rw-r--r--net/disk_cache/blockfile/stats.cc14
-rw-r--r--net/disk_cache/blockfile/stats.h3
-rw-r--r--net/disk_cache/blockfile/stats_unittest.cc83
-rw-r--r--net/net.gypi1
4 files changed, 98 insertions, 3 deletions
diff --git a/net/disk_cache/blockfile/stats.cc b/net/disk_cache/blockfile/stats.cc
index e6b10b8..bb319f5 100644
--- a/net/disk_cache/blockfile/stats.cc
+++ b/net/disk_cache/blockfile/stats.cc
@@ -107,8 +107,18 @@ bool Stats::Init(void* data, int num_bytes, Addr address) {
local_stats.size = sizeof(local_stats);
} else if (num_bytes >= static_cast<int>(sizeof(*stats))) {
stats = reinterpret_cast<OnDiskStats*>(data);
- if (!VerifyStats(stats))
- return false;
+ if (!VerifyStats(stats)) {
+ memset(&local_stats, 0, sizeof(local_stats));
+ if (memcmp(stats, &local_stats, sizeof(local_stats))) {
+ return false;
+ } else {
+ // The storage is empty which means that SerializeStats() was never
+ // called on the last run. Just re-initialize everything.
+ local_stats.signature = kDiskSignature;
+ local_stats.size = sizeof(local_stats);
+ stats = &local_stats;
+ }
+ }
} else {
return false;
}
diff --git a/net/disk_cache/blockfile/stats.h b/net/disk_cache/blockfile/stats.h
index 8e1293d..769c171 100644
--- a/net/disk_cache/blockfile/stats.h
+++ b/net/disk_cache/blockfile/stats.h
@@ -9,6 +9,7 @@
#include <vector>
#include "base/basictypes.h"
+#include "net/base/net_export.h"
#include "net/disk_cache/blockfile/addr.h"
namespace base {
@@ -20,7 +21,7 @@ namespace disk_cache {
typedef std::vector<std::pair<std::string, std::string> > StatsItems;
// This class stores cache-specific usage information, for tunning purposes.
-class Stats {
+class NET_EXPORT_PRIVATE Stats {
public:
static const int kDataSizesLength = 28;
enum Counters {
diff --git a/net/disk_cache/blockfile/stats_unittest.cc b/net/disk_cache/blockfile/stats_unittest.cc
new file mode 100644
index 0000000..fe47bdd
--- /dev/null
+++ b/net/disk_cache/blockfile/stats_unittest.cc
@@ -0,0 +1,83 @@
+// Copyright 2015 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/blockfile/stats.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(DiskCacheStatsTest, Init) {
+ disk_cache::Stats stats;
+ EXPECT_TRUE(stats.Init(nullptr, 0, disk_cache::Addr()));
+ EXPECT_EQ(0, stats.GetCounter(disk_cache::Stats::TRIM_ENTRY));
+}
+
+TEST(DiskCacheStatsTest, InitWithEmptyBuffer) {
+ disk_cache::Stats stats;
+ int required_len = stats.StorageSize();
+ scoped_ptr<char[]> storage(new char[required_len]);
+ memset(storage.get(), 0, required_len);
+
+ ASSERT_TRUE(stats.Init(storage.get(), required_len, disk_cache::Addr()));
+ EXPECT_EQ(0, stats.GetCounter(disk_cache::Stats::TRIM_ENTRY));
+}
+
+TEST(DiskCacheStatsTest, FailsInit) {
+ disk_cache::Stats stats;
+ int required_len = stats.StorageSize();
+ scoped_ptr<char[]> storage(new char[required_len]);
+ memset(storage.get(), 0, required_len);
+
+ // Try a small buffer.
+ EXPECT_LT(200, required_len);
+ disk_cache::Addr addr;
+ EXPECT_FALSE(stats.Init(storage.get(), 200, addr));
+
+ // Try a buffer with garbage.
+ memset(storage.get(), 'a', required_len);
+ EXPECT_FALSE(stats.Init(storage.get(), required_len, addr));
+}
+
+TEST(DiskCacheStatsTest, SaveRestore) {
+ scoped_ptr<disk_cache::Stats> stats(new disk_cache::Stats);
+
+ disk_cache::Addr addr(5);
+ ASSERT_TRUE(stats->Init(nullptr, 0, addr));
+ stats->SetCounter(disk_cache::Stats::CREATE_ERROR, 11);
+ stats->SetCounter(disk_cache::Stats::DOOM_ENTRY, 13);
+ stats->OnEvent(disk_cache::Stats::MIN_COUNTER);
+ stats->OnEvent(disk_cache::Stats::TRIM_ENTRY);
+ stats->OnEvent(disk_cache::Stats::DOOM_RECENT);
+
+ int required_len = stats->StorageSize();
+ scoped_ptr<char[]> storage(new char[required_len]);
+ disk_cache::Addr out_addr;
+ int real_len = stats->SerializeStats(storage.get(), required_len, &out_addr);
+ EXPECT_GE(required_len, real_len);
+ EXPECT_EQ(out_addr, addr);
+
+ stats.reset(new disk_cache::Stats);
+ ASSERT_TRUE(stats->Init(storage.get(), real_len, addr));
+ EXPECT_EQ(1, stats->GetCounter(disk_cache::Stats::MIN_COUNTER));
+ EXPECT_EQ(1, stats->GetCounter(disk_cache::Stats::TRIM_ENTRY));
+ EXPECT_EQ(1, stats->GetCounter(disk_cache::Stats::DOOM_RECENT));
+ EXPECT_EQ(0, stats->GetCounter(disk_cache::Stats::OPEN_HIT));
+ EXPECT_EQ(0, stats->GetCounter(disk_cache::Stats::READ_DATA));
+ EXPECT_EQ(0, stats->GetCounter(disk_cache::Stats::LAST_REPORT_TIMER));
+ EXPECT_EQ(11, stats->GetCounter(disk_cache::Stats::CREATE_ERROR));
+ EXPECT_EQ(13, stats->GetCounter(disk_cache::Stats::DOOM_ENTRY));
+
+ // Now pass the whole buffer. It shoulod not matter that there is unused
+ // space at the end.
+ stats.reset(new disk_cache::Stats);
+ ASSERT_TRUE(stats->Init(storage.get(), required_len, addr));
+ EXPECT_EQ(1, stats->GetCounter(disk_cache::Stats::MIN_COUNTER));
+ EXPECT_EQ(1, stats->GetCounter(disk_cache::Stats::TRIM_ENTRY));
+ EXPECT_EQ(1, stats->GetCounter(disk_cache::Stats::DOOM_RECENT));
+ EXPECT_EQ(0, stats->GetCounter(disk_cache::Stats::OPEN_HIT));
+ EXPECT_EQ(0, stats->GetCounter(disk_cache::Stats::READ_DATA));
+ EXPECT_EQ(0, stats->GetCounter(disk_cache::Stats::LAST_REPORT_TIMER));
+ EXPECT_EQ(11, stats->GetCounter(disk_cache::Stats::CREATE_ERROR));
+ EXPECT_EQ(13, stats->GetCounter(disk_cache::Stats::DOOM_ENTRY));
+}
diff --git a/net/net.gypi b/net/net.gypi
index ef68f7b..796d43d 100644
--- a/net/net.gypi
+++ b/net/net.gypi
@@ -1335,6 +1335,7 @@
'disk_cache/blockfile/block_files_unittest.cc',
'disk_cache/blockfile/index_table_v3_unittest.cc',
'disk_cache/blockfile/mapped_file_unittest.cc',
+ 'disk_cache/blockfile/stats_unittest.cc',
'disk_cache/blockfile/storage_block_unittest.cc',
'disk_cache/cache_util_unittest.cc',
'disk_cache/entry_unittest.cc',