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

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

Issue 6339012: More net/ method ordering. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: More done while waiting for previous patch to clear Created 9 years, 10 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/mapped_file_posix.cc ('k') | net/disk_cache/stats.cc » ('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/metrics/histogram.h" 7 #include "base/metrics/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 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 221
222 void Rankings::Reset() { 222 void Rankings::Reset() {
223 init_ = false; 223 init_ = false;
224 for (int i = 0; i < LAST_ELEMENT; i++) { 224 for (int i = 0; i < LAST_ELEMENT; i++) {
225 heads_[i].set_value(0); 225 heads_[i].set_value(0);
226 tails_[i].set_value(0); 226 tails_[i].set_value(0);
227 } 227 }
228 control_data_ = NULL; 228 control_data_ = NULL;
229 } 229 }
230 230
231 bool Rankings::GetRanking(CacheRankingsBlock* rankings) {
232 if (!rankings->address().is_initialized())
233 return false;
234
235 TimeTicks start = TimeTicks::Now();
236 if (!rankings->Load())
237 return false;
238
239 if (!SanityCheck(rankings, true)) {
240 backend_->CriticalError(ERR_INVALID_LINKS);
241 return false;
242 }
243
244 backend_->OnEvent(Stats::OPEN_RANKINGS);
245
246 // "dummy" is the old "pointer" value, so it has to be 0.
247 if (!rankings->Data()->dirty && !rankings->Data()->dummy)
248 return true;
249
250 EntryImpl* entry = backend_->GetOpenEntry(rankings);
251 if (backend_->GetCurrentEntryId() != rankings->Data()->dirty || !entry) {
252 // We cannot trust this entry, but we cannot initiate a cleanup from this
253 // point (we may be in the middle of a cleanup already). Just get rid of
254 // the invalid pointer and continue; the entry will be deleted when detected
255 // from a regular open/create path.
256 rankings->Data()->dummy = 0;
257 rankings->Data()->dirty = backend_->GetCurrentEntryId() - 1;
258 if (!rankings->Data()->dirty)
259 rankings->Data()->dirty--;
260 return true;
261 }
262
263 // Note that we should not leave this module without deleting rankings first.
264 rankings->SetData(entry->rankings()->Data());
265
266 CACHE_UMA(AGE_MS, "GetRankings", 0, start);
267 return true;
268 }
269
270 void Rankings::ConvertToLongLived(CacheRankingsBlock* rankings) {
271 if (rankings->own_data())
272 return;
273
274 // We cannot return a shared node because we are not keeping a reference
275 // to the entry that owns the buffer. Make this node a copy of the one that
276 // we have, and let the iterator logic update it when the entry changes.
277 CacheRankingsBlock temp(NULL, Addr(0));
278 *temp.Data() = *rankings->Data();
279 rankings->StopSharingData();
280 *rankings->Data() = *temp.Data();
281 }
282
283 void Rankings::Insert(CacheRankingsBlock* node, bool modified, List list) { 231 void Rankings::Insert(CacheRankingsBlock* node, bool modified, List list) {
284 Trace("Insert 0x%x l %d", node->address().value(), list); 232 Trace("Insert 0x%x l %d", node->address().value(), list);
285 DCHECK(node->HasData()); 233 DCHECK(node->HasData());
286 Addr& my_head = heads_[list]; 234 Addr& my_head = heads_[list];
287 Addr& my_tail = tails_[list]; 235 Addr& my_tail = tails_[list];
288 Transaction lock(control_data_, node->address(), INSERT, list); 236 Transaction lock(control_data_, node->address(), INSERT, list);
289 CacheRankingsBlock head(backend_->File(my_head), my_head); 237 CacheRankingsBlock head(backend_->File(my_head), my_head);
290 if (my_head.is_initialized()) { 238 if (my_head.is_initialized()) {
291 if (!GetRanking(&head)) 239 if (!GetRanking(&head))
292 return; 240 return;
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 node->set_modified(); 384 node->set_modified();
437 return; 385 return;
438 } 386 }
439 387
440 TimeTicks start = TimeTicks::Now(); 388 TimeTicks start = TimeTicks::Now();
441 Remove(node, list); 389 Remove(node, list);
442 Insert(node, modified, list); 390 Insert(node, modified, list);
443 CACHE_UMA(AGE_MS, "UpdateRank", 0, start); 391 CACHE_UMA(AGE_MS, "UpdateRank", 0, start);
444 } 392 }
445 393
446 void Rankings::CompleteTransaction() {
447 Addr node_addr(static_cast<CacheAddr>(control_data_->transaction));
448 if (!node_addr.is_initialized() || node_addr.is_separate_file()) {
449 NOTREACHED();
450 LOG(ERROR) << "Invalid rankings info.";
451 return;
452 }
453
454 Trace("CompleteTransaction 0x%x", node_addr.value());
455
456 CacheRankingsBlock node(backend_->File(node_addr), node_addr);
457 if (!node.Load())
458 return;
459
460 node.Data()->dummy = 0;
461 node.Store();
462
463 Addr& my_head = heads_[control_data_->operation_list];
464 Addr& my_tail = tails_[control_data_->operation_list];
465
466 // We want to leave the node inside the list. The entry must me marked as
467 // dirty, and will be removed later. Otherwise, we'll get assertions when
468 // attempting to remove the dirty entry.
469 if (INSERT == control_data_->operation) {
470 Trace("FinishInsert h:0x%x t:0x%x", my_head.value(), my_tail.value());
471 FinishInsert(&node);
472 } else if (REMOVE == control_data_->operation) {
473 Trace("RevertRemove h:0x%x t:0x%x", my_head.value(), my_tail.value());
474 RevertRemove(&node);
475 } else {
476 NOTREACHED();
477 LOG(ERROR) << "Invalid operation to recover.";
478 }
479 }
480
481 void Rankings::FinishInsert(CacheRankingsBlock* node) {
482 control_data_->transaction = 0;
483 control_data_->operation = 0;
484 Addr& my_head = heads_[control_data_->operation_list];
485 Addr& my_tail = tails_[control_data_->operation_list];
486 if (my_head.value() != node->address().value()) {
487 if (my_tail.value() == node->address().value()) {
488 // This part will be skipped by the logic of Insert.
489 node->Data()->next = my_tail.value();
490 }
491
492 Insert(node, true, static_cast<List>(control_data_->operation_list));
493 }
494
495 // Tell the backend about this entry.
496 backend_->RecoveredEntry(node);
497 }
498
499 void Rankings::RevertRemove(CacheRankingsBlock* node) {
500 Addr next_addr(node->Data()->next);
501 Addr prev_addr(node->Data()->prev);
502 if (!next_addr.is_initialized() || !prev_addr.is_initialized()) {
503 // The operation actually finished. Nothing to do.
504 control_data_->transaction = 0;
505 return;
506 }
507 if (next_addr.is_separate_file() || prev_addr.is_separate_file()) {
508 NOTREACHED();
509 LOG(WARNING) << "Invalid rankings info.";
510 control_data_->transaction = 0;
511 return;
512 }
513
514 CacheRankingsBlock next(backend_->File(next_addr), next_addr);
515 CacheRankingsBlock prev(backend_->File(prev_addr), prev_addr);
516 if (!next.Load() || !prev.Load())
517 return;
518
519 CacheAddr node_value = node->address().value();
520 DCHECK(prev.Data()->next == node_value ||
521 prev.Data()->next == prev_addr.value() ||
522 prev.Data()->next == next.address().value());
523 DCHECK(next.Data()->prev == node_value ||
524 next.Data()->prev == next_addr.value() ||
525 next.Data()->prev == prev.address().value());
526
527 if (node_value != prev_addr.value())
528 prev.Data()->next = node_value;
529 if (node_value != next_addr.value())
530 next.Data()->prev = node_value;
531
532 List my_list = static_cast<List>(control_data_->operation_list);
533 Addr& my_head = heads_[my_list];
534 Addr& my_tail = tails_[my_list];
535 if (!my_head.is_initialized() || !my_tail.is_initialized()) {
536 my_head.set_value(node_value);
537 my_tail.set_value(node_value);
538 WriteHead(my_list);
539 WriteTail(my_list);
540 } else if (my_head.value() == next.address().value()) {
541 my_head.set_value(node_value);
542 prev.Data()->next = next.address().value();
543 WriteHead(my_list);
544 } else if (my_tail.value() == prev.address().value()) {
545 my_tail.set_value(node_value);
546 next.Data()->prev = prev.address().value();
547 WriteTail(my_list);
548 }
549
550 next.Store();
551 prev.Store();
552 control_data_->transaction = 0;
553 control_data_->operation = 0;
554 }
555
556 CacheRankingsBlock* Rankings::GetNext(CacheRankingsBlock* node, List list) { 394 CacheRankingsBlock* Rankings::GetNext(CacheRankingsBlock* node, List list) {
557 ScopedRankingsBlock next(this); 395 ScopedRankingsBlock next(this);
558 if (!node) { 396 if (!node) {
559 Addr& my_head = heads_[list]; 397 Addr& my_head = heads_[list];
560 if (!my_head.is_initialized()) 398 if (!my_head.is_initialized())
561 return NULL; 399 return NULL;
562 next.reset(new CacheRankingsBlock(backend_->File(my_head), my_head)); 400 next.reset(new CacheRankingsBlock(backend_->File(my_head), my_head));
563 } else { 401 } else {
564 if (!node->HasData()) 402 if (!node->HasData())
565 node->Load(); 403 node->Load();
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
684 } 522 }
685 523
686 void Rankings::WriteHead(List list) { 524 void Rankings::WriteHead(List list) {
687 control_data_->heads[list] = heads_[list].value(); 525 control_data_->heads[list] = heads_[list].value();
688 } 526 }
689 527
690 void Rankings::WriteTail(List list) { 528 void Rankings::WriteTail(List list) {
691 control_data_->tails[list] = tails_[list].value(); 529 control_data_->tails[list] = tails_[list].value();
692 } 530 }
693 531
532 bool Rankings::GetRanking(CacheRankingsBlock* rankings) {
533 if (!rankings->address().is_initialized())
534 return false;
535
536 TimeTicks start = TimeTicks::Now();
537 if (!rankings->Load())
538 return false;
539
540 if (!SanityCheck(rankings, true)) {
541 backend_->CriticalError(ERR_INVALID_LINKS);
542 return false;
543 }
544
545 backend_->OnEvent(Stats::OPEN_RANKINGS);
546
547 // "dummy" is the old "pointer" value, so it has to be 0.
548 if (!rankings->Data()->dirty && !rankings->Data()->dummy)
549 return true;
550
551 EntryImpl* entry = backend_->GetOpenEntry(rankings);
552 if (backend_->GetCurrentEntryId() != rankings->Data()->dirty || !entry) {
553 // We cannot trust this entry, but we cannot initiate a cleanup from this
554 // point (we may be in the middle of a cleanup already). Just get rid of
555 // the invalid pointer and continue; the entry will be deleted when detected
556 // from a regular open/create path.
557 rankings->Data()->dummy = 0;
558 rankings->Data()->dirty = backend_->GetCurrentEntryId() - 1;
559 if (!rankings->Data()->dirty)
560 rankings->Data()->dirty--;
561 return true;
562 }
563
564 // Note that we should not leave this module without deleting rankings first.
565 rankings->SetData(entry->rankings()->Data());
566
567 CACHE_UMA(AGE_MS, "GetRankings", 0, start);
568 return true;
569 }
570
571 void Rankings::ConvertToLongLived(CacheRankingsBlock* rankings) {
572 if (rankings->own_data())
573 return;
574
575 // We cannot return a shared node because we are not keeping a reference
576 // to the entry that owns the buffer. Make this node a copy of the one that
577 // we have, and let the iterator logic update it when the entry changes.
578 CacheRankingsBlock temp(NULL, Addr(0));
579 *temp.Data() = *rankings->Data();
580 rankings->StopSharingData();
581 *rankings->Data() = *temp.Data();
582 }
583
584 void Rankings::CompleteTransaction() {
585 Addr node_addr(static_cast<CacheAddr>(control_data_->transaction));
586 if (!node_addr.is_initialized() || node_addr.is_separate_file()) {
587 NOTREACHED();
588 LOG(ERROR) << "Invalid rankings info.";
589 return;
590 }
591
592 Trace("CompleteTransaction 0x%x", node_addr.value());
593
594 CacheRankingsBlock node(backend_->File(node_addr), node_addr);
595 if (!node.Load())
596 return;
597
598 node.Data()->dummy = 0;
599 node.Store();
600
601 Addr& my_head = heads_[control_data_->operation_list];
602 Addr& my_tail = tails_[control_data_->operation_list];
603
604 // We want to leave the node inside the list. The entry must me marked as
605 // dirty, and will be removed later. Otherwise, we'll get assertions when
606 // attempting to remove the dirty entry.
607 if (INSERT == control_data_->operation) {
608 Trace("FinishInsert h:0x%x t:0x%x", my_head.value(), my_tail.value());
609 FinishInsert(&node);
610 } else if (REMOVE == control_data_->operation) {
611 Trace("RevertRemove h:0x%x t:0x%x", my_head.value(), my_tail.value());
612 RevertRemove(&node);
613 } else {
614 NOTREACHED();
615 LOG(ERROR) << "Invalid operation to recover.";
616 }
617 }
618
619 void Rankings::FinishInsert(CacheRankingsBlock* node) {
620 control_data_->transaction = 0;
621 control_data_->operation = 0;
622 Addr& my_head = heads_[control_data_->operation_list];
623 Addr& my_tail = tails_[control_data_->operation_list];
624 if (my_head.value() != node->address().value()) {
625 if (my_tail.value() == node->address().value()) {
626 // This part will be skipped by the logic of Insert.
627 node->Data()->next = my_tail.value();
628 }
629
630 Insert(node, true, static_cast<List>(control_data_->operation_list));
631 }
632
633 // Tell the backend about this entry.
634 backend_->RecoveredEntry(node);
635 }
636
637 void Rankings::RevertRemove(CacheRankingsBlock* node) {
638 Addr next_addr(node->Data()->next);
639 Addr prev_addr(node->Data()->prev);
640 if (!next_addr.is_initialized() || !prev_addr.is_initialized()) {
641 // The operation actually finished. Nothing to do.
642 control_data_->transaction = 0;
643 return;
644 }
645 if (next_addr.is_separate_file() || prev_addr.is_separate_file()) {
646 NOTREACHED();
647 LOG(WARNING) << "Invalid rankings info.";
648 control_data_->transaction = 0;
649 return;
650 }
651
652 CacheRankingsBlock next(backend_->File(next_addr), next_addr);
653 CacheRankingsBlock prev(backend_->File(prev_addr), prev_addr);
654 if (!next.Load() || !prev.Load())
655 return;
656
657 CacheAddr node_value = node->address().value();
658 DCHECK(prev.Data()->next == node_value ||
659 prev.Data()->next == prev_addr.value() ||
660 prev.Data()->next == next.address().value());
661 DCHECK(next.Data()->prev == node_value ||
662 next.Data()->prev == next_addr.value() ||
663 next.Data()->prev == prev.address().value());
664
665 if (node_value != prev_addr.value())
666 prev.Data()->next = node_value;
667 if (node_value != next_addr.value())
668 next.Data()->prev = node_value;
669
670 List my_list = static_cast<List>(control_data_->operation_list);
671 Addr& my_head = heads_[my_list];
672 Addr& my_tail = tails_[my_list];
673 if (!my_head.is_initialized() || !my_tail.is_initialized()) {
674 my_head.set_value(node_value);
675 my_tail.set_value(node_value);
676 WriteHead(my_list);
677 WriteTail(my_list);
678 } else if (my_head.value() == next.address().value()) {
679 my_head.set_value(node_value);
680 prev.Data()->next = next.address().value();
681 WriteHead(my_list);
682 } else if (my_tail.value() == prev.address().value()) {
683 my_tail.set_value(node_value);
684 next.Data()->prev = prev.address().value();
685 WriteTail(my_list);
686 }
687
688 next.Store();
689 prev.Store();
690 control_data_->transaction = 0;
691 control_data_->operation = 0;
692 }
693
694 bool Rankings::CheckEntry(CacheRankingsBlock* rankings) { 694 bool Rankings::CheckEntry(CacheRankingsBlock* rankings) {
695 if (!rankings->Data()->dummy) 695 if (!rankings->Data()->dummy)
696 return true; 696 return true;
697 697
698 // If this entry is not dirty, it is a serious problem. 698 // If this entry is not dirty, it is a serious problem.
699 return backend_->GetCurrentEntryId() != rankings->Data()->dirty; 699 return backend_->GetCurrentEntryId() != rankings->Data()->dirty;
700 } 700 }
701 701
702 bool Rankings::CheckLinks(CacheRankingsBlock* node, CacheRankingsBlock* prev, 702 bool Rankings::CheckLinks(CacheRankingsBlock* node, CacheRankingsBlock* prev,
703 CacheRankingsBlock* next, List* list) { 703 CacheRankingsBlock* next, List* list) {
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 void Rankings::DecrementCounter(List list) { 853 void Rankings::DecrementCounter(List list) {
854 if (!count_lists_) 854 if (!count_lists_)
855 return; 855 return;
856 856
857 DCHECK(control_data_->sizes[list] > 0); 857 DCHECK(control_data_->sizes[list] > 0);
858 if (control_data_->sizes[list] > 0) 858 if (control_data_->sizes[list] > 0)
859 control_data_->sizes[list]--; 859 control_data_->sizes[list]--;
860 } 860 }
861 861
862 } // namespace disk_cache 862 } // namespace disk_cache
OLDNEW
« no previous file with comments | « net/disk_cache/mapped_file_posix.cc ('k') | net/disk_cache/stats.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698