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 "components/drive/file_cache.h" | 5 #include "components/drive/file_cache.h" |
6 | 6 |
7 #include <queue> | 7 #include <queue> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
12 #include "base/callback_helpers.h" | 12 #include "base/callback_helpers.h" |
13 #include "base/files/file_enumerator.h" | 13 #include "base/files/file_enumerator.h" |
14 #include "base/files/file_util.h" | 14 #include "base/files/file_util.h" |
15 #include "base/location.h" | 15 #include "base/location.h" |
16 #include "base/logging.h" | 16 #include "base/logging.h" |
17 #include "base/metrics/histogram.h" | 17 #include "base/metrics/histogram.h" |
18 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
19 #include "base/strings/stringprintf.h" | 19 #include "base/strings/stringprintf.h" |
20 #include "base/sys_info.h" | 20 #include "base/sys_info.h" |
| 21 #include "build/build_config.h" |
21 #include "components/drive/drive.pb.h" | 22 #include "components/drive/drive.pb.h" |
22 #include "components/drive/drive_api_util.h" | 23 #include "components/drive/drive_api_util.h" |
23 #include "components/drive/file_system_core_util.h" | 24 #include "components/drive/file_system_core_util.h" |
24 #include "components/drive/resource_metadata_storage.h" | 25 #include "components/drive/resource_metadata_storage.h" |
25 #include "google_apis/drive/task_util.h" | 26 #include "google_apis/drive/task_util.h" |
26 #include "net/base/filename_util.h" | 27 #include "net/base/filename_util.h" |
27 #include "net/base/mime_sniffer.h" | 28 #include "net/base/mime_sniffer.h" |
28 #include "net/base/mime_util.h" | 29 #include "net/base/mime_util.h" |
29 | 30 |
30 namespace drive { | 31 namespace drive { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 } | 80 } |
80 | 81 |
81 void FileCache::AssertOnSequencedWorkerPool() { | 82 void FileCache::AssertOnSequencedWorkerPool() { |
82 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); | 83 DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread()); |
83 } | 84 } |
84 | 85 |
85 bool FileCache::IsUnderFileCacheDirectory(const base::FilePath& path) const { | 86 bool FileCache::IsUnderFileCacheDirectory(const base::FilePath& path) const { |
86 return cache_file_directory_.IsParent(path); | 87 return cache_file_directory_.IsParent(path); |
87 } | 88 } |
88 | 89 |
89 bool FileCache::FreeDiskSpaceIfNeededFor(int64 num_bytes) { | 90 bool FileCache::FreeDiskSpaceIfNeededFor(int64_t num_bytes) { |
90 AssertOnSequencedWorkerPool(); | 91 AssertOnSequencedWorkerPool(); |
91 | 92 |
92 // Do nothing and return if we have enough space. | 93 // Do nothing and return if we have enough space. |
93 if (GetAvailableSpace() >= num_bytes) | 94 if (GetAvailableSpace() >= num_bytes) |
94 return true; | 95 return true; |
95 | 96 |
96 // Otherwise, try to free up the disk space. | 97 // Otherwise, try to free up the disk space. |
97 DVLOG(1) << "Freeing up disk space for " << num_bytes; | 98 DVLOG(1) << "Freeing up disk space for " << num_bytes; |
98 | 99 |
99 // Remove all files which have no corresponding cache entries. | 100 // Remove all files which have no corresponding cache entries. |
100 base::FileEnumerator enumerator(cache_file_directory_, | 101 base::FileEnumerator enumerator(cache_file_directory_, |
101 false, // not recursive | 102 false, // not recursive |
102 base::FileEnumerator::FILES); | 103 base::FileEnumerator::FILES); |
103 ResourceEntry entry; | 104 ResourceEntry entry; |
104 for (base::FilePath current = enumerator.Next(); !current.empty(); | 105 for (base::FilePath current = enumerator.Next(); !current.empty(); |
105 current = enumerator.Next()) { | 106 current = enumerator.Next()) { |
106 const std::string id = GetIdFromPath(current); | 107 const std::string id = GetIdFromPath(current); |
107 const FileError error = storage_->GetEntry(id, &entry); | 108 const FileError error = storage_->GetEntry(id, &entry); |
108 | 109 |
109 if (error == FILE_ERROR_NOT_FOUND) | 110 if (error == FILE_ERROR_NOT_FOUND) |
110 base::DeleteFile(current, false /* recursive */); | 111 base::DeleteFile(current, false /* recursive */); |
111 else if (error != FILE_ERROR_OK) | 112 else if (error != FILE_ERROR_OK) |
112 return false; | 113 return false; |
113 } | 114 } |
114 | 115 |
115 // Check available space again. If we have enough space here, do nothing. | 116 // Check available space again. If we have enough space here, do nothing. |
116 const int64 available_space = GetAvailableSpace(); | 117 const int64_t available_space = GetAvailableSpace(); |
117 if (available_space >= num_bytes) | 118 if (available_space >= num_bytes) |
118 return true; | 119 return true; |
119 | 120 |
120 const int64 requested_space = num_bytes - available_space; | 121 const int64_t requested_space = num_bytes - available_space; |
121 | 122 |
122 // Put all entries in priority queue where latest entry becomes top. | 123 // Put all entries in priority queue where latest entry becomes top. |
123 std::priority_queue<CacheInfo, std::vector<CacheInfo>, CacheInfoLatestCompare> | 124 std::priority_queue<CacheInfo, std::vector<CacheInfo>, CacheInfoLatestCompare> |
124 cache_info_queue; | 125 cache_info_queue; |
125 scoped_ptr<ResourceMetadataStorage::Iterator> it = storage_->GetIterator(); | 126 scoped_ptr<ResourceMetadataStorage::Iterator> it = storage_->GetIterator(); |
126 for (; !it->IsAtEnd(); it->Advance()) { | 127 for (; !it->IsAtEnd(); it->Advance()) { |
127 if (IsEvictable(it->GetID(), it->GetValue())) { | 128 if (IsEvictable(it->GetID(), it->GetValue())) { |
128 const ResourceEntry& entry = it->GetValue(); | 129 const ResourceEntry& entry = it->GetValue(); |
129 | 130 |
130 const base::FilePath& cache_path = GetCacheFilePath(entry.local_id()); | 131 const base::FilePath& cache_path = GetCacheFilePath(entry.local_id()); |
(...skipping 20 matching lines...) Expand all Loading... |
151 return false; | 152 return false; |
152 | 153 |
153 // Copy entries to the vector. This becomes last-accessed desc order. | 154 // Copy entries to the vector. This becomes last-accessed desc order. |
154 std::vector<CacheInfo> cache_info_list; | 155 std::vector<CacheInfo> cache_info_list; |
155 while (!cache_info_queue.empty()) { | 156 while (!cache_info_queue.empty()) { |
156 cache_info_list.push_back(cache_info_queue.top()); | 157 cache_info_list.push_back(cache_info_queue.top()); |
157 cache_info_queue.pop(); | 158 cache_info_queue.pop(); |
158 } | 159 } |
159 | 160 |
160 // Update DB and delete files with accessing to the vector in ascending order. | 161 // Update DB and delete files with accessing to the vector in ascending order. |
161 int64 evicted_cache_size = 0; | 162 int64_t evicted_cache_size = 0; |
162 auto iter = cache_info_list.rbegin(); | 163 auto iter = cache_info_list.rbegin(); |
163 while (evicted_cache_size < requested_space && | 164 while (evicted_cache_size < requested_space && |
164 iter != cache_info_list.rend()) { | 165 iter != cache_info_list.rend()) { |
165 const CacheInfo& cache_info = *iter; | 166 const CacheInfo& cache_info = *iter; |
166 | 167 |
167 // Update DB. | 168 // Update DB. |
168 ResourceEntry entry = cache_info.second; | 169 ResourceEntry entry = cache_info.second; |
169 entry.mutable_file_specific_info()->clear_cache_state(); | 170 entry.mutable_file_specific_info()->clear_cache_state(); |
170 storage_->PutEntry(entry); | 171 storage_->PutEntry(entry); |
171 | 172 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 const std::string& md5, | 224 const std::string& md5, |
224 const base::FilePath& source_path, | 225 const base::FilePath& source_path, |
225 FileOperationType file_operation_type) { | 226 FileOperationType file_operation_type) { |
226 AssertOnSequencedWorkerPool(); | 227 AssertOnSequencedWorkerPool(); |
227 | 228 |
228 ResourceEntry entry; | 229 ResourceEntry entry; |
229 FileError error = storage_->GetEntry(id, &entry); | 230 FileError error = storage_->GetEntry(id, &entry); |
230 if (error != FILE_ERROR_OK) | 231 if (error != FILE_ERROR_OK) |
231 return error; | 232 return error; |
232 | 233 |
233 int64 file_size = 0; | 234 int64_t file_size = 0; |
234 if (file_operation_type == FILE_OPERATION_COPY) { | 235 if (file_operation_type == FILE_OPERATION_COPY) { |
235 if (!base::GetFileSize(source_path, &file_size)) { | 236 if (!base::GetFileSize(source_path, &file_size)) { |
236 LOG(WARNING) << "Couldn't get file size for: " << source_path.value(); | 237 LOG(WARNING) << "Couldn't get file size for: " << source_path.value(); |
237 return FILE_ERROR_FAILED; | 238 return FILE_ERROR_FAILED; |
238 } | 239 } |
239 } | 240 } |
240 if (!FreeDiskSpaceIfNeededFor(file_size)) | 241 if (!FreeDiskSpaceIfNeededFor(file_size)) |
241 return FILE_ERROR_NO_LOCAL_SPACE; | 242 return FILE_ERROR_NO_LOCAL_SPACE; |
242 | 243 |
243 // If file is mounted, return error. | 244 // If file is mounted, return error. |
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
633 return error; | 634 return error; |
634 | 635 |
635 std::set<std::string>::iterator it = mounted_files_.find(id); | 636 std::set<std::string>::iterator it = mounted_files_.find(id); |
636 if (it == mounted_files_.end()) | 637 if (it == mounted_files_.end()) |
637 return FILE_ERROR_INVALID_OPERATION; | 638 return FILE_ERROR_INVALID_OPERATION; |
638 | 639 |
639 mounted_files_.erase(it); | 640 mounted_files_.erase(it); |
640 return FILE_ERROR_OK; | 641 return FILE_ERROR_OK; |
641 } | 642 } |
642 | 643 |
643 int64 FileCache::GetAvailableSpace() { | 644 int64_t FileCache::GetAvailableSpace() { |
644 int64 free_space = 0; | 645 int64_t free_space = 0; |
645 if (free_disk_space_getter_) | 646 if (free_disk_space_getter_) |
646 free_space = free_disk_space_getter_->AmountOfFreeDiskSpace(); | 647 free_space = free_disk_space_getter_->AmountOfFreeDiskSpace(); |
647 else | 648 else |
648 free_space = base::SysInfo::AmountOfFreeDiskSpace(cache_file_directory_); | 649 free_space = base::SysInfo::AmountOfFreeDiskSpace(cache_file_directory_); |
649 | 650 |
650 // Subtract this as if this portion does not exist. | 651 // Subtract this as if this portion does not exist. |
651 free_space -= drive::internal::kMinFreeSpaceInBytes; | 652 free_space -= drive::internal::kMinFreeSpaceInBytes; |
652 return free_space; | 653 return free_space; |
653 } | 654 } |
654 | 655 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
704 | 705 |
705 bool FileCache::IsEvictable(const std::string& id, const ResourceEntry& entry) { | 706 bool FileCache::IsEvictable(const std::string& id, const ResourceEntry& entry) { |
706 return entry.file_specific_info().has_cache_state() && | 707 return entry.file_specific_info().has_cache_state() && |
707 !entry.file_specific_info().cache_state().is_pinned() && | 708 !entry.file_specific_info().cache_state().is_pinned() && |
708 !entry.file_specific_info().cache_state().is_dirty() && | 709 !entry.file_specific_info().cache_state().is_dirty() && |
709 !mounted_files_.count(id); | 710 !mounted_files_.count(id); |
710 } | 711 } |
711 | 712 |
712 } // namespace internal | 713 } // namespace internal |
713 } // namespace drive | 714 } // namespace drive |
OLD | NEW |