Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(236)

Side by Side Diff: net/disk_cache/rankings.cc

Issue 155951: Disk cache: Fix handling of invalid entries that are detected... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/disk_cache/rankings.h ('k') | net/disk_cache/storage_block.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "net/disk_cache/rankings.h" 5 #include "net/disk_cache/rankings.h"
6 6
7 #include "base/histogram.h" 7 #include "base/histogram.h"
8 #include "net/disk_cache/backend_impl.h" 8 #include "net/disk_cache/backend_impl.h"
9 #include "net/disk_cache/entry_impl.h" 9 #include "net/disk_cache/entry_impl.h"
10 #include "net/disk_cache/errors.h" 10 #include "net/disk_cache/errors.h"
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 // 313 //
314 // D. Remove tail: 314 // D. Remove tail:
315 // 1. a(x, r), r(a, r), head(x), tail(r) initial state 315 // 1. a(x, r), r(a, r), head(x), tail(r) initial state
316 // 2. a(x, r), r(a, r), head(x), tail(a) WriteTail() 316 // 2. a(x, r), r(a, r), head(x), tail(a) WriteTail()
317 // 3. a(x, a), r(a, r), head(x), tail(a) prev.Store() 317 // 3. a(x, a), r(a, r), head(x), tail(a) prev.Store()
318 // 4. a(x, a), r(0, 0), head(x), tail(a) next.Store() 318 // 4. a(x, a), r(0, 0), head(x), tail(a) next.Store()
319 void Rankings::Remove(CacheRankingsBlock* node, List list) { 319 void Rankings::Remove(CacheRankingsBlock* node, List list) {
320 Trace("Remove 0x%x (0x%x 0x%x)", node->address().value(), node->Data()->next, 320 Trace("Remove 0x%x (0x%x 0x%x)", node->address().value(), node->Data()->next,
321 node->Data()->prev); 321 node->Data()->prev);
322 DCHECK(node->HasData()); 322 DCHECK(node->HasData());
323 InvalidateIterators(node);
323 Addr next_addr(node->Data()->next); 324 Addr next_addr(node->Data()->next);
324 Addr prev_addr(node->Data()->prev); 325 Addr prev_addr(node->Data()->prev);
325 if (!next_addr.is_initialized() || next_addr.is_separate_file() || 326 if (!next_addr.is_initialized() || next_addr.is_separate_file() ||
326 !prev_addr.is_initialized() || prev_addr.is_separate_file()) { 327 !prev_addr.is_initialized() || prev_addr.is_separate_file()) {
327 LOG(WARNING) << "Invalid rankings info."; 328 LOG(WARNING) << "Invalid rankings info.";
328 return; 329 return;
329 } 330 }
330 331
331 CacheRankingsBlock next(backend_->File(next_addr), next_addr); 332 CacheRankingsBlock next(backend_->File(next_addr), next_addr);
332 CacheRankingsBlock prev(backend_->File(prev_addr), prev_addr); 333 CacheRankingsBlock prev(backend_->File(prev_addr), prev_addr);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 UpdateIterators(&next); 388 UpdateIterators(&next);
388 UpdateIterators(&prev); 389 UpdateIterators(&prev);
389 } 390 }
390 391
391 // A crash in between Remove and Insert will lead to a dirty entry not on the 392 // A crash in between Remove and Insert will lead to a dirty entry not on the
392 // list. We want to avoid that case as much as we can (as while waiting for IO), 393 // list. We want to avoid that case as much as we can (as while waiting for IO),
393 // but the net effect is just an assert on debug when attempting to remove the 394 // but the net effect is just an assert on debug when attempting to remove the
394 // entry. Otherwise we'll need reentrant transactions, which is an overkill. 395 // entry. Otherwise we'll need reentrant transactions, which is an overkill.
395 void Rankings::UpdateRank(CacheRankingsBlock* node, bool modified, List list) { 396 void Rankings::UpdateRank(CacheRankingsBlock* node, bool modified, List list) {
396 Time start = Time::Now(); 397 Time start = Time::Now();
397 NotAnIterator(node);
398 Remove(node, list); 398 Remove(node, list);
399 Insert(node, modified, list); 399 Insert(node, modified, list);
400 CACHE_UMA(AGE_MS, "UpdateRank", 0, start); 400 CACHE_UMA(AGE_MS, "UpdateRank", 0, start);
401 } 401 }
402 402
403 void Rankings::CompleteTransaction() { 403 void Rankings::CompleteTransaction() {
404 Addr node_addr(static_cast<CacheAddr>(control_data_->transaction)); 404 Addr node_addr(static_cast<CacheAddr>(control_data_->transaction));
405 if (!node_addr.is_initialized() || node_addr.is_separate_file()) { 405 if (!node_addr.is_initialized() || node_addr.is_separate_file()) {
406 NOTREACHED(); 406 NOTREACHED();
407 LOG(ERROR) << "Invalid rankings info."; 407 LOG(ERROR) << "Invalid rankings info.";
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 if (node && !CheckSingleLink(prev.get(), node)) 567 if (node && !CheckSingleLink(prev.get(), node))
568 return NULL; 568 return NULL;
569 569
570 return prev.release(); 570 return prev.release();
571 } 571 }
572 572
573 void Rankings::FreeRankingsBlock(CacheRankingsBlock* node) { 573 void Rankings::FreeRankingsBlock(CacheRankingsBlock* node) {
574 TrackRankingsBlock(node, false); 574 TrackRankingsBlock(node, false);
575 } 575 }
576 576
577 void Rankings::TrackRankingsBlock(CacheRankingsBlock* node,
578 bool start_tracking) {
579 if (!node)
580 return;
581
582 IteratorPair current(node->address().value(), node);
583
584 if (start_tracking)
585 iterators_.push_back(current);
586 else
587 iterators_.remove(current);
588 }
589
577 int Rankings::SelfCheck() { 590 int Rankings::SelfCheck() {
578 int total = 0; 591 int total = 0;
579 for (int i = 0; i < LAST_ELEMENT; i++) { 592 for (int i = 0; i < LAST_ELEMENT; i++) {
580 int partial = CheckList(static_cast<List>(i)); 593 int partial = CheckList(static_cast<List>(i));
581 if (partial < 0) 594 if (partial < 0)
582 return partial; 595 return partial;
583 total += partial; 596 total += partial;
584 } 597 }
585 return total; 598 return total;
586 } 599 }
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 return false; 733 return false;
721 } 734 }
722 735
723 bool Rankings::IsTail(CacheAddr addr) { 736 bool Rankings::IsTail(CacheAddr addr) {
724 for (int i = 0; i < LAST_ELEMENT; i++) 737 for (int i = 0; i < LAST_ELEMENT; i++)
725 if (addr == tails_[i].value()) 738 if (addr == tails_[i].value())
726 return true; 739 return true;
727 return false; 740 return false;
728 } 741 }
729 742
730 void Rankings::TrackRankingsBlock(CacheRankingsBlock* node,
731 bool start_tracking) {
732 if (!node)
733 return;
734
735 IteratorPair current(node->address().value(), node);
736
737 if (start_tracking)
738 iterators_.push_back(current);
739 else
740 iterators_.remove(current);
741 }
742
743 // We expect to have just a few iterators at any given time, maybe two or three, 743 // We expect to have just a few iterators at any given time, maybe two or three,
744 // But we could have more than one pointing at the same mode. We walk the list 744 // But we could have more than one pointing at the same mode. We walk the list
745 // of cache iterators and update all that are pointing to the given node. 745 // of cache iterators and update all that are pointing to the given node.
746 void Rankings::UpdateIterators(CacheRankingsBlock* node) { 746 void Rankings::UpdateIterators(CacheRankingsBlock* node) {
747 CacheAddr address = node->address().value(); 747 CacheAddr address = node->address().value();
748 for (IteratorList::iterator it = iterators_.begin(); it != iterators_.end(); 748 for (IteratorList::iterator it = iterators_.begin(); it != iterators_.end();
749 ++it) { 749 ++it) {
750 if (it->first == address) { 750 if (it->first == address && it->second->HasData()) {
751 CacheRankingsBlock* other = it->second; 751 CacheRankingsBlock* other = it->second;
752 other->Data()->next = node->Data()->next; 752 other->Data()->next = node->Data()->next;
753 other->Data()->prev = node->Data()->prev; 753 other->Data()->prev = node->Data()->prev;
754 } 754 }
755 } 755 }
756 } 756 }
757 757
758 void Rankings::NotAnIterator(CacheRankingsBlock* node) { 758 void Rankings::InvalidateIterators(CacheRankingsBlock* node) {
759 #ifdef NDEBUG
760 // This method is only enabled for debug builds.
761 return;
762 #endif
763 CacheAddr address = node->address().value(); 759 CacheAddr address = node->address().value();
764 for (IteratorList::iterator it = iterators_.begin(); it != iterators_.end(); 760 for (IteratorList::iterator it = iterators_.begin(); it != iterators_.end();
765 ++it) { 761 ++it) {
766 if (it->first == address) 762 if (it->first == address) {
767 NOTREACHED(); 763 LOG(WARNING) << "Invalidating iterator at 0x" << std::hex << address;
764 it->second->Discard();
765 }
768 } 766 }
769 } 767 }
770 768
771 void Rankings::IncrementCounter(List list) { 769 void Rankings::IncrementCounter(List list) {
772 if (!count_lists_) 770 if (!count_lists_)
773 return; 771 return;
774 772
775 DCHECK(control_data_->sizes[list] < kint32max); 773 DCHECK(control_data_->sizes[list] < kint32max);
776 if (control_data_->sizes[list] < kint32max) 774 if (control_data_->sizes[list] < kint32max)
777 control_data_->sizes[list]++; 775 control_data_->sizes[list]++;
778 } 776 }
779 777
780 void Rankings::DecrementCounter(List list) { 778 void Rankings::DecrementCounter(List list) {
781 if (!count_lists_) 779 if (!count_lists_)
782 return; 780 return;
783 781
784 DCHECK(control_data_->sizes[list] > 0); 782 DCHECK(control_data_->sizes[list] > 0);
785 if (control_data_->sizes[list] > 0) 783 if (control_data_->sizes[list] > 0)
786 control_data_->sizes[list]--; 784 control_data_->sizes[list]--;
787 } 785 }
788 786
789 } // namespace disk_cache 787 } // namespace disk_cache
OLDNEW
« no previous file with comments | « net/disk_cache/rankings.h ('k') | net/disk_cache/storage_block.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698