Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Side by Side Diff: net/disk_cache/backend_impl.cc

Issue 261045: Start migrating the disk cache to using FilePath. (Closed)
Patch Set: rebase Created 11 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/disk_cache/backend_impl.h ('k') | net/disk_cache/backend_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/field_trial.h" 7 #include "base/field_trial.h"
8 #include "base/file_path.h" 8 #include "base/file_path.h"
9 #include "base/file_util.h" 9 #include "base/file_util.h"
10 #include "base/histogram.h" 10 #include "base/histogram.h"
(...skipping 11 matching lines...) Expand all
22 22
23 // This has to be defined before including histogram_macros.h from this file. 23 // This has to be defined before including histogram_macros.h from this file.
24 #define NET_DISK_CACHE_BACKEND_IMPL_CC_ 24 #define NET_DISK_CACHE_BACKEND_IMPL_CC_
25 #include "net/disk_cache/histogram_macros.h" 25 #include "net/disk_cache/histogram_macros.h"
26 26
27 using base::Time; 27 using base::Time;
28 using base::TimeDelta; 28 using base::TimeDelta;
29 29
30 namespace { 30 namespace {
31 31
32 const wchar_t* kIndexName = L"index"; 32 const char* kIndexName = "index";
33 const int kMaxOldFolders = 100; 33 const int kMaxOldFolders = 100;
34 34
35 // Seems like ~240 MB correspond to less than 50k entries for 99% of the people. 35 // Seems like ~240 MB correspond to less than 50k entries for 99% of the people.
36 const int k64kEntriesStore = 240 * 1000 * 1000; 36 const int k64kEntriesStore = 240 * 1000 * 1000;
37 const int kBaseTableLen = 64 * 1024; 37 const int kBaseTableLen = 64 * 1024;
38 const int kDefaultCacheSize = 80 * 1024 * 1024; 38 const int kDefaultCacheSize = 80 * 1024 * 1024;
39 39
40 int DesiredIndexTableLen(int32 storage_size) { 40 int DesiredIndexTableLen(int32 storage_size) {
41 if (storage_size <= k64kEntriesStore) 41 if (storage_size <= k64kEntriesStore)
42 return kBaseTableLen; 42 return kBaseTableLen;
(...skipping 15 matching lines...) Expand all
58 size_t GetIndexSize(int table_len) { 58 size_t GetIndexSize(int table_len) {
59 size_t table_size = sizeof(disk_cache::CacheAddr) * table_len; 59 size_t table_size = sizeof(disk_cache::CacheAddr) * table_len;
60 return sizeof(disk_cache::IndexHeader) + table_size; 60 return sizeof(disk_cache::IndexHeader) + table_size;
61 } 61 }
62 62
63 // ------------------------------------------------------------------------ 63 // ------------------------------------------------------------------------
64 64
65 // Returns a fully qualified name from path and name, using a given name prefix 65 // Returns a fully qualified name from path and name, using a given name prefix
66 // and index number. For instance, if the arguments are "/foo", "bar" and 5, it 66 // and index number. For instance, if the arguments are "/foo", "bar" and 5, it
67 // will return "/foo/old_bar_005". 67 // will return "/foo/old_bar_005".
68 std::wstring GetPrefixedName(const std::wstring& path, const std::wstring& name, 68 FilePath GetPrefixedName(const FilePath& path, const std::string& name,
69 int index) { 69 int index) {
70 std::wstring prefixed(path); 70 std::string tmp = StringPrintf("%s%s_%03d", "old_", name.c_str(), index);
71 std::wstring tmp = StringPrintf(L"%ls%ls_%03d", L"old_", name.c_str(), index); 71 return path.AppendASCII(tmp);
72 file_util::AppendToPath(&prefixed, tmp);
73 return prefixed;
74 } 72 }
75 73
76 // This is a simple Task to cleanup old caches. 74 // This is a simple Task to cleanup old caches.
77 class CleanupTask : public Task { 75 class CleanupTask : public Task {
78 public: 76 public:
79 CleanupTask(const std::wstring& path, const std::wstring& name) 77 CleanupTask(const FilePath& path, const std::string& name)
80 : path_(path), name_(name) {} 78 : path_(path), name_(name) {}
81 79
82 virtual void Run(); 80 virtual void Run();
83 81
84 private: 82 private:
85 std::wstring path_; 83 FilePath path_;
86 std::wstring name_; 84 std::string name_;
87 DISALLOW_EVIL_CONSTRUCTORS(CleanupTask); 85 DISALLOW_EVIL_CONSTRUCTORS(CleanupTask);
88 }; 86 };
89 87
90 void CleanupTask::Run() { 88 void CleanupTask::Run() {
91 for (int i = 0; i < kMaxOldFolders; i++) { 89 for (int i = 0; i < kMaxOldFolders; i++) {
92 std::wstring to_delete = GetPrefixedName(path_, name_, i); 90 FilePath to_delete = GetPrefixedName(path_, name_, i);
93 disk_cache::DeleteCache(to_delete, true); 91 disk_cache::DeleteCache(to_delete, true);
94 } 92 }
95 } 93 }
96 94
97 // Returns a full path to rename the current cache, in order to delete it. path 95 // Returns a full path to rename the current cache, in order to delete it. path
98 // is the current folder location, and name is the current folder name. 96 // is the current folder location, and name is the current folder name.
99 std::wstring GetTempCacheName(const std::wstring& path, 97 FilePath GetTempCacheName(const FilePath& path, const std::string& name) {
100 const std::wstring& name) {
101 // We'll attempt to have up to kMaxOldFolders folders for deletion. 98 // We'll attempt to have up to kMaxOldFolders folders for deletion.
102 for (int i = 0; i < kMaxOldFolders; i++) { 99 for (int i = 0; i < kMaxOldFolders; i++) {
103 std::wstring to_delete = GetPrefixedName(path, name, i); 100 FilePath to_delete = GetPrefixedName(path, name, i);
104 if (!file_util::PathExists(to_delete)) 101 if (!file_util::PathExists(to_delete))
105 return to_delete; 102 return to_delete;
106 } 103 }
107 return std::wstring(); 104 return FilePath();
108 } 105 }
109 106
110 // Moves the cache files to a new folder and creates a task to delete them. 107 // Moves the cache files to a new folder and creates a task to delete them.
111 bool DelayedCacheCleanup(const std::wstring& full_path) { 108 bool DelayedCacheCleanup(const FilePath& full_path) {
112 FilePath current_path = FilePath::FromWStringHack(full_path); 109 FilePath current_path = full_path.StripTrailingSeparators();
113 current_path = current_path.StripTrailingSeparators();
114 110
115 std::wstring path = current_path.DirName().ToWStringHack(); 111 FilePath path = current_path.DirName();
116 std::wstring name = current_path.BaseName().ToWStringHack(); 112 FilePath name = current_path.BaseName();
113 #if defined(OS_POSIX)
114 std::string name_str = name.value();
115 #elif defined(OS_WIN)
116 // We created this file so it should only contain ASCII.
117 std::string name_str = WideToASCII(name.value());
118 #endif
117 119
118 std::wstring to_delete = GetTempCacheName(path, name); 120 FilePath to_delete = GetTempCacheName(path, name_str);
119 if (to_delete.empty()) { 121 if (to_delete.empty()) {
120 LOG(ERROR) << "Unable to get another cache folder"; 122 LOG(ERROR) << "Unable to get another cache folder";
121 return false; 123 return false;
122 } 124 }
123 125
124 if (!disk_cache::MoveCache(full_path.c_str(), to_delete.c_str())) { 126 if (!disk_cache::MoveCache(full_path, to_delete)) {
125 LOG(ERROR) << "Unable to rename cache folder"; 127 LOG(ERROR) << "Unable to rename cache folder";
126 return false; 128 return false;
127 } 129 }
128 130
129 #if defined(OS_WIN) 131 #if defined(OS_WIN)
130 WorkerPool::PostTask(FROM_HERE, new CleanupTask(path, name), true); 132 WorkerPool::PostTask(FROM_HERE, new CleanupTask(path, name_str), true);
131 #elif defined(OS_POSIX) 133 #elif defined(OS_POSIX)
132 // TODO(rvargas): Use the worker pool. 134 // TODO(rvargas): Use the worker pool.
133 MessageLoop::current()->PostTask(FROM_HERE, new CleanupTask(path, name)); 135 MessageLoop::current()->PostTask(FROM_HERE, new CleanupTask(path, name_str));
134 #endif 136 #endif
135 return true; 137 return true;
136 } 138 }
137 139
138 // Sets |current_group| for the current experiment. Returns false if the files 140 // Sets |current_group| for the current experiment. Returns false if the files
139 // should be discarded. 141 // should be discarded.
140 bool InitExperiment(int* current_group) { 142 bool InitExperiment(int* current_group) {
141 if (*current_group == 3 || *current_group == 4) { 143 if (*current_group == 3 || *current_group == 4) {
142 // Discard current cache for groups 3 and 4. 144 // Discard current cache for groups 3 and 4.
143 return false; 145 return false;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 // number, (located on the same parent folder), and spawn a worker thread to 210 // number, (located on the same parent folder), and spawn a worker thread to
209 // delete all the files on all the stale cache folders. The whole process can 211 // delete all the files on all the stale cache folders. The whole process can
210 // still fail if we are not able to rename the cache folder (for instance due to 212 // still fail if we are not able to rename the cache folder (for instance due to
211 // a sharing violation), and in that case a cache for this profile (on the 213 // a sharing violation), and in that case a cache for this profile (on the
212 // desired path) cannot be created. 214 // desired path) cannot be created.
213 // 215 //
214 // Static. 216 // Static.
215 Backend* BackendImpl::CreateBackend(const std::wstring& full_path, bool force, 217 Backend* BackendImpl::CreateBackend(const std::wstring& full_path, bool force,
216 int max_bytes, net::CacheType type, 218 int max_bytes, net::CacheType type,
217 BackendFlags flags) { 219 BackendFlags flags) {
218 BackendImpl* cache = new BackendImpl(full_path); 220 FilePath full_cache_path = FilePath::FromWStringHack(full_path);
221 BackendImpl* cache = new BackendImpl(full_cache_path);
219 cache->SetMaxSize(max_bytes); 222 cache->SetMaxSize(max_bytes);
220 cache->SetType(type); 223 cache->SetType(type);
221 cache->SetFlags(flags); 224 cache->SetFlags(flags);
222 if (cache->Init()) 225 if (cache->Init())
223 return cache; 226 return cache;
224 227
225 delete cache; 228 delete cache;
226 if (!force) 229 if (!force)
227 return NULL; 230 return NULL;
228 231
229 if (!DelayedCacheCleanup(full_path)) 232 if (!DelayedCacheCleanup(full_cache_path))
230 return NULL; 233 return NULL;
231 234
232 // The worker thread will start deleting files soon, but the original folder 235 // The worker thread will start deleting files soon, but the original folder
233 // is not there anymore... let's create a new set of files. 236 // is not there anymore... let's create a new set of files.
234 cache = new BackendImpl(full_path); 237 cache = new BackendImpl(full_cache_path);
235 cache->SetMaxSize(max_bytes); 238 cache->SetMaxSize(max_bytes);
236 cache->SetType(type); 239 cache->SetType(type);
237 cache->SetFlags(flags); 240 cache->SetFlags(flags);
238 if (cache->Init()) 241 if (cache->Init())
239 return cache; 242 return cache;
240 243
241 delete cache; 244 delete cache;
242 LOG(ERROR) << "Unable to create cache"; 245 LOG(ERROR) << "Unable to create cache";
243 return NULL; 246 return NULL;
244 } 247 }
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 // but that triggers strict aliasing problems with gcc. 474 // but that triggers strict aliasing problems with gcc.
472 EntryImpl* entry_impl = reinterpret_cast<EntryImpl*>(entry); 475 EntryImpl* entry_impl = reinterpret_cast<EntryImpl*>(entry);
473 entry_impl->Doom(); 476 entry_impl->Doom();
474 entry_impl->Release(); 477 entry_impl->Release();
475 return true; 478 return true;
476 } 479 }
477 480
478 bool BackendImpl::DoomAllEntries() { 481 bool BackendImpl::DoomAllEntries() {
479 if (!num_refs_) { 482 if (!num_refs_) {
480 PrepareForRestart(); 483 PrepareForRestart();
481 DeleteCache(path_.c_str(), false); 484 DeleteCache(path_, false);
482 return Init(); 485 return Init();
483 } else { 486 } else {
484 if (disabled_) 487 if (disabled_)
485 return false; 488 return false;
486 489
487 eviction_.TrimCache(true); 490 eviction_.TrimCache(true);
488 stats_.OnEvent(Stats::DOOM_CACHE); 491 stats_.OnEvent(Stats::DOOM_CACHE);
489 return true; 492 return true;
490 } 493 }
491 } 494 }
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 user_flags_ |= kMaxSize; 606 user_flags_ |= kMaxSize;
604 max_size_ = max_bytes; 607 max_size_ = max_bytes;
605 return true; 608 return true;
606 } 609 }
607 610
608 void BackendImpl::SetType(net::CacheType type) { 611 void BackendImpl::SetType(net::CacheType type) {
609 DCHECK(type != net::MEMORY_CACHE); 612 DCHECK(type != net::MEMORY_CACHE);
610 cache_type_ = type; 613 cache_type_ = type;
611 } 614 }
612 615
613 std::wstring BackendImpl::GetFileName(Addr address) const { 616 FilePath BackendImpl::GetFileName(Addr address) const {
614 if (!address.is_separate_file() || !address.is_initialized()) { 617 if (!address.is_separate_file() || !address.is_initialized()) {
615 NOTREACHED(); 618 NOTREACHED();
616 return std::wstring(); 619 return FilePath();
617 } 620 }
618 621
619 std::wstring name(path_); 622 std::string tmp = StringPrintf("f_%06x", address.FileNumber());
620 std::wstring tmp = StringPrintf(L"f_%06x", address.FileNumber()); 623 return path_.AppendASCII(tmp);
621 file_util::AppendToPath(&name, tmp);
622 return name;
623 } 624 }
624 625
625 MappedFile* BackendImpl::File(Addr address) { 626 MappedFile* BackendImpl::File(Addr address) {
626 if (disabled_) 627 if (disabled_)
627 return NULL; 628 return NULL;
628 return block_files_.GetFile(address); 629 return block_files_.GetFile(address);
629 } 630 }
630 631
631 bool BackendImpl::CreateExternalFile(Addr* address) { 632 bool BackendImpl::CreateExternalFile(Addr* address) {
632 int file_number = data_->header.last_file + 1; 633 int file_number = data_->header.last_file + 1;
633 Addr file_address(0); 634 Addr file_address(0);
634 bool success = false; 635 bool success = false;
635 for (int i = 0; i < 0x0fffffff; i++, file_number++) { 636 for (int i = 0; i < 0x0fffffff; i++, file_number++) {
636 if (!file_address.SetFileNumber(file_number)) { 637 if (!file_address.SetFileNumber(file_number)) {
637 file_number = 1; 638 file_number = 1;
638 continue; 639 continue;
639 } 640 }
640 std::wstring name = GetFileName(file_address); 641 FilePath name = GetFileName(file_address);
641 int flags = base::PLATFORM_FILE_READ | 642 int flags = base::PLATFORM_FILE_READ |
642 base::PLATFORM_FILE_WRITE | 643 base::PLATFORM_FILE_WRITE |
643 base::PLATFORM_FILE_CREATE | 644 base::PLATFORM_FILE_CREATE |
644 base::PLATFORM_FILE_EXCLUSIVE_WRITE; 645 base::PLATFORM_FILE_EXCLUSIVE_WRITE;
645 scoped_refptr<disk_cache::File> file(new disk_cache::File( 646 scoped_refptr<disk_cache::File> file(new disk_cache::File(
646 base::CreatePlatformFile(name.c_str(), flags, NULL))); 647 base::CreatePlatformFile(name.ToWStringHack().c_str(), flags, NULL)));
647 if (!file->IsValid()) 648 if (!file->IsValid())
648 continue; 649 continue;
649 650
650 success = true; 651 success = true;
651 break; 652 break;
652 } 653 }
653 654
654 DCHECK(success); 655 DCHECK(success);
655 if (!success) 656 if (!success)
656 return false; 657 return false;
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
981 982
982 if (!file->Write(&header, sizeof(header), 0)) 983 if (!file->Write(&header, sizeof(header), 0))
983 return false; 984 return false;
984 985
985 return file->SetLength(GetIndexSize(header.table_len)); 986 return file->SetLength(GetIndexSize(header.table_len));
986 } 987 }
987 988
988 bool BackendImpl::InitBackingStore(bool* file_created) { 989 bool BackendImpl::InitBackingStore(bool* file_created) {
989 file_util::CreateDirectory(path_); 990 file_util::CreateDirectory(path_);
990 991
991 std::wstring index_name(path_); 992 FilePath index_name = path_.AppendASCII(kIndexName);
992 file_util::AppendToPath(&index_name, kIndexName);
993 993
994 int flags = base::PLATFORM_FILE_READ | 994 int flags = base::PLATFORM_FILE_READ |
995 base::PLATFORM_FILE_WRITE | 995 base::PLATFORM_FILE_WRITE |
996 base::PLATFORM_FILE_OPEN_ALWAYS | 996 base::PLATFORM_FILE_OPEN_ALWAYS |
997 base::PLATFORM_FILE_EXCLUSIVE_WRITE; 997 base::PLATFORM_FILE_EXCLUSIVE_WRITE;
998 scoped_refptr<disk_cache::File> file(new disk_cache::File( 998 scoped_refptr<disk_cache::File> file(new disk_cache::File(
999 base::CreatePlatformFile(index_name.c_str(), flags, file_created))); 999 base::CreatePlatformFile(index_name.ToWStringHack().c_str(), flags,
1000 file_created)));
1000 1001
1001 if (!file->IsValid()) 1002 if (!file->IsValid())
1002 return false; 1003 return false;
1003 1004
1004 bool ret = true; 1005 bool ret = true;
1005 if (*file_created) 1006 if (*file_created)
1006 ret = CreateBackingStore(file); 1007 ret = CreateBackingStore(file);
1007 1008
1008 file = NULL; 1009 file = NULL;
1009 if (!ret) 1010 if (!ret)
1010 return false; 1011 return false;
1011 1012
1012 index_ = new MappedFile(); 1013 index_ = new MappedFile();
1013 data_ = reinterpret_cast<Index*>(index_->Init(index_name, 0)); 1014 data_ = reinterpret_cast<Index*>(index_->Init(index_name.ToWStringHack(), 0));
1014 if (!data_) { 1015 if (!data_) {
1015 LOG(ERROR) << "Unable to map Index file"; 1016 LOG(ERROR) << "Unable to map Index file";
1016 return false; 1017 return false;
1017 } 1018 }
1018 return true; 1019 return true;
1019 } 1020 }
1020 1021
1021 // The maximum cache size will be either set explicitly by the caller, or 1022 // The maximum cache size will be either set explicitly by the caller, or
1022 // calculated by this code. 1023 // calculated by this code.
1023 void BackendImpl::AdjustMaxCacheSize(int table_len) { 1024 void BackendImpl::AdjustMaxCacheSize(int table_len) {
1024 if (max_size_) 1025 if (max_size_)
1025 return; 1026 return;
1026 1027
1027 // If table_len is provided, the index file exists. 1028 // If table_len is provided, the index file exists.
1028 DCHECK(!table_len || data_->header.magic); 1029 DCHECK(!table_len || data_->header.magic);
1029 1030
1030 // The user is not setting the size, let's figure it out. 1031 // The user is not setting the size, let's figure it out.
1031 int64 available = base::SysInfo::AmountOfFreeDiskSpace(path_); 1032 int64 available = base::SysInfo::AmountOfFreeDiskSpace(path_.ToWStringHack());
1032 if (available < 0) { 1033 if (available < 0) {
1033 max_size_ = kDefaultCacheSize; 1034 max_size_ = kDefaultCacheSize;
1034 return; 1035 return;
1035 } 1036 }
1036 1037
1037 if (table_len) 1038 if (table_len)
1038 available += data_->header.num_bytes; 1039 available += data_->header.num_bytes;
1039 1040
1040 max_size_ = PreferedCacheSize(available); 1041 max_size_ = PreferedCacheSize(available);
1041 1042
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after
1619 1620
1620 return num_dirty; 1621 return num_dirty;
1621 } 1622 }
1622 1623
1623 bool BackendImpl::CheckEntry(EntryImpl* cache_entry) { 1624 bool BackendImpl::CheckEntry(EntryImpl* cache_entry) {
1624 RankingsNode* rankings = cache_entry->rankings()->Data(); 1625 RankingsNode* rankings = cache_entry->rankings()->Data();
1625 return !rankings->dummy; 1626 return !rankings->dummy;
1626 } 1627 }
1627 1628
1628 } // namespace disk_cache 1629 } // namespace disk_cache
OLDNEW
« no previous file with comments | « net/disk_cache/backend_impl.h ('k') | net/disk_cache/backend_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698