Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/backend_impl.h" | 5 #include "net/disk_cache/backend_impl.h" |
| 6 | 6 |
| 7 #include "base/file_path.h" | 7 #include "base/file_path.h" |
| 8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 9 #include "base/histogram.h" | 9 #include "base/histogram.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 419 IncreaseNumRefs(); | 419 IncreaseNumRefs(); |
| 420 | 420 |
| 421 if (!cache_entry->CreateEntry(node_address, key, hash)) { | 421 if (!cache_entry->CreateEntry(node_address, key, hash)) { |
| 422 block_files_.DeleteBlock(entry_address, false); | 422 block_files_.DeleteBlock(entry_address, false); |
| 423 block_files_.DeleteBlock(node_address, false); | 423 block_files_.DeleteBlock(node_address, false); |
| 424 LOG(ERROR) << "Create entry failed " << key.c_str(); | 424 LOG(ERROR) << "Create entry failed " << key.c_str(); |
| 425 stats_.OnEvent(Stats::CREATE_ERROR); | 425 stats_.OnEvent(Stats::CREATE_ERROR); |
| 426 return false; | 426 return false; |
| 427 } | 427 } |
| 428 | 428 |
| 429 // We are not failing the operation; let's add this to the map. | |
| 430 open_entries_[entry_address.value()] = cache_entry; | |
| 431 | |
| 429 if (parent.get()) | 432 if (parent.get()) |
| 430 parent->SetNextAddress(entry_address); | 433 parent->SetNextAddress(entry_address); |
| 431 | 434 |
| 432 block_files_.GetFile(entry_address)->Store(cache_entry->entry()); | 435 block_files_.GetFile(entry_address)->Store(cache_entry->entry()); |
| 433 block_files_.GetFile(node_address)->Store(cache_entry->rankings()); | 436 block_files_.GetFile(node_address)->Store(cache_entry->rankings()); |
| 434 | 437 |
| 435 IncreaseNumEntries(); | 438 IncreaseNumEntries(); |
| 436 eviction_.OnCreateEntry(cache_entry); | 439 eviction_.OnCreateEntry(cache_entry); |
| 437 if (!parent.get()) | 440 if (!parent.get()) |
| 438 data_->table[hash & mask_] = entry_address.value(); | 441 data_->table[hash & mask_] = entry_address.value(); |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 713 if (!new_eviction_) | 716 if (!new_eviction_) |
| 714 return; | 717 return; |
| 715 | 718 |
| 716 DCHECK(ENTRY_NORMAL != entry->entry()->Data()->state); | 719 DCHECK(ENTRY_NORMAL != entry->entry()->Data()->state); |
| 717 | 720 |
| 718 Trace("Remove entry 0x%p", entry); | 721 Trace("Remove entry 0x%p", entry); |
| 719 eviction_.OnDestroyEntry(entry); | 722 eviction_.OnDestroyEntry(entry); |
| 720 DecreaseNumEntries(); | 723 DecreaseNumEntries(); |
| 721 } | 724 } |
| 722 | 725 |
| 723 void BackendImpl::CacheEntryDestroyed() { | 726 void BackendImpl::CacheEntryDestroyed(Addr address) { |
| 727 EntriesMap::iterator it = open_entries_.find(address.value()); | |
|
Nicolas Sylvain
2009/07/07 17:47:14
why would it not be in the map? dirty maybe? shoul
rvargas (doing something else)
2009/07/07 18:13:24
Yes and no. We don't store dirty entries in the ma
| |
| 728 if (it != open_entries_.end()) | |
| 729 open_entries_.erase(it); | |
| 724 DecreaseNumRefs(); | 730 DecreaseNumRefs(); |
| 725 } | 731 } |
| 726 | 732 |
| 727 int32 BackendImpl::GetCurrentEntryId() { | 733 bool BackendImpl::IsOpen(CacheRankingsBlock* rankings) const { |
| 734 DCHECK(rankings->HasData()); | |
| 735 EntriesMap::const_iterator it = | |
| 736 open_entries_.find(rankings->Data()->contents); | |
| 737 if (it != open_entries_.end()) { | |
| 738 // We have this entry in memory. | |
| 739 return rankings->Data()->pointer == it->second; | |
| 740 } | |
| 741 | |
| 742 return false; | |
| 743 } | |
| 744 | |
| 745 int32 BackendImpl::GetCurrentEntryId() const { | |
| 728 return data_->header.this_id; | 746 return data_->header.this_id; |
| 729 } | 747 } |
| 730 | 748 |
| 731 int BackendImpl::MaxFileSize() const { | 749 int BackendImpl::MaxFileSize() const { |
| 732 return max_size_ / 8; | 750 return max_size_ / 8; |
| 733 } | 751 } |
| 734 | 752 |
| 735 void BackendImpl::ModifyStorageSize(int32 old_size, int32 new_size) { | 753 void BackendImpl::ModifyStorageSize(int32 old_size, int32 new_size) { |
| 736 if (disabled_ || old_size == new_size) | 754 if (disabled_ || old_size == new_size) |
| 737 return; | 755 return; |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1028 data_->header.crash = 0; | 1046 data_->header.crash = 0; |
| 1029 index_ = NULL; | 1047 index_ = NULL; |
| 1030 data_ = NULL; | 1048 data_ = NULL; |
| 1031 block_files_.CloseFiles(); | 1049 block_files_.CloseFiles(); |
| 1032 rankings_.Reset(); | 1050 rankings_.Reset(); |
| 1033 init_ = false; | 1051 init_ = false; |
| 1034 restarted_ = true; | 1052 restarted_ = true; |
| 1035 } | 1053 } |
| 1036 | 1054 |
| 1037 int BackendImpl::NewEntry(Addr address, EntryImpl** entry, bool* dirty) { | 1055 int BackendImpl::NewEntry(Addr address, EntryImpl** entry, bool* dirty) { |
| 1056 EntriesMap::iterator it = open_entries_.find(address.value()); | |
| 1057 if (it != open_entries_.end()) { | |
| 1058 // Easy job. This entry is already in memory. | |
| 1059 EntryImpl* this_entry = it->second; | |
| 1060 this_entry->AddRef(); | |
| 1061 *entry = this_entry; | |
| 1062 *dirty = false; | |
| 1063 return 0; | |
| 1064 } | |
| 1065 | |
| 1038 scoped_refptr<EntryImpl> cache_entry(new EntryImpl(this, address)); | 1066 scoped_refptr<EntryImpl> cache_entry(new EntryImpl(this, address)); |
| 1039 IncreaseNumRefs(); | 1067 IncreaseNumRefs(); |
| 1040 *entry = NULL; | 1068 *entry = NULL; |
| 1041 | 1069 |
| 1042 if (!address.is_initialized() || address.is_separate_file() || | 1070 if (!address.is_initialized() || address.is_separate_file() || |
| 1043 address.file_type() != BLOCK_256) { | 1071 address.file_type() != BLOCK_256) { |
| 1044 LOG(WARNING) << "Wrong entry address."; | 1072 LOG(WARNING) << "Wrong entry address."; |
| 1045 return ERR_INVALID_ADDRESS; | 1073 return ERR_INVALID_ADDRESS; |
| 1046 } | 1074 } |
| 1047 | 1075 |
| 1048 if (!cache_entry->entry()->Load()) | 1076 if (!cache_entry->entry()->Load()) |
| 1049 return ERR_READ_FAILURE; | 1077 return ERR_READ_FAILURE; |
| 1050 | 1078 |
| 1051 if (!cache_entry->SanityCheck()) { | 1079 if (!cache_entry->SanityCheck()) { |
| 1052 LOG(WARNING) << "Messed up entry found."; | 1080 LOG(WARNING) << "Messed up entry found."; |
| 1053 return ERR_INVALID_ENTRY; | 1081 return ERR_INVALID_ENTRY; |
| 1054 } | 1082 } |
| 1055 | 1083 |
| 1056 if (!cache_entry->LoadNodeAddress()) | 1084 if (!cache_entry->LoadNodeAddress()) |
| 1057 return ERR_READ_FAILURE; | 1085 return ERR_READ_FAILURE; |
| 1058 | 1086 |
| 1059 *dirty = cache_entry->IsDirty(GetCurrentEntryId()); | 1087 *dirty = cache_entry->IsDirty(GetCurrentEntryId()); |
| 1060 | 1088 |
| 1061 // Prevent overwriting the dirty flag on the destructor. | 1089 // Prevent overwriting the dirty flag on the destructor. |
| 1062 cache_entry->ClearDirtyFlag(); | 1090 cache_entry->ClearDirtyFlag(); |
| 1063 | 1091 |
| 1064 if (!rankings_.SanityCheck(cache_entry->rankings(), false)) | 1092 if (!rankings_.SanityCheck(cache_entry->rankings(), false)) |
| 1065 return ERR_INVALID_LINKS; | 1093 return ERR_INVALID_LINKS; |
| 1066 | 1094 |
| 1095 // We only add clean entries to the map. | |
| 1096 if (!*dirty) | |
| 1097 open_entries_[address.value()] = cache_entry; | |
| 1098 | |
| 1067 cache_entry.swap(entry); | 1099 cache_entry.swap(entry); |
| 1068 return 0; | 1100 return 0; |
| 1069 } | 1101 } |
| 1070 | 1102 |
| 1071 EntryImpl* BackendImpl::MatchEntry(const std::string& key, uint32 hash, | 1103 EntryImpl* BackendImpl::MatchEntry(const std::string& key, uint32 hash, |
| 1072 bool find_parent) { | 1104 bool find_parent) { |
| 1073 Addr address(data_->table[hash & mask_]); | 1105 Addr address(data_->table[hash & mask_]); |
| 1074 EntryImpl* cache_entry = NULL; | 1106 EntryImpl* cache_entry = NULL; |
| 1075 EntryImpl* parent_entry = NULL; | 1107 EntryImpl* parent_entry = NULL; |
| 1076 bool found = false; | 1108 bool found = false; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1112 } else { | 1144 } else { |
| 1113 Trace("NewEntry failed on MatchEntry 0x%x", address.value()); | 1145 Trace("NewEntry failed on MatchEntry 0x%x", address.value()); |
| 1114 } | 1146 } |
| 1115 | 1147 |
| 1116 // Restart the search. | 1148 // Restart the search. |
| 1117 address.set_value(data_->table[hash & mask_]); | 1149 address.set_value(data_->table[hash & mask_]); |
| 1118 continue; | 1150 continue; |
| 1119 } | 1151 } |
| 1120 | 1152 |
| 1121 if (cache_entry->IsSameEntry(key, hash)) { | 1153 if (cache_entry->IsSameEntry(key, hash)) { |
| 1122 cache_entry = EntryImpl::Update(cache_entry); | 1154 if (!cache_entry->Update()) { |
| 1155 cache_entry->Release(); | |
| 1156 cache_entry = NULL; | |
| 1157 } | |
| 1123 found = true; | 1158 found = true; |
| 1124 break; | 1159 break; |
| 1125 } | 1160 } |
| 1126 cache_entry = EntryImpl::Update(cache_entry); | 1161 if (!cache_entry->Update()) { |
| 1162 cache_entry->Release(); | |
| 1163 cache_entry = NULL; | |
|
Nicolas Sylvain
2009/07/07 17:47:14
do you really need this here? since you do it belo
rvargas (doing something else)
2009/07/07 18:13:24
if I don't set it to null, we'll copy an invalid p
| |
| 1164 } | |
| 1127 if (parent_entry) | 1165 if (parent_entry) |
| 1128 parent_entry->Release(); | 1166 parent_entry->Release(); |
| 1129 parent_entry = cache_entry; | 1167 parent_entry = cache_entry; |
| 1130 cache_entry = NULL; | 1168 cache_entry = NULL; |
| 1131 if (!parent_entry) | 1169 if (!parent_entry) |
| 1132 break; | 1170 break; |
| 1133 | 1171 |
| 1134 address.set_value(parent_entry->GetNextAddress()); | 1172 address.set_value(parent_entry->GetNextAddress()); |
| 1135 } | 1173 } |
| 1136 | 1174 |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1272 // path and take the appropriate action. | 1310 // path and take the appropriate action. |
| 1273 std::string key = entry->GetKey(); | 1311 std::string key = entry->GetKey(); |
| 1274 uint32 hash = entry->GetHash(); | 1312 uint32 hash = entry->GetHash(); |
| 1275 entry = NULL; // Release the entry. | 1313 entry = NULL; // Release the entry. |
| 1276 temp = MatchEntry(key, hash, false); | 1314 temp = MatchEntry(key, hash, false); |
| 1277 if (temp) | 1315 if (temp) |
| 1278 temp->Release(); | 1316 temp->Release(); |
| 1279 | 1317 |
| 1280 return NULL; | 1318 return NULL; |
| 1281 } | 1319 } |
| 1320 if (!entry->Update()) | |
| 1321 return NULL; | |
| 1282 | 1322 |
| 1283 entry.swap(&temp); | 1323 entry.swap(&temp); |
| 1284 return EntryImpl::Update(temp); // Update returns an adref'd entry. | 1324 return temp; |
| 1285 } | 1325 } |
| 1286 | 1326 |
| 1287 bool BackendImpl::ResurrectEntry(EntryImpl* deleted_entry, Entry** entry) { | 1327 bool BackendImpl::ResurrectEntry(EntryImpl* deleted_entry, Entry** entry) { |
| 1288 if (ENTRY_NORMAL == deleted_entry->entry()->Data()->state) { | 1328 if (ENTRY_NORMAL == deleted_entry->entry()->Data()->state) { |
| 1289 deleted_entry->Release(); | 1329 deleted_entry->Release(); |
| 1290 stats_.OnEvent(Stats::CREATE_MISS); | 1330 stats_.OnEvent(Stats::CREATE_MISS); |
| 1291 Trace("create entry miss "); | 1331 Trace("create entry miss "); |
| 1292 return false; | 1332 return false; |
| 1293 } | 1333 } |
| 1294 | 1334 |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1533 | 1573 |
| 1534 return num_dirty; | 1574 return num_dirty; |
| 1535 } | 1575 } |
| 1536 | 1576 |
| 1537 bool BackendImpl::CheckEntry(EntryImpl* cache_entry) { | 1577 bool BackendImpl::CheckEntry(EntryImpl* cache_entry) { |
| 1538 RankingsNode* rankings = cache_entry->rankings()->Data(); | 1578 RankingsNode* rankings = cache_entry->rankings()->Data(); |
| 1539 return !rankings->pointer; | 1579 return !rankings->pointer; |
| 1540 } | 1580 } |
| 1541 | 1581 |
| 1542 } // namespace disk_cache | 1582 } // namespace disk_cache |
| OLD | NEW |