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

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

Issue 159643: Disk cache: Remove remaining uses of RankingsNode.pointer.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 4 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
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 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 void Rankings::Reset() { 197 void Rankings::Reset() {
198 init_ = false; 198 init_ = false;
199 for (int i = 0; i < LAST_ELEMENT; i++) { 199 for (int i = 0; i < LAST_ELEMENT; i++) {
200 heads_[i].set_value(0); 200 heads_[i].set_value(0);
201 tails_[i].set_value(0); 201 tails_[i].set_value(0);
202 } 202 }
203 control_data_ = NULL; 203 control_data_ = NULL;
204 } 204 }
205 205
206 bool Rankings::GetRanking(CacheRankingsBlock* rankings) { 206 bool Rankings::GetRanking(CacheRankingsBlock* rankings) {
207 Time start = Time::Now();
208 if (!rankings->address().is_initialized()) 207 if (!rankings->address().is_initialized())
209 return false; 208 return false;
210 209
210 Time start = Time::Now();
211 if (!rankings->Load()) 211 if (!rankings->Load())
212 return false; 212 return false;
213 213
214 if (!SanityCheck(rankings, true)) { 214 if (!SanityCheck(rankings, true)) {
215 backend_->CriticalError(ERR_INVALID_LINKS); 215 backend_->CriticalError(ERR_INVALID_LINKS);
216 return false; 216 return false;
217 } 217 }
218 218
219 if (!rankings->Data()->pointer) {
220 backend_->OnEvent(Stats::GET_RANKINGS);
221 return true;
222 }
223
224 backend_->OnEvent(Stats::OPEN_RANKINGS); 219 backend_->OnEvent(Stats::OPEN_RANKINGS);
225 220
226 if (backend_->GetCurrentEntryId() != rankings->Data()->dirty || 221 // "dummy" is the old "pointer" value, so it has to be 0.
227 !backend_->IsOpen(rankings)) { 222 if (!rankings->Data()->dirty && !rankings->Data()->dummy)
223 return true;
224
225 EntryImpl* entry = backend_->GetOpenEntry(rankings);
226 if (backend_->GetCurrentEntryId() != rankings->Data()->dirty || !entry) {
228 // We cannot trust this entry, but we cannot initiate a cleanup from this 227 // We cannot trust this entry, but we cannot initiate a cleanup from this
229 // point (we may be in the middle of a cleanup already). Just get rid of 228 // point (we may be in the middle of a cleanup already). Just get rid of
230 // the invalid pointer and continue; the entry will be deleted when detected 229 // the invalid pointer and continue; the entry will be deleted when detected
231 // from a regular open/create path. 230 // from a regular open/create path.
232 rankings->Data()->pointer = NULL; 231 rankings->Data()->dummy = 0;
233 rankings->Data()->dirty = backend_->GetCurrentEntryId() - 1; 232 rankings->Data()->dirty = backend_->GetCurrentEntryId() - 1;
234 if (!rankings->Data()->dirty) 233 if (!rankings->Data()->dirty)
235 rankings->Data()->dirty--; 234 rankings->Data()->dirty--;
236 return true; 235 return true;
237 } 236 }
238 237
239 EntryImpl* cache_entry = 238 // Note that we should not leave this module without deleting rankings first.
240 reinterpret_cast<EntryImpl*>(rankings->Data()->pointer); 239 rankings->SetData(entry->rankings()->Data());
241 rankings->SetData(cache_entry->rankings()->Data()); 240
242 CACHE_UMA(AGE_MS, "GetRankings", 0, start); 241 CACHE_UMA(AGE_MS, "GetRankings", 0, start);
243 return true; 242 return true;
244 } 243 }
245 244
245 void Rankings::ConvertToLongLived(CacheRankingsBlock* rankings) {
246 if (rankings->own_data())
247 return;
248
249 // We cannot return a shared node because we are not keeping a reference
250 // to the entry that owns the buffer. Make this node a copy of the one that
251 // we have, and let the iterator logic update it when the entry changes.
252 CacheRankingsBlock temp(NULL, Addr(0));
253 *temp.Data() = *rankings->Data();
254 rankings->StopSharingData();
255 *rankings->Data() = *temp.Data();
256 }
257
246 void Rankings::Insert(CacheRankingsBlock* node, bool modified, List list) { 258 void Rankings::Insert(CacheRankingsBlock* node, bool modified, List list) {
247 Trace("Insert 0x%x", node->address().value()); 259 Trace("Insert 0x%x", node->address().value());
248 DCHECK(node->HasData()); 260 DCHECK(node->HasData());
249 Addr& my_head = heads_[list]; 261 Addr& my_head = heads_[list];
250 Addr& my_tail = tails_[list]; 262 Addr& my_tail = tails_[list];
251 Transaction lock(control_data_, node->address(), INSERT, list); 263 Transaction lock(control_data_, node->address(), INSERT, list);
252 CacheRankingsBlock head(backend_->File(my_head), my_head); 264 CacheRankingsBlock head(backend_->File(my_head), my_head);
253 if (my_head.is_initialized()) { 265 if (my_head.is_initialized()) {
254 if (!GetRanking(&head)) 266 if (!GetRanking(&head))
255 return; 267 return;
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 LOG(ERROR) << "Invalid rankings info."; 419 LOG(ERROR) << "Invalid rankings info.";
408 return; 420 return;
409 } 421 }
410 422
411 Trace("CompleteTransaction 0x%x", node_addr.value()); 423 Trace("CompleteTransaction 0x%x", node_addr.value());
412 424
413 CacheRankingsBlock node(backend_->File(node_addr), node_addr); 425 CacheRankingsBlock node(backend_->File(node_addr), node_addr);
414 if (!node.Load()) 426 if (!node.Load())
415 return; 427 return;
416 428
417 node.Data()->pointer = NULL; 429 node.Data()->dummy = 0;
418 node.Store(); 430 node.Store();
419 431
420 Addr& my_head = heads_[control_data_->operation_list]; 432 Addr& my_head = heads_[control_data_->operation_list];
421 Addr& my_tail = tails_[control_data_->operation_list]; 433 Addr& my_tail = tails_[control_data_->operation_list];
422 434
423 // We want to leave the node inside the list. The entry must me marked as 435 // We want to leave the node inside the list. The entry must me marked as
424 // dirty, and will be removed later. Otherwise, we'll get assertions when 436 // dirty, and will be removed later. Otherwise, we'll get assertions when
425 // attempting to remove the dirty entry. 437 // attempting to remove the dirty entry.
426 if (INSERT == control_data_->operation) { 438 if (INSERT == control_data_->operation) {
427 Trace("FinishInsert h:0x%x t:0x%x", my_head.value(), my_tail.value()); 439 Trace("FinishInsert h:0x%x t:0x%x", my_head.value(), my_tail.value());
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 } 523 }
512 524
513 CacheRankingsBlock* Rankings::GetNext(CacheRankingsBlock* node, List list) { 525 CacheRankingsBlock* Rankings::GetNext(CacheRankingsBlock* node, List list) {
514 ScopedRankingsBlock next(this); 526 ScopedRankingsBlock next(this);
515 if (!node) { 527 if (!node) {
516 Addr& my_head = heads_[list]; 528 Addr& my_head = heads_[list];
517 if (!my_head.is_initialized()) 529 if (!my_head.is_initialized())
518 return NULL; 530 return NULL;
519 next.reset(new CacheRankingsBlock(backend_->File(my_head), my_head)); 531 next.reset(new CacheRankingsBlock(backend_->File(my_head), my_head));
520 } else { 532 } else {
533 if (!node->HasData())
534 node->Load();
521 Addr& my_tail = tails_[list]; 535 Addr& my_tail = tails_[list];
522 if (!my_tail.is_initialized()) 536 if (!my_tail.is_initialized())
523 return NULL; 537 return NULL;
524 if (my_tail.value() == node->address().value()) 538 if (my_tail.value() == node->address().value())
525 return NULL; 539 return NULL;
526 Addr address(node->Data()->next); 540 Addr address(node->Data()->next);
527 if (address.value() == node->address().value()) 541 if (address.value() == node->address().value())
528 return NULL; // Another tail? fail it. 542 return NULL; // Another tail? fail it.
529 next.reset(new CacheRankingsBlock(backend_->File(address), address)); 543 next.reset(new CacheRankingsBlock(backend_->File(address), address));
530 } 544 }
531 545
532 TrackRankingsBlock(next.get(), true); 546 TrackRankingsBlock(next.get(), true);
533 547
534 if (!GetRanking(next.get())) 548 if (!GetRanking(next.get()))
535 return NULL; 549 return NULL;
536 550
551 ConvertToLongLived(next.get());
537 if (node && !CheckSingleLink(node, next.get())) 552 if (node && !CheckSingleLink(node, next.get()))
538 return NULL; 553 return NULL;
539 554
540 return next.release(); 555 return next.release();
541 } 556 }
542 557
543 CacheRankingsBlock* Rankings::GetPrev(CacheRankingsBlock* node, List list) { 558 CacheRankingsBlock* Rankings::GetPrev(CacheRankingsBlock* node, List list) {
544 ScopedRankingsBlock prev(this); 559 ScopedRankingsBlock prev(this);
545 if (!node) { 560 if (!node) {
546 Addr& my_tail = tails_[list]; 561 Addr& my_tail = tails_[list];
547 if (!my_tail.is_initialized()) 562 if (!my_tail.is_initialized())
548 return NULL; 563 return NULL;
549 prev.reset(new CacheRankingsBlock(backend_->File(my_tail), my_tail)); 564 prev.reset(new CacheRankingsBlock(backend_->File(my_tail), my_tail));
550 } else { 565 } else {
566 if (!node->HasData())
567 node->Load();
551 Addr& my_head = heads_[list]; 568 Addr& my_head = heads_[list];
552 if (!my_head.is_initialized()) 569 if (!my_head.is_initialized())
553 return NULL; 570 return NULL;
554 if (my_head.value() == node->address().value()) 571 if (my_head.value() == node->address().value())
555 return NULL; 572 return NULL;
556 Addr address(node->Data()->prev); 573 Addr address(node->Data()->prev);
557 if (address.value() == node->address().value()) 574 if (address.value() == node->address().value())
558 return NULL; // Another head? fail it. 575 return NULL; // Another head? fail it.
559 prev.reset(new CacheRankingsBlock(backend_->File(address), address)); 576 prev.reset(new CacheRankingsBlock(backend_->File(address), address));
560 } 577 }
561 578
562 TrackRankingsBlock(prev.get(), true); 579 TrackRankingsBlock(prev.get(), true);
563 580
564 if (!GetRanking(prev.get())) 581 if (!GetRanking(prev.get()))
565 return NULL; 582 return NULL;
566 583
584 ConvertToLongLived(prev.get());
567 if (node && !CheckSingleLink(prev.get(), node)) 585 if (node && !CheckSingleLink(prev.get(), node))
568 return NULL; 586 return NULL;
569 587
570 return prev.release(); 588 return prev.release();
571 } 589 }
572 590
573 void Rankings::FreeRankingsBlock(CacheRankingsBlock* node) { 591 void Rankings::FreeRankingsBlock(CacheRankingsBlock* node) {
574 TrackRankingsBlock(node, false); 592 TrackRankingsBlock(node, false);
575 } 593 }
576 594
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 653
636 void Rankings::WriteHead(List list) { 654 void Rankings::WriteHead(List list) {
637 control_data_->heads[list] = heads_[list].value(); 655 control_data_->heads[list] = heads_[list].value();
638 } 656 }
639 657
640 void Rankings::WriteTail(List list) { 658 void Rankings::WriteTail(List list) {
641 control_data_->tails[list] = tails_[list].value(); 659 control_data_->tails[list] = tails_[list].value();
642 } 660 }
643 661
644 bool Rankings::CheckEntry(CacheRankingsBlock* rankings) { 662 bool Rankings::CheckEntry(CacheRankingsBlock* rankings) {
645 if (!rankings->Data()->pointer) 663 if (!rankings->Data()->dummy)
646 return true; 664 return true;
647 665
648 // If this entry is not dirty, it is a serious problem. 666 // If this entry is not dirty, it is a serious problem.
649 return backend_->GetCurrentEntryId() != rankings->Data()->dirty; 667 return backend_->GetCurrentEntryId() != rankings->Data()->dirty;
650 } 668 }
651 669
652 bool Rankings::CheckLinks(CacheRankingsBlock* node, CacheRankingsBlock* prev, 670 bool Rankings::CheckLinks(CacheRankingsBlock* node, CacheRankingsBlock* prev,
653 CacheRankingsBlock* next, List list) { 671 CacheRankingsBlock* next, List list) {
654 if ((prev->Data()->next != node->address().value() && 672 if ((prev->Data()->next != node->address().value() &&
655 heads_[list].value() != node->address().value()) || 673 heads_[list].value() != node->address().value()) ||
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 760
743 // We expect to have just a few iterators at any given time, maybe two or three, 761 // 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 762 // 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. 763 // of cache iterators and update all that are pointing to the given node.
746 void Rankings::UpdateIterators(CacheRankingsBlock* node) { 764 void Rankings::UpdateIterators(CacheRankingsBlock* node) {
747 CacheAddr address = node->address().value(); 765 CacheAddr address = node->address().value();
748 for (IteratorList::iterator it = iterators_.begin(); it != iterators_.end(); 766 for (IteratorList::iterator it = iterators_.begin(); it != iterators_.end();
749 ++it) { 767 ++it) {
750 if (it->first == address && it->second->HasData()) { 768 if (it->first == address && it->second->HasData()) {
751 CacheRankingsBlock* other = it->second; 769 CacheRankingsBlock* other = it->second;
752 other->Data()->next = node->Data()->next; 770 *other->Data() = *node->Data();
753 other->Data()->prev = node->Data()->prev;
754 } 771 }
755 } 772 }
756 } 773 }
757 774
758 void Rankings::InvalidateIterators(CacheRankingsBlock* node) { 775 void Rankings::InvalidateIterators(CacheRankingsBlock* node) {
759 CacheAddr address = node->address().value(); 776 CacheAddr address = node->address().value();
760 for (IteratorList::iterator it = iterators_.begin(); it != iterators_.end(); 777 for (IteratorList::iterator it = iterators_.begin(); it != iterators_.end();
761 ++it) { 778 ++it) {
762 if (it->first == address) { 779 if (it->first == address) {
763 LOG(WARNING) << "Invalidating iterator at 0x" << std::hex << address; 780 LOG(WARNING) << "Invalidating iterator at 0x" << std::hex << address;
(...skipping 14 matching lines...) Expand all
778 void Rankings::DecrementCounter(List list) { 795 void Rankings::DecrementCounter(List list) {
779 if (!count_lists_) 796 if (!count_lists_)
780 return; 797 return;
781 798
782 DCHECK(control_data_->sizes[list] > 0); 799 DCHECK(control_data_->sizes[list] > 0);
783 if (control_data_->sizes[list] > 0) 800 if (control_data_->sizes[list] > 0)
784 control_data_->sizes[list]--; 801 control_data_->sizes[list]--;
785 } 802 }
786 803
787 } // namespace disk_cache 804 } // namespace disk_cache
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698