diff options
author | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 22:42:52 +0000 |
---|---|---|
committer | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 22:42:52 +0000 |
commit | 586acc5fe142f498261f52c66862fa417c3d52d2 (patch) | |
tree | c98b3417a883f2477029c8cd5888f4078681e24e /net/disk_cache/disk_cache_perftest.cc | |
parent | a814a8d55429605fe6d7045045cd25b6bf624580 (diff) | |
download | chromium_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.cc | 236 |
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; +} |