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 |