| 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_util.h" |     7 #include "base/file_util.h" | 
|     8 #include "base/histogram.h" |     8 #include "base/histogram.h" | 
|     9 #include "base/message_loop.h" |     9 #include "base/message_loop.h" | 
|    10 #include "base/string_util.h" |    10 #include "base/string_util.h" | 
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   425       return true; |   425       return true; | 
|   426     } |   426     } | 
|   427  |   427  | 
|   428     entry->Doom(); |   428     entry->Doom(); | 
|   429     entry->Close(); |   429     entry->Close(); | 
|   430     EndEnumeration(&iter);  // Dooming the entry invalidates the iterator. |   430     EndEnumeration(&iter);  // Dooming the entry invalidates the iterator. | 
|   431   } |   431   } | 
|   432 } |   432 } | 
|   433  |   433  | 
|   434 bool BackendImpl::OpenNextEntry(void** iter, Entry** next_entry) { |   434 bool BackendImpl::OpenNextEntry(void** iter, Entry** next_entry) { | 
|   435   if (disabled_) |   435   return OpenFollowingEntry(true, iter, next_entry); | 
|   436     return false; |  | 
|   437  |  | 
|   438   Rankings::ScopedRankingsBlock rankings(&rankings_, |  | 
|   439       reinterpret_cast<CacheRankingsBlock*>(*iter)); |  | 
|   440   Rankings::ScopedRankingsBlock next(&rankings_, |  | 
|   441                                      rankings_.GetNext(rankings.get())); |  | 
|   442   *next_entry = NULL; |  | 
|   443   *iter = NULL; |  | 
|   444   if (!next.get()) |  | 
|   445     return false; |  | 
|   446  |  | 
|   447   scoped_refptr<EntryImpl> entry; |  | 
|   448   if (next->Data()->pointer) { |  | 
|   449     entry = reinterpret_cast<EntryImpl*>(next->Data()->pointer); |  | 
|   450   } else { |  | 
|   451     bool dirty; |  | 
|   452     EntryImpl* temp = NULL; |  | 
|   453     if (NewEntry(Addr(next->Data()->contents), &temp, &dirty)) |  | 
|   454       return false; |  | 
|   455     entry.swap(&temp); |  | 
|   456  |  | 
|   457     if (dirty) { |  | 
|   458       // We cannot trust this entry. Call MatchEntry to go through the regular |  | 
|   459       // path and take the appropriate action. |  | 
|   460       std::string key = entry->GetKey(); |  | 
|   461       uint32 hash = entry->GetHash(); |  | 
|   462       entry = NULL;  // Release the entry. |  | 
|   463       temp = MatchEntry(key, hash, false); |  | 
|   464       if (temp) |  | 
|   465         temp->Release(); |  | 
|   466  |  | 
|   467       return false; |  | 
|   468     } |  | 
|   469  |  | 
|   470     entry.swap(&temp); |  | 
|   471     temp = EntryImpl::Update(temp);  // Update returns an adref'd entry. |  | 
|   472     entry.swap(&temp); |  | 
|   473     if (!entry.get()) |  | 
|   474       return false; |  | 
|   475   } |  | 
|   476  |  | 
|   477   entry.swap(reinterpret_cast<EntryImpl**>(next_entry)); |  | 
|   478   *iter = next.release(); |  | 
|   479   return true; |  | 
|   480 } |   436 } | 
|   481  |   437  | 
|   482 void BackendImpl::EndEnumeration(void** iter) { |   438 void BackendImpl::EndEnumeration(void** iter) { | 
|   483   Rankings::ScopedRankingsBlock rankings(&rankings_, |   439   Rankings::ScopedRankingsBlock rankings(&rankings_, | 
|   484       reinterpret_cast<CacheRankingsBlock*>(*iter)); |   440       reinterpret_cast<CacheRankingsBlock*>(*iter)); | 
|   485   *iter = NULL; |   441   *iter = NULL; | 
|   486 } |   442 } | 
|   487  |   443  | 
|   488 void BackendImpl::GetStats(StatsItems* stats) { |   444 void BackendImpl::GetStats(StatsItems* stats) { | 
|   489   if (disabled_) |   445   if (disabled_) | 
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   540 MappedFile* BackendImpl::File(Addr address) { |   496 MappedFile* BackendImpl::File(Addr address) { | 
|   541   if (disabled_) |   497   if (disabled_) | 
|   542     return NULL; |   498     return NULL; | 
|   543   return block_files_.GetFile(address); |   499   return block_files_.GetFile(address); | 
|   544 } |   500 } | 
|   545  |   501  | 
|   546 bool BackendImpl::CreateExternalFile(Addr* address) { |   502 bool BackendImpl::CreateExternalFile(Addr* address) { | 
|   547   int file_number = data_->header.last_file + 1; |   503   int file_number = data_->header.last_file + 1; | 
|   548   Addr file_address(0); |   504   Addr file_address(0); | 
|   549   bool success = false; |   505   bool success = false; | 
|   550   for (int i = 0; (i < 0x0fffffff) && !success; i++, file_number++) { |   506   for (int i = 0; i < 0x0fffffff; i++, file_number++) { | 
|   551     if (!file_address.SetFileNumber(file_number)) { |   507     if (!file_address.SetFileNumber(file_number)) { | 
|   552       file_number = 1; |   508       file_number = 1; | 
|   553       continue; |   509       continue; | 
|   554     } |   510     } | 
|   555     std::wstring name = GetFileName(file_address); |   511     std::wstring name = GetFileName(file_address); | 
|   556     int flags = base::PLATFORM_FILE_READ | |   512     int flags = base::PLATFORM_FILE_READ | | 
|   557                 base::PLATFORM_FILE_WRITE |  |   513                 base::PLATFORM_FILE_WRITE |  | 
|   558                 base::PLATFORM_FILE_CREATE |  |   514                 base::PLATFORM_FILE_CREATE |  | 
|   559                 base::PLATFORM_FILE_EXCLUSIVE_WRITE; |   515                 base::PLATFORM_FILE_EXCLUSIVE_WRITE; | 
|   560     scoped_refptr<disk_cache::File> file(new disk_cache::File( |   516     scoped_refptr<disk_cache::File> file(new disk_cache::File( | 
|   561         base::CreatePlatformFile(name.c_str(), flags, NULL))); |   517         base::CreatePlatformFile(name.c_str(), flags, NULL))); | 
|   562     if (!file->IsValid()) |   518     if (!file->IsValid()) | 
|   563       continue; |   519       continue; | 
|   564  |   520  | 
|   565     success = true; |   521     success = true; | 
 |   522     break; | 
|   566   } |   523   } | 
|   567  |   524  | 
|   568   DCHECK(success); |   525   DCHECK(success); | 
|   569   if (!success) |   526   if (!success) | 
|   570     return false; |   527     return false; | 
|   571  |   528  | 
|   572   data_->header.last_file = file_number; |   529   data_->header.last_file = file_number; | 
|   573   address->set_value(file_address.value()); |   530   address->set_value(file_address.value()); | 
|   574   return true; |   531   return true; | 
|   575 } |   532 } | 
|   576  |   533  | 
|   577 bool BackendImpl::CreateBlock(FileType block_type, int block_count, |   534 bool BackendImpl::CreateBlock(FileType block_type, int block_count, | 
|   578                              Addr* block_address) { |   535                              Addr* block_address) { | 
|   579   return block_files_.CreateBlock(block_type, block_count, block_address); |   536   return block_files_.CreateBlock(block_type, block_count, block_address); | 
|   580 } |   537 } | 
|   581  |   538  | 
|   582 void BackendImpl::DeleteBlock(Addr block_address, bool deep) { |   539 void BackendImpl::DeleteBlock(Addr block_address, bool deep) { | 
|   583   block_files_.DeleteBlock(block_address, deep); |   540   block_files_.DeleteBlock(block_address, deep); | 
|   584 } |   541 } | 
|   585  |   542  | 
|   586 void BackendImpl::UpdateRank(CacheRankingsBlock* node, bool modified) { |   543 void BackendImpl::UpdateRank(CacheRankingsBlock* node, bool modified) { | 
|   587   rankings_.UpdateRank(node, modified); |   544   if (!read_only_) | 
 |   545     rankings_.UpdateRank(node, modified); | 
|   588 } |   546 } | 
|   589  |   547  | 
|   590 void BackendImpl::RecoveredEntry(CacheRankingsBlock* rankings) { |   548 void BackendImpl::RecoveredEntry(CacheRankingsBlock* rankings) { | 
|   591   Addr address(rankings->Data()->contents); |   549   Addr address(rankings->Data()->contents); | 
|   592   EntryImpl* cache_entry = NULL; |   550   EntryImpl* cache_entry = NULL; | 
|   593   bool dirty; |   551   bool dirty; | 
|   594   if (NewEntry(address, &cache_entry, &dirty)) |   552   if (NewEntry(address, &cache_entry, &dirty)) | 
|   595     return; |   553     return; | 
|   596  |   554  | 
|   597   uint32 hash = cache_entry->GetHash(); |   555   uint32 hash = cache_entry->GetHash(); | 
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   701 } |   659 } | 
|   702  |   660  | 
|   703 void BackendImpl::DecrementIoCount() { |   661 void BackendImpl::DecrementIoCount() { | 
|   704   num_pending_io_--; |   662   num_pending_io_--; | 
|   705 } |   663 } | 
|   706  |   664  | 
|   707 void BackendImpl::SetUnitTestMode() { |   665 void BackendImpl::SetUnitTestMode() { | 
|   708   unit_test_ = true; |   666   unit_test_ = true; | 
|   709 } |   667 } | 
|   710  |   668  | 
 |   669 void BackendImpl::SetUpgradeMode() { | 
 |   670   read_only_ = true; | 
 |   671 } | 
 |   672  | 
|   711 void BackendImpl::ClearRefCountForTest() { |   673 void BackendImpl::ClearRefCountForTest() { | 
|   712   num_refs_ = 0; |   674   num_refs_ = 0; | 
|   713 } |   675 } | 
|   714  |   676  | 
|   715 int BackendImpl::SelfCheck() { |   677 int BackendImpl::SelfCheck() { | 
|   716   if (!init_) { |   678   if (!init_) { | 
|   717     LOG(ERROR) << "Init failed"; |   679     LOG(ERROR) << "Init failed"; | 
|   718     return ERR_INIT_FAILED; |   680     return ERR_INIT_FAILED; | 
|   719   } |   681   } | 
|   720  |   682  | 
|   721   int num_entries = rankings_.SelfCheck(); |   683   int num_entries = rankings_.SelfCheck(); | 
|   722   if (num_entries < 0) { |   684   if (num_entries < 0) { | 
|   723     LOG(ERROR) << "Invalid rankings list, error " << num_entries; |   685     LOG(ERROR) << "Invalid rankings list, error " << num_entries; | 
|   724     return num_entries; |   686     return num_entries; | 
|   725   } |   687   } | 
|   726  |   688  | 
|   727   if (num_entries != data_->header.num_entries) { |   689   if (num_entries != data_->header.num_entries) { | 
|   728     LOG(ERROR) << "Number of entries mismatch"; |   690     LOG(ERROR) << "Number of entries mismatch"; | 
|   729     return ERR_NUM_ENTRIES_MISMATCH; |   691     return ERR_NUM_ENTRIES_MISMATCH; | 
|   730   } |   692   } | 
|   731  |   693  | 
|   732   return CheckAllEntries(); |   694   return CheckAllEntries(); | 
|   733 } |   695 } | 
|   734  |   696  | 
 |   697 bool BackendImpl::OpenPrevEntry(void** iter, Entry** prev_entry) { | 
 |   698   return OpenFollowingEntry(false, iter, prev_entry); | 
 |   699 } | 
 |   700  | 
|   735 // ------------------------------------------------------------------------ |   701 // ------------------------------------------------------------------------ | 
|   736  |   702  | 
|   737 // We just created a new file so we're going to write the header and set the |   703 // We just created a new file so we're going to write the header and set the | 
|   738 // file length to include the hash table (zero filled). |   704 // file length to include the hash table (zero filled). | 
|   739 bool BackendImpl::CreateBackingStore(disk_cache::File* file) { |   705 bool BackendImpl::CreateBackingStore(disk_cache::File* file) { | 
|   740   AdjustMaxCacheSize(0); |   706   AdjustMaxCacheSize(0); | 
|   741  |   707  | 
|   742   IndexHeader header; |   708   IndexHeader header; | 
|   743   header.table_len = DesiredIndexTableLen(max_size_); |   709   header.table_len = DesiredIndexTableLen(max_size_); | 
|   744  |   710  | 
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   859   cache_entry->ClearDirtyFlag(); |   825   cache_entry->ClearDirtyFlag(); | 
|   860  |   826  | 
|   861   if (!rankings_.SanityCheck(cache_entry->rankings(), false)) |   827   if (!rankings_.SanityCheck(cache_entry->rankings(), false)) | 
|   862     return ERR_INVALID_LINKS; |   828     return ERR_INVALID_LINKS; | 
|   863  |   829  | 
|   864   cache_entry.swap(entry); |   830   cache_entry.swap(entry); | 
|   865   return 0; |   831   return 0; | 
|   866 } |   832 } | 
|   867  |   833  | 
|   868 EntryImpl* BackendImpl::MatchEntry(const std::string& key, uint32 hash, |   834 EntryImpl* BackendImpl::MatchEntry(const std::string& key, uint32 hash, | 
|   869                                      bool find_parent) { |   835                                    bool find_parent) { | 
|   870   Addr address(data_->table[hash & mask_]); |   836   Addr address(data_->table[hash & mask_]); | 
|   871   EntryImpl* cache_entry = NULL; |   837   EntryImpl* cache_entry = NULL; | 
|   872   EntryImpl* parent_entry = NULL; |   838   EntryImpl* parent_entry = NULL; | 
|   873   bool found = false; |   839   bool found = false; | 
|   874  |   840  | 
|   875   for (;;) { |   841   for (;;) { | 
|   876     if (disabled_) |   842     if (disabled_) | 
|   877       break; |   843       break; | 
|   878  |   844  | 
|   879     if (!address.is_initialized()) { |   845     if (!address.is_initialized()) { | 
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   937   } |   903   } | 
|   938  |   904  | 
|   939   if (cache_entry && (find_parent || !found)) { |   905   if (cache_entry && (find_parent || !found)) { | 
|   940     cache_entry->Release(); |   906     cache_entry->Release(); | 
|   941     cache_entry = NULL; |   907     cache_entry = NULL; | 
|   942   } |   908   } | 
|   943  |   909  | 
|   944   return find_parent ? parent_entry : cache_entry; |   910   return find_parent ? parent_entry : cache_entry; | 
|   945 } |   911 } | 
|   946  |   912  | 
 |   913 // This is the actual implementation for OpenNextEntry and OpenPrevEntry. | 
 |   914 bool BackendImpl::OpenFollowingEntry(bool forward, void** iter, | 
 |   915                                      Entry** next_entry) { | 
 |   916   if (disabled_) | 
 |   917     return false; | 
 |   918  | 
 |   919   Rankings::ScopedRankingsBlock rankings(&rankings_, | 
 |   920       reinterpret_cast<CacheRankingsBlock*>(*iter)); | 
 |   921   CacheRankingsBlock* next_block = forward ? rankings_.GetNext(rankings.get()) : | 
 |   922                                              rankings_.GetPrev(rankings.get()); | 
 |   923   Rankings::ScopedRankingsBlock next(&rankings_, next_block); | 
 |   924   *next_entry = NULL; | 
 |   925   *iter = NULL; | 
 |   926   if (!next.get()) | 
 |   927     return false; | 
 |   928  | 
 |   929   scoped_refptr<EntryImpl> entry; | 
 |   930   if (next->Data()->pointer) { | 
 |   931     entry = reinterpret_cast<EntryImpl*>(next->Data()->pointer); | 
 |   932   } else { | 
 |   933     bool dirty; | 
 |   934     EntryImpl* temp = NULL; | 
 |   935     if (NewEntry(Addr(next->Data()->contents), &temp, &dirty)) | 
 |   936       return false; | 
 |   937     entry.swap(&temp); | 
 |   938  | 
 |   939     if (dirty) { | 
 |   940       // We cannot trust this entry. Call MatchEntry to go through the regular | 
 |   941       // path and take the appropriate action. | 
 |   942       std::string key = entry->GetKey(); | 
 |   943       uint32 hash = entry->GetHash(); | 
 |   944       entry = NULL;  // Release the entry. | 
 |   945       temp = MatchEntry(key, hash, false); | 
 |   946       if (temp) | 
 |   947         temp->Release(); | 
 |   948  | 
 |   949       return false; | 
 |   950     } | 
 |   951  | 
 |   952     entry.swap(&temp); | 
 |   953     temp = EntryImpl::Update(temp);  // Update returns an adref'd entry. | 
 |   954     entry.swap(&temp); | 
 |   955     if (!entry.get()) | 
 |   956       return false; | 
 |   957   } | 
 |   958  | 
 |   959   entry.swap(reinterpret_cast<EntryImpl**>(next_entry)); | 
 |   960   *iter = next.release(); | 
 |   961   return true; | 
 |   962 } | 
 |   963  | 
|   947 void BackendImpl::DestroyInvalidEntry(Addr address, EntryImpl* entry) { |   964 void BackendImpl::DestroyInvalidEntry(Addr address, EntryImpl* entry) { | 
|   948   LOG(WARNING) << "Destroying invalid entry."; |   965   LOG(WARNING) << "Destroying invalid entry."; | 
|   949   Trace("Destroying invalid entry 0x%p", entry); |   966   Trace("Destroying invalid entry 0x%p", entry); | 
|   950  |   967  | 
|   951   rankings_.Remove(entry->rankings()); |   968   rankings_.Remove(entry->rankings()); | 
|   952   entry->SetPointerForInvalidEntry(GetCurrentEntryId()); |   969   entry->SetPointerForInvalidEntry(GetCurrentEntryId()); | 
|   953  |   970  | 
|   954   entry->InternalDoom(); |   971   entry->InternalDoom(); | 
|   955  |   972  | 
|   956   data_->header.num_entries--; |   973   data_->header.num_entries--; | 
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1126  |  1143  | 
|  1127   return num_dirty; |  1144   return num_dirty; | 
|  1128 } |  1145 } | 
|  1129  |  1146  | 
|  1130 bool BackendImpl::CheckEntry(EntryImpl* cache_entry) { |  1147 bool BackendImpl::CheckEntry(EntryImpl* cache_entry) { | 
|  1131   RankingsNode* rankings = cache_entry->rankings()->Data(); |  1148   RankingsNode* rankings = cache_entry->rankings()->Data(); | 
|  1132   return !rankings->pointer; |  1149   return !rankings->pointer; | 
|  1133 } |  1150 } | 
|  1134  |  1151  | 
|  1135 }  // namespace disk_cache |  1152 }  // namespace disk_cache | 
| OLD | NEW |