OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "net/disk_cache/backend_impl.h" | 5 #include "net/disk_cache/backend_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/file_path.h" | 9 #include "base/file_path.h" |
10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
(...skipping 21 matching lines...) Expand all Loading... | |
32 // This has to be defined before including histogram_macros.h from this file. | 32 // This has to be defined before including histogram_macros.h from this file. |
33 #define NET_DISK_CACHE_BACKEND_IMPL_CC_ | 33 #define NET_DISK_CACHE_BACKEND_IMPL_CC_ |
34 #include "net/disk_cache/histogram_macros.h" | 34 #include "net/disk_cache/histogram_macros.h" |
35 | 35 |
36 using base::Time; | 36 using base::Time; |
37 using base::TimeDelta; | 37 using base::TimeDelta; |
38 using base::TimeTicks; | 38 using base::TimeTicks; |
39 | 39 |
40 namespace { | 40 namespace { |
41 | 41 |
42 using disk_cache::Bitmap; | |
43 | |
42 const char* kIndexName = "index"; | 44 const char* kIndexName = "index"; |
43 const int kMaxOldFolders = 100; | 45 const int kMaxOldFolders = 100; |
44 | 46 |
45 // Seems like ~240 MB correspond to less than 50k entries for 99% of the people. | 47 // Seems like ~240 MB correspond to less than 50k entries for 99% of the people. |
46 // Note that the actual target is to keep the index table load factor under 55% | 48 // Note that the actual target is to keep the index table load factor under 55% |
47 // for most users. | 49 // for most users. |
48 const int k64kEntriesStore = 240 * 1000 * 1000; | 50 const int k64kEntriesStore = 240 * 1000 * 1000; |
49 const int kBaseTableLen = 64 * 1024; | 51 const int kBaseTableLen = 64 * 1024; |
50 const int kDefaultCacheSize = 80 * 1024 * 1024; | 52 const int kDefaultCacheSize = 80 * 1024 * 1024; |
51 | 53 |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
244 // is not there anymore... let's create a new set of files. | 246 // is not there anymore... let's create a new set of files. |
245 int rv = Run(); | 247 int rv = Run(); |
246 DCHECK_EQ(net::ERR_IO_PENDING, rv); | 248 DCHECK_EQ(net::ERR_IO_PENDING, rv); |
247 } | 249 } |
248 | 250 |
249 // A callback to perform final cleanup on the background thread. | 251 // A callback to perform final cleanup on the background thread. |
250 void FinalCleanupCallback(disk_cache::BackendImpl* backend) { | 252 void FinalCleanupCallback(disk_cache::BackendImpl* backend) { |
251 backend->CleanupCache(); | 253 backend->CleanupCache(); |
252 } | 254 } |
253 | 255 |
256 bool IsPowerOfTwo(size_t number) { | |
257 return !(number & (number - 1)); | |
258 } | |
259 | |
260 bool IndexBitmapLookup(const Bitmap& bitmap, | |
261 const std::string& key) { | |
262 DCHECK_NE(0, bitmap.Size()) << "Call site should provide default behaviour"; | |
rvargas (doing something else)
2013/02/12 01:58:33
nit: Can we just have the comment in the code (red
| |
263 DCHECK(IsPowerOfTwo(bitmap.Size())); | |
264 const uint32 mask = bitmap.Size() - 1; | |
265 const uint32 hash = base::Hash(key); | |
266 return bitmap.Get(hash & mask); | |
267 } | |
268 | |
269 void IndexBitmapSetValue(Bitmap* bitmap, | |
270 const std::string& key, | |
271 bool value) { | |
272 if (bitmap->Size() == 0) | |
273 return; | |
274 DCHECK(IsPowerOfTwo(bitmap->Size())); | |
275 const uint32 mask = bitmap->Size() - 1; | |
276 const uint32 hash = base::Hash(key); | |
277 bitmap->Set(hash & mask, value); | |
278 } | |
279 | |
254 } // namespace | 280 } // namespace |
255 | 281 |
256 // ------------------------------------------------------------------------ | 282 // ------------------------------------------------------------------------ |
257 | 283 |
258 namespace disk_cache { | 284 namespace disk_cache { |
259 | 285 |
260 int CreateCacheBackend(net::CacheType type, const base::FilePath& path, | 286 int CreateCacheBackend(net::CacheType type, const base::FilePath& path, |
261 int max_bytes, | 287 int max_bytes, |
262 bool force, base::MessageLoopProxy* thread, | 288 bool force, base::MessageLoopProxy* thread, |
263 net::NetLog* net_log, Backend** backend, | 289 net::NetLog* net_log, Backend** backend, |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
446 if (!(user_flags_ & kNoRandom)) { | 472 if (!(user_flags_ & kNoRandom)) { |
447 // The unit test controls directly what to test. | 473 // The unit test controls directly what to test. |
448 new_eviction_ = (cache_type_ == net::DISK_CACHE); | 474 new_eviction_ = (cache_type_ == net::DISK_CACHE); |
449 } | 475 } |
450 | 476 |
451 if (!CheckIndex()) { | 477 if (!CheckIndex()) { |
452 ReportError(ERR_INIT_FAILED); | 478 ReportError(ERR_INIT_FAILED); |
453 return net::ERR_FAILED; | 479 return net::ERR_FAILED; |
454 } | 480 } |
455 | 481 |
482 // TODO(gavinp): Consider clearing the |index_bitmap_| if the cache is being | |
483 // |restarted_|. It's not strictly required, because any bits set in | |
484 // |index_bitmap_| should not cause incorrect behaviour. | |
485 if (!restarted_) { | |
rvargas (doing something else)
2013/02/12 01:58:33
Maybe we should move this to InitBitmap()
| |
486 // Although |index_bitmap_| is referenced on the IO thread, it is safe to | |
487 // initialize on the cache thread when !restarted_, because the IO thread | |
488 // waits on Init() completion before using the cache and also because the | |
489 // callback PostTask includes a memory commit. | |
490 DCHECK(IsPowerOfTwo(mask_ + 1)); | |
491 index_bitmap_.Resize(mask_ + 1, false); | |
492 for (size_t i = 0; i <= mask_; ++i) | |
rvargas (doing something else)
2013/02/12 01:58:33
nit: int
| |
493 index_bitmap_.Set(i, data_->table[i] != 0); | |
494 } | |
495 | |
456 if (!restarted_ && (create_files || !data_->header.num_entries)) | 496 if (!restarted_ && (create_files || !data_->header.num_entries)) |
457 ReportError(ERR_CACHE_CREATED); | 497 ReportError(ERR_CACHE_CREATED); |
458 | 498 |
459 if (!(user_flags_ & kNoRandom) && | 499 if (!(user_flags_ & kNoRandom) && |
460 cache_type_ == net::DISK_CACHE && !InitExperiment(&data_->header)) | 500 cache_type_ == net::DISK_CACHE && !InitExperiment(&data_->header)) |
461 return net::ERR_FAILED; | 501 return net::ERR_FAILED; |
462 | 502 |
463 // We don't care if the value overflows. The only thing we care about is that | 503 // We don't care if the value overflows. The only thing we care about is that |
464 // the id cannot be zero, because that value is used as "not dirty". | 504 // the id cannot be zero, because that value is used as "not dirty". |
465 // Increasing the value once per second gives us many years before we start | 505 // Increasing the value once per second gives us many years before we start |
(...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1274 | 1314 |
1275 void BackendImpl::SetNewEviction() { | 1315 void BackendImpl::SetNewEviction() { |
1276 user_flags_ |= kNewEviction; | 1316 user_flags_ |= kNewEviction; |
1277 new_eviction_ = true; | 1317 new_eviction_ = true; |
1278 } | 1318 } |
1279 | 1319 |
1280 void BackendImpl::SetFlags(uint32 flags) { | 1320 void BackendImpl::SetFlags(uint32 flags) { |
1281 user_flags_ |= flags; | 1321 user_flags_ |= flags; |
1282 } | 1322 } |
1283 | 1323 |
1324 void BackendImpl::ClearIndexBitmapForTest() { | |
1325 index_bitmap_.Clear(); | |
1326 } | |
1327 | |
1284 void BackendImpl::ClearRefCountForTest() { | 1328 void BackendImpl::ClearRefCountForTest() { |
1285 num_refs_ = 0; | 1329 num_refs_ = 0; |
1286 } | 1330 } |
1287 | 1331 |
1288 int BackendImpl::FlushQueueForTest(const CompletionCallback& callback) { | 1332 int BackendImpl::FlushQueueForTest(const CompletionCallback& callback) { |
1289 background_queue_.FlushQueue(callback); | 1333 background_queue_.FlushQueue(callback); |
1290 return net::ERR_IO_PENDING; | 1334 return net::ERR_IO_PENDING; |
1291 } | 1335 } |
1292 | 1336 |
1293 int BackendImpl::RunTaskForTest(const base::Closure& task, | 1337 int BackendImpl::RunTaskForTest(const base::Closure& task, |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1352 NOTREACHED(); | 1396 NOTREACHED(); |
1353 not_deleted = 0; | 1397 not_deleted = 0; |
1354 } | 1398 } |
1355 | 1399 |
1356 return not_deleted; | 1400 return not_deleted; |
1357 } | 1401 } |
1358 | 1402 |
1359 int BackendImpl::OpenEntry(const std::string& key, Entry** entry, | 1403 int BackendImpl::OpenEntry(const std::string& key, Entry** entry, |
1360 const CompletionCallback& callback) { | 1404 const CompletionCallback& callback) { |
1361 DCHECK(!callback.is_null()); | 1405 DCHECK(!callback.is_null()); |
1406 if (index_bitmap_.Size() != 0 && !IndexBitmapLookup(index_bitmap_, key)) { | |
rvargas (doing something else)
2013/02/12 01:58:33
when would Size be 0?
| |
1407 VLOG(4) << "BackendImpl::OpenEntry missed on bitmap"; | |
rvargas (doing something else)
2013/02/12 01:58:33
remove tracing before checking in.
| |
1408 return net::ERR_FAILED; | |
1409 } | |
1362 background_queue_.OpenEntry(key, entry, callback); | 1410 background_queue_.OpenEntry(key, entry, callback); |
1363 return net::ERR_IO_PENDING; | 1411 return net::ERR_IO_PENDING; |
1364 } | 1412 } |
1365 | 1413 |
1366 int BackendImpl::CreateEntry(const std::string& key, Entry** entry, | 1414 int BackendImpl::CreateEntry(const std::string& key, Entry** entry, |
1367 const CompletionCallback& callback) { | 1415 const CompletionCallback& callback) { |
1368 DCHECK(!callback.is_null()); | 1416 DCHECK(!callback.is_null()); |
1417 // TODO(gavinp): Only set index_bitmap_ when CreateEntry succeeds. | |
1418 IndexBitmapSetValue(&index_bitmap_, key, true); | |
1369 background_queue_.CreateEntry(key, entry, callback); | 1419 background_queue_.CreateEntry(key, entry, callback); |
1370 return net::ERR_IO_PENDING; | 1420 return net::ERR_IO_PENDING; |
1371 } | 1421 } |
1372 | 1422 |
1373 int BackendImpl::DoomEntry(const std::string& key, | 1423 int BackendImpl::DoomEntry(const std::string& key, |
1374 const CompletionCallback& callback) { | 1424 const CompletionCallback& callback) { |
1375 DCHECK(!callback.is_null()); | 1425 DCHECK(!callback.is_null()); |
1426 // TODO(gavinp): Clear the index_bitmap_ when appropriate after Doom. | |
1376 background_queue_.DoomEntry(key, callback); | 1427 background_queue_.DoomEntry(key, callback); |
1377 return net::ERR_IO_PENDING; | 1428 return net::ERR_IO_PENDING; |
1378 } | 1429 } |
1379 | 1430 |
1380 int BackendImpl::DoomAllEntries(const CompletionCallback& callback) { | 1431 int BackendImpl::DoomAllEntries(const CompletionCallback& callback) { |
1381 DCHECK(!callback.is_null()); | 1432 DCHECK(!callback.is_null()); |
1382 background_queue_.DoomAllEntries(callback); | 1433 background_queue_.DoomAllEntries(callback); |
1383 return net::ERR_IO_PENDING; | 1434 return net::ERR_IO_PENDING; |
1384 } | 1435 } |
1385 | 1436 |
(...skipping 853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2239 if (total_memory > kMaxBuffersSize || total_memory <= 0) | 2290 if (total_memory > kMaxBuffersSize || total_memory <= 0) |
2240 total_memory = kMaxBuffersSize; | 2291 total_memory = kMaxBuffersSize; |
2241 | 2292 |
2242 done = true; | 2293 done = true; |
2243 } | 2294 } |
2244 | 2295 |
2245 return static_cast<int>(total_memory); | 2296 return static_cast<int>(total_memory); |
2246 } | 2297 } |
2247 | 2298 |
2248 } // namespace disk_cache | 2299 } // namespace disk_cache |
OLD | NEW |