Chromium Code Reviews| 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 |