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/blockfile/backend_impl.h" | 5 #include "net/disk_cache/blockfile/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/files/file.h" | 9 #include "base/files/file.h" |
10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 DCHECK_NE(net::APP_CACHE, cache_type_); | 374 DCHECK_NE(net::APP_CACHE, cache_type_); |
375 if (end_time.is_null()) | 375 if (end_time.is_null()) |
376 return SyncDoomEntriesSince(initial_time); | 376 return SyncDoomEntriesSince(initial_time); |
377 | 377 |
378 DCHECK(end_time >= initial_time); | 378 DCHECK(end_time >= initial_time); |
379 | 379 |
380 if (disabled_) | 380 if (disabled_) |
381 return net::ERR_FAILED; | 381 return net::ERR_FAILED; |
382 | 382 |
383 EntryImpl* node; | 383 EntryImpl* node; |
384 void* iter = NULL; | 384 scoped_ptr<Rankings::Iterator> iterator(new Rankings::Iterator()); |
385 EntryImpl* next = OpenNextEntryImpl(&iter); | 385 EntryImpl* next = OpenNextEntryImpl(iterator.get()); |
386 if (!next) | 386 if (!next) |
387 return net::OK; | 387 return net::OK; |
388 | 388 |
389 while (next) { | 389 while (next) { |
390 node = next; | 390 node = next; |
391 next = OpenNextEntryImpl(&iter); | 391 next = OpenNextEntryImpl(iterator.get()); |
392 | 392 |
393 if (node->GetLastUsed() >= initial_time && | 393 if (node->GetLastUsed() >= initial_time && |
394 node->GetLastUsed() < end_time) { | 394 node->GetLastUsed() < end_time) { |
395 node->DoomImpl(); | 395 node->DoomImpl(); |
396 } else if (node->GetLastUsed() < initial_time) { | 396 } else if (node->GetLastUsed() < initial_time) { |
397 if (next) | 397 if (next) |
398 next->Release(); | 398 next->Release(); |
399 next = NULL; | 399 next = NULL; |
400 SyncEndEnumeration(iter); | 400 SyncEndEnumeration(iterator.Pass()); |
401 } | 401 } |
402 | 402 |
403 node->Release(); | 403 node->Release(); |
404 } | 404 } |
405 | 405 |
406 return net::OK; | 406 return net::OK; |
407 } | 407 } |
408 | 408 |
409 // We use OpenNextEntryImpl to retrieve elements from the cache, until we get | 409 // We use OpenNextEntryImpl to retrieve elements from the cache, until we get |
410 // entries that are too old. | 410 // entries that are too old. |
411 int BackendImpl::SyncDoomEntriesSince(const base::Time initial_time) { | 411 int BackendImpl::SyncDoomEntriesSince(const base::Time initial_time) { |
412 DCHECK_NE(net::APP_CACHE, cache_type_); | 412 DCHECK_NE(net::APP_CACHE, cache_type_); |
413 if (disabled_) | 413 if (disabled_) |
414 return net::ERR_FAILED; | 414 return net::ERR_FAILED; |
415 | 415 |
416 stats_.OnEvent(Stats::DOOM_RECENT); | 416 stats_.OnEvent(Stats::DOOM_RECENT); |
417 for (;;) { | 417 for (;;) { |
418 void* iter = NULL; | 418 scoped_ptr<Rankings::Iterator> iterator(new Rankings::Iterator()); |
419 EntryImpl* entry = OpenNextEntryImpl(&iter); | 419 EntryImpl* entry = OpenNextEntryImpl(iterator.get()); |
420 if (!entry) | 420 if (!entry) |
421 return net::OK; | 421 return net::OK; |
422 | 422 |
423 if (initial_time > entry->GetLastUsed()) { | 423 if (initial_time > entry->GetLastUsed()) { |
424 entry->Release(); | 424 entry->Release(); |
425 SyncEndEnumeration(iter); | 425 SyncEndEnumeration(iterator.Pass()); |
426 return net::OK; | 426 return net::OK; |
427 } | 427 } |
428 | 428 |
429 entry->DoomImpl(); | 429 entry->DoomImpl(); |
430 entry->Release(); | 430 entry->Release(); |
431 SyncEndEnumeration(iter); // Dooming the entry invalidates the iterator. | 431 SyncEndEnumeration(iterator.Pass()); // The doom invalidated the iterator. |
432 } | 432 } |
433 } | 433 } |
434 | 434 |
435 int BackendImpl::SyncOpenNextEntry(void** iter, Entry** next_entry) { | 435 int BackendImpl::SyncOpenNextEntry(Rankings::Iterator* iterator, |
436 *next_entry = OpenNextEntryImpl(iter); | 436 Entry** next_entry) { |
| 437 *next_entry = OpenNextEntryImpl(iterator); |
437 return (*next_entry) ? net::OK : net::ERR_FAILED; | 438 return (*next_entry) ? net::OK : net::ERR_FAILED; |
438 } | 439 } |
439 | 440 |
440 void BackendImpl::SyncEndEnumeration(void* iter) { | 441 void BackendImpl::SyncEndEnumeration(scoped_ptr<Rankings::Iterator> iterator) { |
441 scoped_ptr<Rankings::Iterator> iterator( | 442 iterator->Reset(); |
442 reinterpret_cast<Rankings::Iterator*>(iter)); | |
443 } | 443 } |
444 | 444 |
445 void BackendImpl::SyncOnExternalCacheHit(const std::string& key) { | 445 void BackendImpl::SyncOnExternalCacheHit(const std::string& key) { |
446 if (disabled_) | 446 if (disabled_) |
447 return; | 447 return; |
448 | 448 |
449 uint32 hash = base::Hash(key); | 449 uint32 hash = base::Hash(key); |
450 bool error; | 450 bool error; |
451 EntryImpl* cache_entry = MatchEntry(key, hash, false, Addr(), &error); | 451 EntryImpl* cache_entry = MatchEntry(key, hash, false, Addr(), &error); |
452 if (cache_entry) { | 452 if (cache_entry) { |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 | 597 |
598 CACHE_UMA(AGE_MS, "CreateTime", 0, start); | 598 CACHE_UMA(AGE_MS, "CreateTime", 0, start); |
599 stats_.OnEvent(Stats::CREATE_HIT); | 599 stats_.OnEvent(Stats::CREATE_HIT); |
600 SIMPLE_STATS_COUNTER("disk_cache.miss"); | 600 SIMPLE_STATS_COUNTER("disk_cache.miss"); |
601 Trace("create entry hit "); | 601 Trace("create entry hit "); |
602 FlushIndex(); | 602 FlushIndex(); |
603 cache_entry->AddRef(); | 603 cache_entry->AddRef(); |
604 return cache_entry.get(); | 604 return cache_entry.get(); |
605 } | 605 } |
606 | 606 |
607 EntryImpl* BackendImpl::OpenNextEntryImpl(void** iter) { | 607 EntryImpl* BackendImpl::OpenNextEntryImpl(Rankings::Iterator* iterator) { |
608 if (disabled_) | 608 if (disabled_) |
609 return NULL; | 609 return NULL; |
610 | 610 |
611 DCHECK(iter); | |
612 | |
613 const int kListsToSearch = 3; | 611 const int kListsToSearch = 3; |
614 scoped_refptr<EntryImpl> entries[kListsToSearch]; | 612 scoped_refptr<EntryImpl> entries[kListsToSearch]; |
615 scoped_ptr<Rankings::Iterator> iterator( | 613 if (!iterator->my_rankings) { |
616 reinterpret_cast<Rankings::Iterator*>(*iter)); | 614 iterator->my_rankings = &rankings_; |
617 *iter = NULL; | |
618 | |
619 if (!iterator.get()) { | |
620 iterator.reset(new Rankings::Iterator(&rankings_)); | |
621 bool ret = false; | 615 bool ret = false; |
622 | 616 |
623 // Get an entry from each list. | 617 // Get an entry from each list. |
624 for (int i = 0; i < kListsToSearch; i++) { | 618 for (int i = 0; i < kListsToSearch; i++) { |
625 EntryImpl* temp = NULL; | 619 EntryImpl* temp = NULL; |
626 ret |= OpenFollowingEntryFromList(static_cast<Rankings::List>(i), | 620 ret |= OpenFollowingEntryFromList(static_cast<Rankings::List>(i), |
627 &iterator->nodes[i], &temp); | 621 &iterator->nodes[i], &temp); |
628 entries[i].swap(&temp); // The entry was already addref'd. | 622 entries[i].swap(&temp); // The entry was already addref'd. |
629 } | 623 } |
630 if (!ret) | 624 if (!ret) { |
| 625 iterator->Reset(); |
631 return NULL; | 626 return NULL; |
| 627 } |
632 } else { | 628 } else { |
633 // Get the next entry from the last list, and the actual entries for the | 629 // Get the next entry from the last list, and the actual entries for the |
634 // elements on the other lists. | 630 // elements on the other lists. |
635 for (int i = 0; i < kListsToSearch; i++) { | 631 for (int i = 0; i < kListsToSearch; i++) { |
636 EntryImpl* temp = NULL; | 632 EntryImpl* temp = NULL; |
637 if (iterator->list == i) { | 633 if (iterator->list == i) { |
638 OpenFollowingEntryFromList( | 634 OpenFollowingEntryFromList( |
639 iterator->list, &iterator->nodes[i], &temp); | 635 iterator->list, &iterator->nodes[i], &temp); |
640 } else { | 636 } else { |
641 temp = GetEnumeratedEntry(iterator->nodes[i], | 637 temp = GetEnumeratedEntry(iterator->nodes[i], |
(...skipping 15 matching lines...) Expand all Loading... |
657 newest = oldest = i; | 653 newest = oldest = i; |
658 continue; | 654 continue; |
659 } | 655 } |
660 if (access_times[i] > access_times[newest]) | 656 if (access_times[i] > access_times[newest]) |
661 newest = i; | 657 newest = i; |
662 if (access_times[i] < access_times[oldest]) | 658 if (access_times[i] < access_times[oldest]) |
663 oldest = i; | 659 oldest = i; |
664 } | 660 } |
665 } | 661 } |
666 | 662 |
667 if (newest < 0 || oldest < 0) | 663 if (newest < 0 || oldest < 0) { |
| 664 iterator->Reset(); |
668 return NULL; | 665 return NULL; |
| 666 } |
669 | 667 |
670 EntryImpl* next_entry; | 668 EntryImpl* next_entry; |
671 next_entry = entries[newest].get(); | 669 next_entry = entries[newest].get(); |
672 iterator->list = static_cast<Rankings::List>(newest); | 670 iterator->list = static_cast<Rankings::List>(newest); |
673 *iter = iterator.release(); | |
674 next_entry->AddRef(); | 671 next_entry->AddRef(); |
675 return next_entry; | 672 return next_entry; |
676 } | 673 } |
677 | 674 |
678 bool BackendImpl::SetMaxSize(int max_bytes) { | 675 bool BackendImpl::SetMaxSize(int max_bytes) { |
679 COMPILE_ASSERT(sizeof(max_bytes) == sizeof(max_size_), unsupported_int_model); | 676 COMPILE_ASSERT(sizeof(max_bytes) == sizeof(max_size_), unsupported_int_model); |
680 if (max_bytes < 0) | 677 if (max_bytes < 0) |
681 return false; | 678 return false; |
682 | 679 |
683 // Zero size means use the default. | 680 // Zero size means use the default. |
(...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1243 return net::ERR_IO_PENDING; | 1240 return net::ERR_IO_PENDING; |
1244 } | 1241 } |
1245 | 1242 |
1246 int BackendImpl::DoomEntriesSince(const base::Time initial_time, | 1243 int BackendImpl::DoomEntriesSince(const base::Time initial_time, |
1247 const CompletionCallback& callback) { | 1244 const CompletionCallback& callback) { |
1248 DCHECK(!callback.is_null()); | 1245 DCHECK(!callback.is_null()); |
1249 background_queue_.DoomEntriesSince(initial_time, callback); | 1246 background_queue_.DoomEntriesSince(initial_time, callback); |
1250 return net::ERR_IO_PENDING; | 1247 return net::ERR_IO_PENDING; |
1251 } | 1248 } |
1252 | 1249 |
1253 int BackendImpl::OpenNextEntry(void** iter, Entry** next_entry, | 1250 class BackendImpl::IteratorImpl : public Backend::Iterator { |
1254 const CompletionCallback& callback) { | 1251 public: |
1255 DCHECK(!callback.is_null()); | 1252 explicit IteratorImpl(base::WeakPtr<InFlightBackendIO> background_queue) |
1256 background_queue_.OpenNextEntry(iter, next_entry, callback); | 1253 : background_queue_(background_queue), |
1257 return net::ERR_IO_PENDING; | 1254 iterator_(new Rankings::Iterator()) { |
1258 } | 1255 } |
1259 | 1256 |
1260 void BackendImpl::EndEnumeration(void** iter) { | 1257 virtual ~IteratorImpl() { |
1261 background_queue_.EndEnumeration(*iter); | 1258 if (background_queue_) |
1262 *iter = NULL; | 1259 background_queue_->EndEnumeration(iterator_.Pass()); |
| 1260 } |
| 1261 |
| 1262 virtual int OpenNextEntry(Entry** next_entry, |
| 1263 const net::CompletionCallback& callback) OVERRIDE { |
| 1264 if (!background_queue_) |
| 1265 return net::ERR_FAILED; |
| 1266 background_queue_->OpenNextEntry(iterator_.get(), next_entry, callback); |
| 1267 return net::ERR_IO_PENDING; |
| 1268 } |
| 1269 |
| 1270 private: |
| 1271 const base::WeakPtr<InFlightBackendIO> background_queue_; |
| 1272 scoped_ptr<Rankings::Iterator> iterator_; |
| 1273 }; |
| 1274 |
| 1275 scoped_ptr<Backend::Iterator> BackendImpl::CreateIterator() { |
| 1276 return scoped_ptr<Backend::Iterator>(new IteratorImpl(GetBackgroundQueue())); |
1263 } | 1277 } |
1264 | 1278 |
1265 void BackendImpl::GetStats(StatsItems* stats) { | 1279 void BackendImpl::GetStats(StatsItems* stats) { |
1266 if (disabled_) | 1280 if (disabled_) |
1267 return; | 1281 return; |
1268 | 1282 |
1269 std::pair<std::string, std::string> item; | 1283 std::pair<std::string, std::string> item; |
1270 | 1284 |
1271 item.first = "Entries"; | 1285 item.first = "Entries"; |
1272 item.second = base::StringPrintf("%d", data_->header.num_entries); | 1286 item.second = base::StringPrintf("%d", data_->header.num_entries); |
(...skipping 793 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2066 if (total_memory > kMaxBuffersSize || total_memory <= 0) | 2080 if (total_memory > kMaxBuffersSize || total_memory <= 0) |
2067 total_memory = kMaxBuffersSize; | 2081 total_memory = kMaxBuffersSize; |
2068 | 2082 |
2069 done = true; | 2083 done = true; |
2070 } | 2084 } |
2071 | 2085 |
2072 return static_cast<int>(total_memory); | 2086 return static_cast<int>(total_memory); |
2073 } | 2087 } |
2074 | 2088 |
2075 } // namespace disk_cache | 2089 } // namespace disk_cache |
OLD | NEW |