Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(524)

Side by Side Diff: net/disk_cache/blockfile/disk_cache_perftest.cc

Issue 1969413003: Support Simple Cache in disk_cache_perftest. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rename Hash test to BlockfileHash Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/BUILD.gn ('k') | net/disk_cache/disk_cache_perftest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <string>
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/hash.h"
10 #include "base/strings/string_util.h"
11 #include "base/test/perf_time_logger.h"
12 #include "base/test/test_file_util.h"
13 #include "base/threading/thread.h"
14 #include "net/base/cache_type.h"
15 #include "net/base/io_buffer.h"
16 #include "net/base/net_errors.h"
17 #include "net/base/test_completion_callback.h"
18 #include "net/disk_cache/blockfile/backend_impl.h"
19 #include "net/disk_cache/blockfile/block_files.h"
20 #include "net/disk_cache/disk_cache.h"
21 #include "net/disk_cache/disk_cache_test_base.h"
22 #include "net/disk_cache/disk_cache_test_util.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "testing/platform_test.h"
25
26 using base::Time;
27
28 namespace {
29
30 struct TestEntry {
31 std::string key;
32 int data_len;
33 };
34 typedef std::vector<TestEntry> TestEntries;
35
36 const int kMaxSize = 16 * 1024 - 1;
37
38 // Creates num_entries on the cache, and writes 200 bytes of metadata and up
39 // to kMaxSize of data to each entry.
40 bool TimeWrite(int num_entries, disk_cache::Backend* cache,
41 TestEntries* entries) {
42 const int kSize1 = 200;
43 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
44 scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kMaxSize));
45
46 CacheTestFillBuffer(buffer1->data(), kSize1, false);
47 CacheTestFillBuffer(buffer2->data(), kMaxSize, false);
48
49 int expected = 0;
50
51 MessageLoopHelper helper;
52 CallbackTest callback(&helper, true);
53
54 base::PerfTimeLogger timer("Write disk cache entries");
55
56 for (int i = 0; i < num_entries; i++) {
57 TestEntry entry;
58 entry.key = GenerateKey(true);
59 entry.data_len = rand() % kMaxSize;
60 entries->push_back(entry);
61
62 disk_cache::Entry* cache_entry;
63 net::TestCompletionCallback cb;
64 int rv = cache->CreateEntry(entry.key, &cache_entry, cb.callback());
65 if (net::OK != cb.GetResult(rv))
66 break;
67 int ret = cache_entry->WriteData(
68 0, 0, buffer1.get(), kSize1,
69 base::Bind(&CallbackTest::Run, base::Unretained(&callback)), false);
70 if (net::ERR_IO_PENDING == ret)
71 expected++;
72 else if (kSize1 != ret)
73 break;
74
75 ret = cache_entry->WriteData(
76 1, 0, buffer2.get(), entry.data_len,
77 base::Bind(&CallbackTest::Run, base::Unretained(&callback)), false);
78 if (net::ERR_IO_PENDING == ret)
79 expected++;
80 else if (entry.data_len != ret)
81 break;
82 cache_entry->Close();
83 }
84
85 helper.WaitUntilCacheIoFinished(expected);
86 timer.Done();
87
88 return (expected == helper.callbacks_called());
89 }
90
91 // Reads the data and metadata from each entry listed on |entries|.
92 bool TimeRead(int num_entries, disk_cache::Backend* cache,
93 const TestEntries& entries, bool cold) {
94 const int kSize1 = 200;
95 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
96 scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kMaxSize));
97
98 CacheTestFillBuffer(buffer1->data(), kSize1, false);
99 CacheTestFillBuffer(buffer2->data(), kMaxSize, false);
100
101 int expected = 0;
102
103 MessageLoopHelper helper;
104 CallbackTest callback(&helper, true);
105
106 const char* message = cold ? "Read disk cache entries (cold)" :
107 "Read disk cache entries (warm)";
108 base::PerfTimeLogger timer(message);
109
110 for (int i = 0; i < num_entries; i++) {
111 disk_cache::Entry* cache_entry;
112 net::TestCompletionCallback cb;
113 int rv = cache->OpenEntry(entries[i].key, &cache_entry, cb.callback());
114 if (net::OK != cb.GetResult(rv))
115 break;
116 int ret = cache_entry->ReadData(
117 0, 0, buffer1.get(), kSize1,
118 base::Bind(&CallbackTest::Run, base::Unretained(&callback)));
119 if (net::ERR_IO_PENDING == ret)
120 expected++;
121 else if (kSize1 != ret)
122 break;
123
124 ret = cache_entry->ReadData(
125 1, 0, buffer2.get(), entries[i].data_len,
126 base::Bind(&CallbackTest::Run, base::Unretained(&callback)));
127 if (net::ERR_IO_PENDING == ret)
128 expected++;
129 else if (entries[i].data_len != ret)
130 break;
131 cache_entry->Close();
132 }
133
134 helper.WaitUntilCacheIoFinished(expected);
135 timer.Done();
136
137 return (expected == helper.callbacks_called());
138 }
139
140 int BlockSize() {
141 // We can use form 1 to 4 blocks.
142 return (rand() & 0x3) + 1;
143 }
144
145 } // namespace
146
147 TEST_F(DiskCacheTest, Hash) {
148 int seed = static_cast<int>(Time::Now().ToInternalValue());
149 srand(seed);
150
151 base::PerfTimeLogger timer("Hash disk cache keys");
152 for (int i = 0; i < 300000; i++) {
153 std::string key = GenerateKey(true);
154 base::Hash(key);
155 }
156 timer.Done();
157 }
158
159 TEST_F(DiskCacheTest, CacheBackendPerformance) {
160 base::Thread cache_thread("CacheThread");
161 ASSERT_TRUE(cache_thread.StartWithOptions(
162 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)));
163
164 ASSERT_TRUE(CleanupCacheDir());
165 net::TestCompletionCallback cb;
166 std::unique_ptr<disk_cache::Backend> cache;
167 int rv = disk_cache::CreateCacheBackend(net::DISK_CACHE,
168 net::CACHE_BACKEND_BLOCKFILE,
169 cache_path_,
170 0,
171 false,
172 cache_thread.task_runner(),
173 NULL,
174 &cache,
175 cb.callback());
176
177 ASSERT_EQ(net::OK, cb.GetResult(rv));
178
179 int seed = static_cast<int>(Time::Now().ToInternalValue());
180 srand(seed);
181
182 TestEntries entries;
183 int num_entries = 1000;
184
185 EXPECT_TRUE(TimeWrite(num_entries, cache.get(), &entries));
186
187 base::MessageLoop::current()->RunUntilIdle();
188 cache.reset();
189
190 ASSERT_TRUE(base::EvictFileFromSystemCache(
191 cache_path_.AppendASCII("index")));
192 ASSERT_TRUE(base::EvictFileFromSystemCache(
193 cache_path_.AppendASCII("data_0")));
194 ASSERT_TRUE(base::EvictFileFromSystemCache(
195 cache_path_.AppendASCII("data_1")));
196 ASSERT_TRUE(base::EvictFileFromSystemCache(
197 cache_path_.AppendASCII("data_2")));
198 ASSERT_TRUE(base::EvictFileFromSystemCache(
199 cache_path_.AppendASCII("data_3")));
200
201 rv = disk_cache::CreateCacheBackend(net::DISK_CACHE,
202 net::CACHE_BACKEND_BLOCKFILE,
203 cache_path_,
204 0,
205 false,
206 cache_thread.task_runner(),
207 NULL,
208 &cache,
209 cb.callback());
210 ASSERT_EQ(net::OK, cb.GetResult(rv));
211
212 EXPECT_TRUE(TimeRead(num_entries, cache.get(), entries, true));
213
214 EXPECT_TRUE(TimeRead(num_entries, cache.get(), entries, false));
215
216 base::MessageLoop::current()->RunUntilIdle();
217 }
218
219 // Creating and deleting "entries" on a block-file is something quite frequent
220 // (after all, almost everything is stored on block files). The operation is
221 // almost free when the file is empty, but can be expensive if the file gets
222 // fragmented, or if we have multiple files. This test measures that scenario,
223 // by using multiple, highly fragmented files.
224 TEST_F(DiskCacheTest, BlockFilesPerformance) {
225 ASSERT_TRUE(CleanupCacheDir());
226
227 disk_cache::BlockFiles files(cache_path_);
228 ASSERT_TRUE(files.Init(true));
229
230 int seed = static_cast<int>(Time::Now().ToInternalValue());
231 srand(seed);
232
233 const int kNumEntries = 60000;
234 disk_cache::Addr* address = new disk_cache::Addr[kNumEntries];
235
236 base::PerfTimeLogger timer1("Fill three block-files");
237
238 // Fill up the 32-byte block file (use three files).
239 for (int i = 0; i < kNumEntries; i++) {
240 EXPECT_TRUE(files.CreateBlock(disk_cache::RANKINGS, BlockSize(),
241 &address[i]));
242 }
243
244 timer1.Done();
245 base::PerfTimeLogger timer2("Create and delete blocks");
246
247 for (int i = 0; i < 200000; i++) {
248 int entry = rand() * (kNumEntries / RAND_MAX + 1);
249 if (entry >= kNumEntries)
250 entry = 0;
251
252 files.DeleteBlock(address[entry], false);
253 EXPECT_TRUE(files.CreateBlock(disk_cache::RANKINGS, BlockSize(),
254 &address[entry]));
255 }
256
257 timer2.Done();
258 base::MessageLoop::current()->RunUntilIdle();
259 delete[] address;
260 }
OLDNEW
« no previous file with comments | « net/BUILD.gn ('k') | net/disk_cache/disk_cache_perftest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698