OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <fcntl.h> | |
6 | |
7 #include <string> | 5 #include <string> |
8 | 6 |
9 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/file_path.h" |
10 #include "base/file_util.h" | 9 #include "base/file_util.h" |
11 #include "base/perftimer.h" | 10 #include "base/perftimer.h" |
12 #if defined(OS_WIN) | |
13 #include "base/scoped_handle.h" | |
14 #endif | |
15 #include "base/string_util.h" | 11 #include "base/string_util.h" |
| 12 #include "base/test_file_util.h" |
16 #include "base/timer.h" | 13 #include "base/timer.h" |
17 #include "net/base/net_errors.h" | 14 #include "net/base/net_errors.h" |
18 #include "net/disk_cache/block_files.h" | 15 #include "net/disk_cache/block_files.h" |
19 #include "net/disk_cache/disk_cache.h" | 16 #include "net/disk_cache/disk_cache.h" |
20 #include "net/disk_cache/disk_cache_test_util.h" | 17 #include "net/disk_cache/disk_cache_test_util.h" |
21 #include "net/disk_cache/hash.h" | 18 #include "net/disk_cache/hash.h" |
22 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
23 #include "testing/platform_test.h" | 20 #include "testing/platform_test.h" |
24 | 21 |
25 using base::Time; | 22 using base::Time; |
26 | 23 |
27 extern int g_cache_tests_max_id; | 24 extern int g_cache_tests_max_id; |
28 extern volatile int g_cache_tests_received; | 25 extern volatile int g_cache_tests_received; |
29 extern volatile bool g_cache_tests_error; | 26 extern volatile bool g_cache_tests_error; |
30 | 27 |
31 typedef PlatformTest DiskCacheTest; | 28 typedef PlatformTest DiskCacheTest; |
32 | 29 |
33 namespace { | 30 namespace { |
34 | 31 |
35 bool EvictFileFromSystemCache(const wchar_t* name) { | |
36 #if defined(OS_WIN) | |
37 // Overwrite it with no buffering. | |
38 ScopedHandle file(CreateFile(name, GENERIC_READ | GENERIC_WRITE, | |
39 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, | |
40 OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL)); | |
41 if (!file.IsValid()) | |
42 return false; | |
43 | |
44 // Execute in chunks. It could be optimized. We want to do few of these since | |
45 // these opterations will be slow without the cache. | |
46 char buffer[128 * 1024]; | |
47 int total_bytes = 0; | |
48 DWORD bytes_read; | |
49 for (;;) { | |
50 if (!ReadFile(file, buffer, sizeof(buffer), &bytes_read, NULL)) | |
51 return false; | |
52 if (bytes_read == 0) | |
53 break; | |
54 | |
55 bool final = false; | |
56 if (bytes_read < sizeof(buffer)) | |
57 final = true; | |
58 | |
59 DWORD to_write = final ? sizeof(buffer) : bytes_read; | |
60 | |
61 DWORD actual; | |
62 SetFilePointer(file, total_bytes, 0, FILE_BEGIN); | |
63 if (!WriteFile(file, buffer, to_write, &actual, NULL)) | |
64 return false; | |
65 total_bytes += bytes_read; | |
66 | |
67 if (final) { | |
68 SetFilePointer(file, total_bytes, 0, FILE_BEGIN); | |
69 SetEndOfFile(file); | |
70 break; | |
71 } | |
72 } | |
73 return true; | |
74 #elif defined(OS_LINUX) | |
75 int fd = open(WideToUTF8(std::wstring(name)).c_str(), O_RDONLY); | |
76 if (fd < 0) | |
77 return false; | |
78 if (fdatasync(fd) != 0) | |
79 return false; | |
80 if (posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED) != 0) | |
81 return false; | |
82 close(fd); | |
83 return true; | |
84 #else | |
85 // TODO(port): Mac has its own way to do this. | |
86 NOTIMPLEMENTED(); | |
87 return false; | |
88 #endif | |
89 } | |
90 | |
91 struct TestEntry { | 32 struct TestEntry { |
92 std::string key; | 33 std::string key; |
93 int data_len; | 34 int data_len; |
94 }; | 35 }; |
95 typedef std::vector<TestEntry> TestEntries; | 36 typedef std::vector<TestEntry> TestEntries; |
96 | 37 |
97 const int kMaxSize = 16 * 1024 - 1; | 38 const int kMaxSize = 16 * 1024 - 1; |
98 | 39 |
99 // Creates num_entries on the cache, and writes 200 bytes of metadata and up | 40 // Creates num_entries on the cache, and writes 200 bytes of metadata and up |
100 // to kMaxSize of data to each entry. | 41 // to kMaxSize of data to each entry. |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 for (int i = 0; i < 300000; i++) { | 148 for (int i = 0; i < 300000; i++) { |
208 std::string key = GenerateKey(true); | 149 std::string key = GenerateKey(true); |
209 disk_cache::Hash(key); | 150 disk_cache::Hash(key); |
210 } | 151 } |
211 timer.Done(); | 152 timer.Done(); |
212 } | 153 } |
213 | 154 |
214 TEST_F(DiskCacheTest, CacheBackendPerformance) { | 155 TEST_F(DiskCacheTest, CacheBackendPerformance) { |
215 MessageLoopForIO message_loop; | 156 MessageLoopForIO message_loop; |
216 | 157 |
217 std::wstring path = GetCachePath(); | 158 std::wstring path_wstring = GetCachePath(); |
218 ASSERT_TRUE(DeleteCache(path.c_str())); | 159 ASSERT_TRUE(DeleteCache(path_wstring.c_str())); |
219 disk_cache::Backend* cache = disk_cache::CreateCacheBackend(path, false, 0); | 160 disk_cache::Backend* cache = disk_cache::CreateCacheBackend(path_wstring, |
| 161 false, 0); |
220 ASSERT_TRUE(NULL != cache); | 162 ASSERT_TRUE(NULL != cache); |
221 | 163 |
222 int seed = static_cast<int>(Time::Now().ToInternalValue()); | 164 int seed = static_cast<int>(Time::Now().ToInternalValue()); |
223 srand(seed); | 165 srand(seed); |
224 | 166 |
225 TestEntries entries; | 167 TestEntries entries; |
226 int num_entries = 1000; | 168 int num_entries = 1000; |
227 | 169 |
228 int ret = TimeWrite(num_entries, cache, &entries); | 170 int ret = TimeWrite(num_entries, cache, &entries); |
229 EXPECT_EQ(ret, g_cache_tests_received); | 171 EXPECT_EQ(ret, g_cache_tests_received); |
230 | 172 |
231 MessageLoop::current()->RunAllPending(); | 173 MessageLoop::current()->RunAllPending(); |
232 delete cache; | 174 delete cache; |
233 | 175 |
234 std::wstring filename(path); | 176 FilePath path = FilePath::FromWStringHack(path_wstring); |
235 file_util::AppendToPath(&filename, L"index"); | |
236 ASSERT_TRUE(EvictFileFromSystemCache(filename.c_str())); | |
237 | 177 |
238 filename = path; | 178 ASSERT_TRUE(file_util::EvictFileFromSystemCache( |
239 file_util::AppendToPath(&filename, L"data_0"); | 179 path.Append(FILE_PATH_LITERAL("index")))); |
240 ASSERT_TRUE(EvictFileFromSystemCache(filename.c_str())); | 180 ASSERT_TRUE(file_util::EvictFileFromSystemCache( |
| 181 path.Append(FILE_PATH_LITERAL("data_0")))); |
| 182 ASSERT_TRUE(file_util::EvictFileFromSystemCache( |
| 183 path.Append(FILE_PATH_LITERAL("data_1")))); |
| 184 ASSERT_TRUE(file_util::EvictFileFromSystemCache( |
| 185 path.Append(FILE_PATH_LITERAL("data_2")))); |
| 186 ASSERT_TRUE(file_util::EvictFileFromSystemCache( |
| 187 path.Append(FILE_PATH_LITERAL("data_3")))); |
241 | 188 |
242 filename = path; | 189 cache = disk_cache::CreateCacheBackend(path_wstring, false, 0); |
243 file_util::AppendToPath(&filename, L"data_1"); | |
244 ASSERT_TRUE(EvictFileFromSystemCache(filename.c_str())); | |
245 | |
246 filename = path; | |
247 file_util::AppendToPath(&filename, L"data_2"); | |
248 ASSERT_TRUE(EvictFileFromSystemCache(filename.c_str())); | |
249 | |
250 filename = path; | |
251 file_util::AppendToPath(&filename, L"data_3"); | |
252 ASSERT_TRUE(EvictFileFromSystemCache(filename.c_str())); | |
253 | |
254 cache = disk_cache::CreateCacheBackend(path, false, 0); | |
255 ASSERT_TRUE(NULL != cache); | 190 ASSERT_TRUE(NULL != cache); |
256 | 191 |
257 ret = TimeRead(num_entries, cache, entries, true); | 192 ret = TimeRead(num_entries, cache, entries, true); |
258 EXPECT_EQ(ret, g_cache_tests_received); | 193 EXPECT_EQ(ret, g_cache_tests_received); |
259 | 194 |
260 ret = TimeRead(num_entries, cache, entries, false); | 195 ret = TimeRead(num_entries, cache, entries, false); |
261 EXPECT_EQ(ret, g_cache_tests_received); | 196 EXPECT_EQ(ret, g_cache_tests_received); |
262 | 197 |
263 MessageLoop::current()->RunAllPending(); | 198 MessageLoop::current()->RunAllPending(); |
264 delete cache; | 199 delete cache; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 entry = 0; | 238 entry = 0; |
304 | 239 |
305 files.DeleteBlock(address[entry], false); | 240 files.DeleteBlock(address[entry], false); |
306 EXPECT_TRUE(files.CreateBlock(disk_cache::RANKINGS, BlockSize(), | 241 EXPECT_TRUE(files.CreateBlock(disk_cache::RANKINGS, BlockSize(), |
307 &address[entry])); | 242 &address[entry])); |
308 } | 243 } |
309 | 244 |
310 timer2.Done(); | 245 timer2.Done(); |
311 MessageLoop::current()->RunAllPending(); | 246 MessageLoop::current()->RunAllPending(); |
312 } | 247 } |
OLD | NEW |