| 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 |