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