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 <limits> | 7 #include <limits> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
533 // We have an entry already. It could be the one we are looking for, or just | 533 // We have an entry already. It could be the one we are looking for, or just |
534 // a hash conflict. | 534 // a hash conflict. |
535 bool error; | 535 bool error; |
536 EntryImpl* old_entry = MatchEntry(key, hash, false, Addr(), &error); | 536 EntryImpl* old_entry = MatchEntry(key, hash, false, Addr(), &error); |
537 if (old_entry) | 537 if (old_entry) |
538 return ResurrectEntry(old_entry); | 538 return ResurrectEntry(old_entry); |
539 | 539 |
540 EntryImpl* parent_entry = MatchEntry(key, hash, true, Addr(), &error); | 540 EntryImpl* parent_entry = MatchEntry(key, hash, true, Addr(), &error); |
541 DCHECK(!error); | 541 DCHECK(!error); |
542 if (parent_entry) { | 542 if (parent_entry) { |
543 parent.swap(&parent_entry); | 543 parent = make_scoped_refptr(parent_entry); |
544 parent_entry->Release(); | |
dcheng
2017/03/02 18:40:19
Is there any chance we can fix the //net code to j
tzik
2017/03/02 19:26:28
Agree. It's very hard to read even for writing sma
jkarlin
2017/03/03 15:30:32
+1
| |
544 } else if (data_->table[hash & mask_]) { | 545 } else if (data_->table[hash & mask_]) { |
545 // We should have corrected the problem. | 546 // We should have corrected the problem. |
546 NOTREACHED(); | 547 NOTREACHED(); |
547 return NULL; | 548 return NULL; |
548 } | 549 } |
549 } | 550 } |
550 | 551 |
551 // The general flow is to allocate disk space and initialize the entry data, | 552 // The general flow is to allocate disk space and initialize the entry data, |
552 // followed by saving that to disk, then linking the entry though the index | 553 // followed by saving that to disk, then linking the entry though the index |
553 // and finally through the lists. If there is a crash in this process, we may | 554 // and finally through the lists. If there is a crash in this process, we may |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
625 scoped_refptr<EntryImpl> entries[kListsToSearch]; | 626 scoped_refptr<EntryImpl> entries[kListsToSearch]; |
626 if (!iterator->my_rankings) { | 627 if (!iterator->my_rankings) { |
627 iterator->my_rankings = &rankings_; | 628 iterator->my_rankings = &rankings_; |
628 bool ret = false; | 629 bool ret = false; |
629 | 630 |
630 // Get an entry from each list. | 631 // Get an entry from each list. |
631 for (int i = 0; i < kListsToSearch; i++) { | 632 for (int i = 0; i < kListsToSearch; i++) { |
632 EntryImpl* temp = NULL; | 633 EntryImpl* temp = NULL; |
633 ret |= OpenFollowingEntryFromList(static_cast<Rankings::List>(i), | 634 ret |= OpenFollowingEntryFromList(static_cast<Rankings::List>(i), |
634 &iterator->nodes[i], &temp); | 635 &iterator->nodes[i], &temp); |
635 entries[i].swap(&temp); // The entry was already addref'd. | 636 if (temp) { |
637 // The entry was already addref'd. | |
638 entries[i] = make_scoped_refptr(temp); | |
639 temp->Release(); | |
640 } | |
636 } | 641 } |
637 if (!ret) { | 642 if (!ret) { |
638 iterator->Reset(); | 643 iterator->Reset(); |
639 return NULL; | 644 return NULL; |
640 } | 645 } |
641 } else { | 646 } else { |
642 // Get the next entry from the last list, and the actual entries for the | 647 // Get the next entry from the last list, and the actual entries for the |
643 // elements on the other lists. | 648 // elements on the other lists. |
644 for (int i = 0; i < kListsToSearch; i++) { | 649 for (int i = 0; i < kListsToSearch; i++) { |
645 EntryImpl* temp = NULL; | 650 EntryImpl* temp = NULL; |
646 if (iterator->list == i) { | 651 if (iterator->list == i) { |
647 OpenFollowingEntryFromList( | 652 OpenFollowingEntryFromList( |
648 iterator->list, &iterator->nodes[i], &temp); | 653 iterator->list, &iterator->nodes[i], &temp); |
649 } else { | 654 } else { |
650 temp = GetEnumeratedEntry(iterator->nodes[i], | 655 temp = GetEnumeratedEntry(iterator->nodes[i], |
651 static_cast<Rankings::List>(i)); | 656 static_cast<Rankings::List>(i)); |
652 } | 657 } |
653 | 658 |
654 entries[i].swap(&temp); // The entry was already addref'd. | 659 if (temp) { |
660 // The entry was already addref'd. | |
661 entries[i] = make_scoped_refptr(temp); | |
662 temp->Release(); | |
663 } | |
655 } | 664 } |
656 } | 665 } |
657 | 666 |
658 int newest = -1; | 667 int newest = -1; |
659 int oldest = -1; | 668 int oldest = -1; |
660 Time access_times[kListsToSearch]; | 669 Time access_times[kListsToSearch]; |
661 for (int i = 0; i < kListsToSearch; i++) { | 670 for (int i = 0; i < kListsToSearch; i++) { |
662 if (entries[i].get()) { | 671 if (entries[i].get()) { |
663 access_times[i] = entries[i]->GetLastUsed(); | 672 access_times[i] = entries[i]->GetLastUsed(); |
664 if (newest < 0) { | 673 if (newest < 0) { |
(...skipping 934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1599 cache_entry->SetDirtyFlag(GetCurrentEntryId()); | 1608 cache_entry->SetDirtyFlag(GetCurrentEntryId()); |
1600 | 1609 |
1601 if (cache_entry->dirty()) { | 1610 if (cache_entry->dirty()) { |
1602 Trace("Dirty entry 0x%p 0x%x", reinterpret_cast<void*>(cache_entry.get()), | 1611 Trace("Dirty entry 0x%p 0x%x", reinterpret_cast<void*>(cache_entry.get()), |
1603 address.value()); | 1612 address.value()); |
1604 } | 1613 } |
1605 | 1614 |
1606 open_entries_[address.value()] = cache_entry.get(); | 1615 open_entries_[address.value()] = cache_entry.get(); |
1607 | 1616 |
1608 cache_entry->BeginLogging(net_log_, false); | 1617 cache_entry->BeginLogging(net_log_, false); |
1609 cache_entry.swap(entry); | 1618 *entry = cache_entry.get(); |
1619 (*entry)->AddRef(); | |
1610 return 0; | 1620 return 0; |
1611 } | 1621 } |
1612 | 1622 |
1613 EntryImpl* BackendImpl::MatchEntry(const std::string& key, | 1623 EntryImpl* BackendImpl::MatchEntry(const std::string& key, |
1614 uint32_t hash, | 1624 uint32_t hash, |
1615 bool find_parent, | 1625 bool find_parent, |
1616 Addr entry_addr, | 1626 Addr entry_addr, |
1617 bool* match_error) { | 1627 bool* match_error) { |
1618 Addr address(data_->table[hash & mask_]); | 1628 Addr address(data_->table[hash & mask_]); |
1619 scoped_refptr<EntryImpl> cache_entry, parent_entry; | 1629 scoped_refptr<EntryImpl> cache_entry, parent_entry; |
1620 EntryImpl* tmp = NULL; | |
1621 bool found = false; | 1630 bool found = false; |
1622 std::set<CacheAddr> visited; | 1631 std::set<CacheAddr> visited; |
1623 *match_error = false; | 1632 *match_error = false; |
1624 | 1633 |
1625 for (;;) { | 1634 for (;;) { |
1635 DCHECK(!cache_entry); | |
1636 | |
1626 if (disabled_) | 1637 if (disabled_) |
1627 break; | 1638 break; |
1628 | 1639 |
1629 if (visited.find(address.value()) != visited.end()) { | 1640 if (visited.find(address.value()) != visited.end()) { |
1630 // It's possible for a buggy version of the code to write a loop. Just | 1641 // It's possible for a buggy version of the code to write a loop. Just |
1631 // break it. | 1642 // break it. |
1632 Trace("Hash collision loop 0x%x", address.value()); | 1643 Trace("Hash collision loop 0x%x", address.value()); |
1633 address.set_value(0); | 1644 address.set_value(0); |
1634 parent_entry->SetNextAddress(address); | 1645 parent_entry->SetNextAddress(address); |
1635 } | 1646 } |
1636 visited.insert(address.value()); | 1647 visited.insert(address.value()); |
1637 | 1648 |
1638 if (!address.is_initialized()) { | 1649 if (!address.is_initialized()) { |
1639 if (find_parent) | 1650 if (find_parent) |
1640 found = true; | 1651 found = true; |
1641 break; | 1652 break; |
1642 } | 1653 } |
1643 | 1654 |
1655 EntryImpl* tmp = nullptr; | |
1644 int error = NewEntry(address, &tmp); | 1656 int error = NewEntry(address, &tmp); |
1645 cache_entry.swap(&tmp); | 1657 if (!error) { |
1658 cache_entry = make_scoped_refptr(tmp); | |
1659 tmp->Release(); | |
1660 } | |
1646 | 1661 |
1647 if (error || cache_entry->dirty()) { | 1662 if (error || cache_entry->dirty()) { |
1648 // This entry is dirty on disk (it was not properly closed): we cannot | 1663 // This entry is dirty on disk (it was not properly closed): we cannot |
1649 // trust it. | 1664 // trust it. |
1650 Addr child(0); | 1665 Addr child(0); |
1651 if (!error) | 1666 if (!error) |
1652 child.set_value(cache_entry->GetNextAddress()); | 1667 child.set_value(cache_entry->GetNextAddress()); |
1653 | 1668 |
1654 if (parent_entry.get()) { | 1669 if (parent_entry.get()) { |
1655 parent_entry->SetNextAddress(child); | 1670 parent_entry->SetNextAddress(child); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1702 parent_entry = NULL; | 1717 parent_entry = NULL; |
1703 | 1718 |
1704 if (find_parent && entry_addr.is_initialized() && !cache_entry.get()) { | 1719 if (find_parent && entry_addr.is_initialized() && !cache_entry.get()) { |
1705 *match_error = true; | 1720 *match_error = true; |
1706 parent_entry = NULL; | 1721 parent_entry = NULL; |
1707 } | 1722 } |
1708 | 1723 |
1709 if (cache_entry.get() && (find_parent || !found)) | 1724 if (cache_entry.get() && (find_parent || !found)) |
1710 cache_entry = NULL; | 1725 cache_entry = NULL; |
1711 | 1726 |
1727 EntryImpl* tmp = NULL; | |
1712 if (find_parent) | 1728 if (find_parent) |
1713 parent_entry.swap(&tmp); | 1729 tmp = parent_entry.get(); |
1714 else | 1730 else |
1715 cache_entry.swap(&tmp); | 1731 tmp = cache_entry.get(); |
1732 | |
1733 if (tmp) | |
1734 tmp->AddRef(); | |
1716 | 1735 |
1717 FlushIndex(); | 1736 FlushIndex(); |
1718 return tmp; | 1737 return tmp; |
1719 } | 1738 } |
1720 | 1739 |
1721 bool BackendImpl::OpenFollowingEntryFromList(Rankings::List list, | 1740 bool BackendImpl::OpenFollowingEntryFromList(Rankings::List list, |
1722 CacheRankingsBlock** from_entry, | 1741 CacheRankingsBlock** from_entry, |
1723 EntryImpl** next_entry) { | 1742 EntryImpl** next_entry) { |
1724 if (disabled_) | 1743 if (disabled_) |
1725 return false; | 1744 return false; |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2053 if (!address.is_initialized()) | 2072 if (!address.is_initialized()) |
2054 continue; | 2073 continue; |
2055 for (;;) { | 2074 for (;;) { |
2056 EntryImpl* tmp; | 2075 EntryImpl* tmp; |
2057 int ret = NewEntry(address, &tmp); | 2076 int ret = NewEntry(address, &tmp); |
2058 if (ret) { | 2077 if (ret) { |
2059 STRESS_NOTREACHED(); | 2078 STRESS_NOTREACHED(); |
2060 return ret; | 2079 return ret; |
2061 } | 2080 } |
2062 scoped_refptr<EntryImpl> cache_entry; | 2081 scoped_refptr<EntryImpl> cache_entry; |
2063 cache_entry.swap(&tmp); | 2082 cache_entry = make_scoped_refptr(tmp); |
2083 tmp->Release(); | |
2064 | 2084 |
2065 if (cache_entry->dirty()) | 2085 if (cache_entry->dirty()) |
2066 num_dirty++; | 2086 num_dirty++; |
2067 else if (CheckEntry(cache_entry.get())) | 2087 else if (CheckEntry(cache_entry.get())) |
2068 num_entries++; | 2088 num_entries++; |
2069 else | 2089 else |
2070 return ERR_INVALID_ENTRY; | 2090 return ERR_INVALID_ENTRY; |
2071 | 2091 |
2072 DCHECK_EQ(i, cache_entry->entry()->Data()->hash & mask_); | 2092 DCHECK_EQ(i, cache_entry->entry()->Data()->hash & mask_); |
2073 address.set_value(cache_entry->GetNextAddress()); | 2093 address.set_value(cache_entry->GetNextAddress()); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2114 if (total_memory > kMaxBuffersSize || total_memory <= 0) | 2134 if (total_memory > kMaxBuffersSize || total_memory <= 0) |
2115 total_memory = kMaxBuffersSize; | 2135 total_memory = kMaxBuffersSize; |
2116 | 2136 |
2117 done = true; | 2137 done = true; |
2118 } | 2138 } |
2119 | 2139 |
2120 return static_cast<int>(total_memory); | 2140 return static_cast<int>(total_memory); |
2121 } | 2141 } |
2122 | 2142 |
2123 } // namespace disk_cache | 2143 } // namespace disk_cache |
OLD | NEW |