1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string>
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/basictypes.h"
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/file_path.h"
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/file_util.h"
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/perftimer.h"
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string_util.h"
123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread.h"
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/test/test_file_util.h"
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/timer.h"
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/io_buffer.h"
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/net_errors.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/test_completion_callback.h"
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/block_files.h"
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/disk_cache.h"
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/disk_cache_test_util.h"
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/hash.h"
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing/gtest/include/gtest/gtest.h"
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing/platform_test.h"
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottusing base::Time;
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottextern volatile int g_cache_tests_received;
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottextern volatile bool g_cache_tests_error;
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttypedef PlatformTest DiskCacheTest;
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace {
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct TestEntry {
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::string key;
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int data_len;
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttypedef std::vector<TestEntry> TestEntries;
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst int kMaxSize = 16 * 1024 - 1;
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Creates num_entries on the cache, and writes 200 bytes of metadata and up
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// to kMaxSize of data to each entry.
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint TimeWrite(int num_entries, disk_cache::Backend* cache,
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott              TestEntries* entries) {
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const int kSize1 = 200;
47513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
48513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kMaxSize));
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CacheTestFillBuffer(buffer1->data(), kSize1, false);
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CacheTestFillBuffer(buffer2->data(), kMaxSize, false);
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CallbackTest callback(true);
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  g_cache_tests_error = false;
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  g_cache_tests_received = 0;
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int expected = 0;
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoopHelper helper;
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  PerfTimeLogger timer("Write disk cache entries");
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < num_entries; i++) {
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    TestEntry entry;
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    entry.key = GenerateKey(true);
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    entry.data_len = rand() % kMaxSize;
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    entries->push_back(entry);
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    disk_cache::Entry* cache_entry;
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestCompletionCallback cb;
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int rv = cache->CreateEntry(entry.key, &cache_entry, &cb);
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (net::OK != cb.GetResult(rv))
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      break;
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int ret = cache_entry->WriteData(0, 0, buffer1, kSize1, &callback, false);
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (net::ERR_IO_PENDING == ret)
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      expected++;
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    else if (kSize1 != ret)
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      break;
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ret = cache_entry->WriteData(1, 0, buffer2, entry.data_len, &callback,
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                 false);
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (net::ERR_IO_PENDING == ret)
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      expected++;
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    else if (entry.data_len != ret)
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      break;
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    cache_entry->Close();
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  helper.WaitUntilCacheIoFinished(expected);
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  timer.Done();
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return expected;
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Reads the data and metadata from each entry listed on |entries|.
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint TimeRead(int num_entries, disk_cache::Backend* cache,
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott             const TestEntries& entries, bool cold) {
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const int kSize1 = 200;
98513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
99513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kMaxSize));
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CacheTestFillBuffer(buffer1->data(), kSize1, false);
102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CacheTestFillBuffer(buffer2->data(), kMaxSize, false);
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CallbackTest callback(true);
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  g_cache_tests_error = false;
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  g_cache_tests_received = 0;
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int expected = 0;
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoopHelper helper;
110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* message = cold ? "Read disk cache entries (cold)" :
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        "Read disk cache entries (warm)";
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  PerfTimeLogger timer(message);
114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < num_entries; i++) {
116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    disk_cache::Entry* cache_entry;
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestCompletionCallback cb;
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int rv = cache->OpenEntry(entries[i].key, &cache_entry, &cb);
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (net::OK != cb.GetResult(rv))
120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      break;
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int ret = cache_entry->ReadData(0, 0, buffer1, kSize1, &callback);
122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (net::ERR_IO_PENDING == ret)
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      expected++;
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    else if (kSize1 != ret)
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      break;
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ret = cache_entry->ReadData(1, 0, buffer2, entries[i].data_len, &callback);
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (net::ERR_IO_PENDING == ret)
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      expected++;
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    else if (entries[i].data_len != ret)
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      break;
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    cache_entry->Close();
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  helper.WaitUntilCacheIoFinished(expected);
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  timer.Done();
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return expected;
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint BlockSize() {
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We can use form 1 to 4 blocks.
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return (rand() & 0x3) + 1;
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(DiskCacheTest, Hash) {
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int seed = static_cast<int>(Time::Now().ToInternalValue());
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  srand(seed);
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  PerfTimeLogger timer("Hash disk cache keys");
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < 300000; i++) {
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    std::string key = GenerateKey(true);
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    disk_cache::Hash(key);
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  timer.Done();
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(DiskCacheTest, CacheBackendPerformance) {
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoopForIO message_loop;
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::Thread cache_thread("CacheThread");
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(cache_thread.StartWithOptions(
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  base::Thread::Options(MessageLoop::TYPE_IO, 0)));
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ScopedTestCache test_cache;
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestCompletionCallback cb;
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  disk_cache::Backend* cache;
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = disk_cache::CreateCacheBackend(
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch               net::DISK_CACHE, test_cache.path(), 0, false,
1723f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen               cache_thread.message_loop_proxy(), NULL, &cache, &cb);
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(net::OK, cb.GetResult(rv));
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int seed = static_cast<int>(Time::Now().ToInternalValue());
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  srand(seed);
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TestEntries entries;
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int num_entries = 1000;
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int ret = TimeWrite(num_entries, cache, &entries);
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ret, g_cache_tests_received);
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->RunAllPending();
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  delete cache;
187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_TRUE(file_util::EvictFileFromSystemCache(
189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott              test_cache.path().AppendASCII("index")));
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_TRUE(file_util::EvictFileFromSystemCache(
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott              test_cache.path().AppendASCII("data_0")));
192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_TRUE(file_util::EvictFileFromSystemCache(
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott              test_cache.path().AppendASCII("data_1")));
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_TRUE(file_util::EvictFileFromSystemCache(
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott              test_cache.path().AppendASCII("data_2")));
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_TRUE(file_util::EvictFileFromSystemCache(
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott              test_cache.path().AppendASCII("data_3")));
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  rv = disk_cache::CreateCacheBackend(net::DISK_CACHE, test_cache.path(), 0,
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                      false, cache_thread.message_loop_proxy(),
2013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                      NULL, &cache, &cb);
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(net::OK, cb.GetResult(rv));
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ret = TimeRead(num_entries, cache, entries, true);
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ret, g_cache_tests_received);
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ret = TimeRead(num_entries, cache, entries, false);
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EXPECT_EQ(ret, g_cache_tests_received);
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->RunAllPending();
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  delete cache;
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Creating and deleting "entries" on a block-file is something quite frequent
215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// (after all, almost everything is stored on block files). The operation is
216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// almost free when the file is empty, but can be expensive if the file gets
217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// fragmented, or if we have multiple files. This test measures that scenario,
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// by using multiple, highly fragmented files.
219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(DiskCacheTest, BlockFilesPerformance) {
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoopForIO message_loop;
221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ScopedTestCache test_cache;
223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  disk_cache::BlockFiles files(test_cache.path());
225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  ASSERT_TRUE(files.Init(true));
226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int seed = static_cast<int>(Time::Now().ToInternalValue());
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  srand(seed);
229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const int kNumEntries = 60000;
231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  disk_cache::Addr* address = new disk_cache::Addr[kNumEntries];
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  PerfTimeLogger timer1("Fill three block-files");
234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Fill up the 32-byte block file (use three files).
236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < kNumEntries; i++) {
237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_TRUE(files.CreateBlock(disk_cache::RANKINGS, BlockSize(),
238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                  &address[i]));
239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  timer1.Done();
242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  PerfTimeLogger timer2("Create and delete blocks");
243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (int i = 0; i < 200000; i++) {
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int entry = rand() * (kNumEntries / RAND_MAX + 1);
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (entry >= kNumEntries)
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      entry = 0;
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    files.DeleteBlock(address[entry], false);
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    EXPECT_TRUE(files.CreateBlock(disk_cache::RANKINGS, BlockSize(),
251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                  &address[entry]));
252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  timer2.Done();
255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MessageLoop::current()->RunAllPending();
256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  delete[] address;
257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
258