summaryrefslogtreecommitdiffstats
path: root/net/disk_cache/disk_cache_perftest.cc
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 22:42:52 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 22:42:52 +0000
commit586acc5fe142f498261f52c66862fa417c3d52d2 (patch)
treec98b3417a883f2477029c8cd5888f4078681e24e /net/disk_cache/disk_cache_perftest.cc
parenta814a8d55429605fe6d7045045cd25b6bf624580 (diff)
downloadchromium_src-586acc5fe142f498261f52c66862fa417c3d52d2.zip
chromium_src-586acc5fe142f498261f52c66862fa417c3d52d2.tar.gz
chromium_src-586acc5fe142f498261f52c66862fa417c3d52d2.tar.bz2
Add net to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/disk_cache/disk_cache_perftest.cc')
-rw-r--r--net/disk_cache/disk_cache_perftest.cc236
1 files changed, 236 insertions, 0 deletions
diff --git a/net/disk_cache/disk_cache_perftest.cc b/net/disk_cache/disk_cache_perftest.cc
new file mode 100644
index 0000000..6e23471
--- /dev/null
+++ b/net/disk_cache/disk_cache_perftest.cc
@@ -0,0 +1,236 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "base/perftimer.h"
+#include "base/scoped_handle.h"
+#include "base/timer.h"
+#include "net/base/net_errors.h"
+#include "net/disk_cache/disk_cache.h"
+#include "net/disk_cache/disk_cache_test_util.h"
+#include "net/disk_cache/hash.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+extern int g_cache_tests_max_id;
+extern volatile int g_cache_tests_received;
+extern volatile bool g_cache_tests_error;
+
+namespace {
+
+bool EvictFileFromSystemCache(const wchar_t* name) {
+ // Overwrite it with no buffering.
+ ScopedHandle file(CreateFile(name, GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+ OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL));
+ if (!file.IsValid())
+ return false;
+
+ // Execute in chunks. It could be optimized. We want to do few of these since
+ // these opterations will be slow without the cache.
+ char buffer[128 * 1024];
+ int total_bytes = 0;
+ DWORD bytes_read;
+ for (;;) {
+ if (!ReadFile(file, buffer, sizeof(buffer), &bytes_read, NULL))
+ return false;
+ if (bytes_read == 0)
+ break;
+
+ bool final = false;
+ if (bytes_read < sizeof(buffer))
+ final = true;
+
+ DWORD to_write = final ? sizeof(buffer) : bytes_read;
+
+ DWORD actual;
+ SetFilePointer(file, total_bytes, 0, FILE_BEGIN);
+ if (!WriteFile(file, buffer, to_write, &actual, NULL))
+ return false;
+ total_bytes += bytes_read;
+
+ if (final) {
+ SetFilePointer(file, total_bytes, 0, FILE_BEGIN);
+ SetEndOfFile(file);
+ break;
+ }
+ }
+ return true;
+}
+
+struct TestEntry {
+ std::string key;
+ int data_len;
+};
+typedef std::vector<TestEntry> TestEntries;
+
+const int kMaxSize = 16 * 1024 - 1;
+
+// Creates num_entries on the cache, and writes 200 bytes of metadata and up
+// to kMaxSize of data to each entry.
+int TimeWrite(int num_entries, disk_cache::Backend* cache,
+ TestEntries* entries) {
+ char buffer1[200];
+ char buffer2[kMaxSize];
+
+ CacheTestFillBuffer(buffer1, sizeof(buffer1), false);
+ CacheTestFillBuffer(buffer2, sizeof(buffer2), false);
+
+ CallbackTest callback(1);
+ g_cache_tests_error = false;
+ g_cache_tests_max_id = 1;
+ g_cache_tests_received = 0;
+ int expected = 0;
+
+ MessageLoopHelper helper;
+
+ PerfTimeLogger timer("Write disk cache entries");
+
+ for (int i = 0; i < num_entries; i++) {
+ TestEntry entry;
+ entry.key = GenerateKey(true);
+ entry.data_len = rand() % sizeof(buffer2);
+ entries->push_back(entry);
+
+ disk_cache::Entry* cache_entry;
+ if (!cache->CreateEntry(entry.key, &cache_entry))
+ break;
+ int ret = cache_entry->WriteData(0, 0, buffer1, sizeof(buffer1), &callback,
+ false);
+ if (net::ERR_IO_PENDING == ret)
+ expected++;
+ else if (sizeof(buffer1) != ret)
+ break;
+
+ ret = cache_entry->WriteData(1, 0, buffer2, entry.data_len, &callback,
+ false);
+ if (net::ERR_IO_PENDING == ret)
+ expected++;
+ else if (entry.data_len != ret)
+ break;
+ cache_entry->Close();
+ }
+
+ helper.WaitUntilCacheIoFinished(expected);
+ timer.Done();
+
+ return expected;
+}
+
+// Reads the data and metadata from each entry listed on |entries|.
+int TimeRead(int num_entries, disk_cache::Backend* cache,
+ const TestEntries& entries, bool cold) {
+ char buffer1[200];
+ char buffer2[kMaxSize];
+
+ CacheTestFillBuffer(buffer1, sizeof(buffer1), false);
+ CacheTestFillBuffer(buffer2, sizeof(buffer2), false);
+
+ CallbackTest callback(1);
+ g_cache_tests_error = false;
+ g_cache_tests_max_id = 1;
+ g_cache_tests_received = 0;
+ int expected = 0;
+
+ MessageLoopHelper helper;
+
+ const char* message = cold ? "Read disk cache entries (cold)" :
+ "Read disk cache entries (warm)";
+ PerfTimeLogger timer(message);
+
+ for (int i = 0; i < num_entries; i++) {
+ disk_cache::Entry* cache_entry;
+ if (!cache->OpenEntry(entries[i].key, &cache_entry))
+ break;
+ int ret = cache_entry->ReadData(0, 0, buffer1, sizeof(buffer1), &callback);
+ if (net::ERR_IO_PENDING == ret)
+ expected++;
+ else if (sizeof(buffer1) != ret)
+ break;
+
+ ret = cache_entry->ReadData(1, 0, buffer2, entries[i].data_len, &callback);
+ if (net::ERR_IO_PENDING == ret)
+ expected++;
+ else if (entries[i].data_len != ret)
+ break;
+ cache_entry->Close();
+ }
+
+ helper.WaitUntilCacheIoFinished(expected);
+ timer.Done();
+
+ return expected;
+}
+
+} // namespace
+
+TEST(DiskCacheTest, Hash) {
+ int seed = static_cast<int>(Time::Now().ToInternalValue());
+ srand(seed);
+
+ PerfTimeLogger timer("Hash disk cache keys");
+ for (int i = 0; i < 300000; i++) {
+ std::string key = GenerateKey(true);
+ uint32 hash = disk_cache::Hash(key);
+ }
+ timer.Done();
+}
+
+TEST(DiskCacheTest, CacheBackendPerformance) {
+ std::wstring path = GetCachePath();
+ ASSERT_TRUE(DeleteCache(path.c_str()));
+ disk_cache::Backend* cache = disk_cache::CreateCacheBackend(path, false, 0);
+ ASSERT_TRUE(NULL != cache);
+
+ int seed = static_cast<int>(Time::Now().ToInternalValue());
+ srand(seed);
+
+ TestEntries entries;
+ int num_entries = 1000;
+
+ int ret = TimeWrite(num_entries, cache, &entries);
+ EXPECT_EQ(ret, g_cache_tests_received);
+
+ delete cache;
+
+ ASSERT_TRUE(EvictFileFromSystemCache((path + L"\\index").c_str()));
+ ASSERT_TRUE(EvictFileFromSystemCache((path + L"\\data_0").c_str()));
+ ASSERT_TRUE(EvictFileFromSystemCache((path + L"\\data_1").c_str()));
+ ASSERT_TRUE(EvictFileFromSystemCache((path + L"\\data_2").c_str()));
+ ASSERT_TRUE(EvictFileFromSystemCache((path + L"\\data_3").c_str()));
+
+ cache = disk_cache::CreateCacheBackend(path, false, 0);
+ ASSERT_TRUE(NULL != cache);
+
+ ret = TimeRead(num_entries, cache, entries, true);
+ EXPECT_EQ(ret, g_cache_tests_received);
+
+ ret = TimeRead(num_entries, cache, entries, false);
+ EXPECT_EQ(ret, g_cache_tests_received);
+
+ delete cache;
+}