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

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

Issue 8065015: Disk Cache: Improve handling of dirty entries. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 2 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/entry_impl.h" 5 #include "net/disk_cache/entry_impl.h"
6 6
7 #include "base/message_loop.h" 7 #include "base/message_loop.h"
8 #include "base/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "net/base/io_buffer.h" 10 #include "net/base/io_buffer.h"
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 DeleteData(address, index); 489 DeleteData(address, index);
490 } 490 }
491 } 491 }
492 492
493 if (!everything) 493 if (!everything)
494 return; 494 return;
495 495
496 // Remove all traces of this entry. 496 // Remove all traces of this entry.
497 backend_->RemoveEntry(this); 497 backend_->RemoveEntry(this);
498 498
499 // Note that at this point node_ and entry_ are just two blocks of data, and
500 // even if they reference each other, nobody should be referencing them.
501
499 Addr address(entry_.Data()->long_key); 502 Addr address(entry_.Data()->long_key);
500 DeleteData(address, kKeyFileIndex); 503 DeleteData(address, kKeyFileIndex);
501 backend_->ModifyStorageSize(entry_.Data()->key_len, 0); 504 backend_->ModifyStorageSize(entry_.Data()->key_len, 0);
502 505
503 memset(node_.buffer(), 0, node_.size()); 506 backend_->DeleteBlock(entry_.address(), true);
504 memset(entry_.buffer(), 0, entry_.size());
505 node_.Store();
506 entry_.Store();
507 507
508 backend_->DeleteBlock(node_.address(), false); 508 if (!LeaveRankingsBehind())
509 backend_->DeleteBlock(entry_.address(), false); 509 backend_->DeleteBlock(node_.address(), true);
510 } 510 }
511 511
512 CacheAddr EntryImpl::GetNextAddress() { 512 CacheAddr EntryImpl::GetNextAddress() {
513 return entry_.Data()->next; 513 return entry_.Data()->next;
514 } 514 }
515 515
516 void EntryImpl::SetNextAddress(Addr address) { 516 void EntryImpl::SetNextAddress(Addr address) {
517 DCHECK_NE(address.value(), entry_.address().value()); 517 DCHECK_NE(address.value(), entry_.address().value());
518 entry_.Data()->next = address.value(); 518 entry_.Data()->next = address.value();
519 bool success = entry_.Store(); 519 bool success = entry_.Store();
(...skipping 24 matching lines...) Expand all
544 544
545 void EntryImpl::SetDirtyFlag(int32 current_id) { 545 void EntryImpl::SetDirtyFlag(int32 current_id) {
546 DCHECK(node_.HasData()); 546 DCHECK(node_.HasData());
547 // We are checking if the entry is valid or not. If there is a pointer here, 547 // We are checking if the entry is valid or not. If there is a pointer here,
548 // we should not be checking the entry. 548 // we should not be checking the entry.
549 if (node_.Data()->dummy) 549 if (node_.Data()->dummy)
550 dirty_ = true; 550 dirty_ = true;
551 551
552 if (node_.Data()->dirty && current_id != node_.Data()->dirty) 552 if (node_.Data()->dirty && current_id != node_.Data()->dirty)
553 dirty_ = true; 553 dirty_ = true;
554
555 if (!current_id)
556 dirty_ = true;
554 } 557 }
555 558
556 void EntryImpl::SetPointerForInvalidEntry(int32 new_id) { 559 void EntryImpl::SetPointerForInvalidEntry(int32 new_id) {
557 node_.Data()->dirty = new_id; 560 node_.Data()->dirty = new_id;
558 node_.Data()->dummy = 0; 561 node_.Data()->dummy = 0;
559 node_.Store(); 562 node_.Store();
560 } 563 }
561 564
565 bool EntryImpl::LeaveRankingsBehind() {
566 return !node_.Data()->contents;
567 }
568
569 // This only includes checks that relate to the first block of the entry (the
570 // first 256 bytes), and values that should be set from the entry creation.
571 // Basically, even if there is something wrong with this entry, we want to see
572 // if it is possible to load the rankings node and delete them together.
562 bool EntryImpl::SanityCheck() { 573 bool EntryImpl::SanityCheck() {
563 EntryStore* stored = entry_.Data(); 574 EntryStore* stored = entry_.Data();
564 if (!stored->rankings_node || stored->key_len <= 0) 575 if (!stored->rankings_node || stored->key_len <= 0)
565 return false; 576 return false;
566 577
567 if (stored->reuse_count < 0 || stored->refetch_count < 0) 578 if (stored->reuse_count < 0 || stored->refetch_count < 0)
568 return false; 579 return false;
569 580
570 Addr rankings_addr(stored->rankings_node); 581 Addr rankings_addr(stored->rankings_node);
571 if (!rankings_addr.is_initialized() || rankings_addr.is_separate_file() || 582 if (!rankings_addr.is_initialized() || rankings_addr.is_separate_file() ||
572 rankings_addr.file_type() != RANKINGS) 583 rankings_addr.file_type() != RANKINGS || rankings_addr.num_blocks() != 1)
573 return false; 584 return false;
574 585
575 Addr next_addr(stored->next); 586 Addr next_addr(stored->next);
576 if (next_addr.is_initialized() && 587 if (next_addr.is_initialized() &&
577 (next_addr.is_separate_file() || next_addr.file_type() != BLOCK_256)) 588 (next_addr.is_separate_file() || next_addr.file_type() != BLOCK_256))
578 return false; 589 return false;
579 590
580 if (!rankings_addr.SanityCheck() || !next_addr.SanityCheck()) 591 if (!rankings_addr.SanityCheck() || !next_addr.SanityCheck())
581 return false; 592 return false;
582 593
(...skipping 10 matching lines...) Expand all
593 604
594 if (key_addr.is_initialized() && 605 if (key_addr.is_initialized() &&
595 ((stored->key_len <= kMaxBlockSize && key_addr.is_separate_file()) || 606 ((stored->key_len <= kMaxBlockSize && key_addr.is_separate_file()) ||
596 (stored->key_len > kMaxBlockSize && key_addr.is_block_file()))) 607 (stored->key_len > kMaxBlockSize && key_addr.is_block_file())))
597 return false; 608 return false;
598 609
599 int num_blocks = NumBlocksForEntry(stored->key_len); 610 int num_blocks = NumBlocksForEntry(stored->key_len);
600 if (entry_.address().num_blocks() != num_blocks) 611 if (entry_.address().num_blocks() != num_blocks)
601 return false; 612 return false;
602 613
614 return true;
615 }
616
617 bool EntryImpl::DataSanityCheck() {
618 EntryStore* stored = entry_.Data();
619 Addr key_addr(stored->long_key);
620
603 // The key must be NULL terminated. 621 // The key must be NULL terminated.
604 if (!key_addr.is_initialized() && stored->key[stored->key_len]) 622 if (!key_addr.is_initialized() && stored->key[stored->key_len])
605 return false; 623 return false;
606 624
607 if (stored->hash != Hash(GetKey())) 625 if (stored->hash != Hash(GetKey()))
608 return false; 626 return false;
609 627
610 for (int i = 0; i < kNumStreams; i++) { 628 for (int i = 0; i < kNumStreams; i++) {
611 Addr data_addr(stored->data_addr[i]); 629 Addr data_addr(stored->data_addr[i]);
612 int data_size = stored->data_size[i]; 630 int data_size = stored->data_size[i];
613 if (data_size < 0) 631 if (data_size < 0)
614 return false; 632 return false;
615 if (!data_size && data_addr.is_initialized()) 633 if (!data_size && data_addr.is_initialized())
616 return false; 634 return false;
617 if (!data_addr.SanityCheck()) 635 if (!data_addr.SanityCheck())
618 return false; 636 return false;
619 if (!data_size) 637 if (!data_size)
620 continue; 638 continue;
621 if (data_size <= kMaxBlockSize && data_addr.is_separate_file()) 639 if (data_size <= kMaxBlockSize && data_addr.is_separate_file())
622 return false; 640 return false;
623 if (data_size > kMaxBlockSize && data_addr.is_block_file()) 641 if (data_size > kMaxBlockSize && data_addr.is_block_file())
624 return false; 642 return false;
625 } 643 }
644 return true;
645 }
626 646
627 return true; 647 void EntryImpl::FixForDelete() {
648 EntryStore* stored = entry_.Data();
649 Addr key_addr(stored->long_key);
650
651 if (!key_addr.is_initialized())
652 stored->key[stored->key_len] = '\0';
653
654 for (int i = 0; i < kNumStreams; i++) {
655 Addr data_addr(stored->data_addr[i]);
656 int data_size = stored->data_size[i];
657 if (data_addr.is_initialized()) {
658 if ((data_size <= kMaxBlockSize && data_addr.is_separate_file()) ||
659 (data_size > kMaxBlockSize && data_addr.is_block_file()) ||
660 !data_addr.SanityCheck()) {
661 // The address is weird so don't attempt to delete it.
662 stored->data_addr[i] = 0;
663 // In general, trust the stored size as it should be in sync with the
664 // total size tracked by the backend.
665 }
666 }
667 if (data_size < 0)
668 stored->data_size[i] = 0;
669 }
670 entry_.Store();
628 } 671 }
629 672
630 void EntryImpl::IncrementIoCount() { 673 void EntryImpl::IncrementIoCount() {
631 backend_->IncrementIoCount(); 674 backend_->IncrementIoCount();
632 } 675 }
633 676
634 void EntryImpl::DecrementIoCount() { 677 void EntryImpl::DecrementIoCount() {
635 backend_->DecrementIoCount(); 678 backend_->DecrementIoCount();
636 } 679 }
637 680
(...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after
1426 Trace("%s 0x%p 0x%x 0x%x", msg, reinterpret_cast<void*>(this), 1469 Trace("%s 0x%p 0x%x 0x%x", msg, reinterpret_cast<void*>(this),
1427 entry_.address().value(), node_.address().value()); 1470 entry_.address().value(), node_.address().value());
1428 1471
1429 Trace(" data: 0x%x 0x%x 0x%x", entry_.Data()->data_addr[0], 1472 Trace(" data: 0x%x 0x%x 0x%x", entry_.Data()->data_addr[0],
1430 entry_.Data()->data_addr[1], entry_.Data()->long_key); 1473 entry_.Data()->data_addr[1], entry_.Data()->long_key);
1431 1474
1432 Trace(" doomed: %d 0x%x", doomed_, dirty); 1475 Trace(" doomed: %d 0x%x", doomed_, dirty);
1433 } 1476 }
1434 1477
1435 } // namespace disk_cache 1478 } // namespace disk_cache
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698