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 "chrome/browser/chromeos/drive/file_cache_metadata.h" | 5 #include "chrome/browser/chromeos/drive/file_cache_metadata.h" |
6 | 6 |
7 #include "base/callback.h" | 7 #include "base/callback.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "base/sequenced_task_runner.h" | 10 #include "base/sequenced_task_runner.h" |
11 #include "chrome/browser/chromeos/drive/drive.pb.h" | 11 #include "chrome/browser/chromeos/drive/drive.pb.h" |
12 #include "chrome/browser/chromeos/drive/file_cache.h" | 12 #include "chrome/browser/chromeos/drive/file_cache.h" |
13 #include "chrome/browser/chromeos/drive/file_system_util.h" | 13 #include "chrome/browser/chromeos/drive/file_system_util.h" |
14 #include "third_party/leveldatabase/src/include/leveldb/db.h" | 14 #include "third_party/leveldatabase/src/include/leveldb/db.h" |
15 | 15 |
16 namespace drive { | 16 namespace drive { |
17 namespace internal { | 17 namespace internal { |
18 | 18 |
19 namespace { | 19 namespace { |
20 | 20 |
| 21 typedef std::map<std::string, FileCacheEntry> CacheMap; |
| 22 |
21 enum DBOpenStatus { | 23 enum DBOpenStatus { |
22 DB_OPEN_SUCCESS, | 24 DB_OPEN_SUCCESS, |
23 DB_OPEN_FAILURE_CORRUPTION, | 25 DB_OPEN_FAILURE_CORRUPTION, |
24 DB_OPEN_FAILURE_OTHER, | 26 DB_OPEN_FAILURE_OTHER, |
25 DB_OPEN_FAILURE_UNRECOVERABLE, | 27 DB_OPEN_FAILURE_UNRECOVERABLE, |
26 DB_OPEN_MAX_VALUE, | 28 DB_OPEN_MAX_VALUE, |
27 }; | 29 }; |
28 | 30 |
29 // A map table of resource ID to file path. | 31 // A map table of resource ID to file path. |
30 typedef std::map<std::string, base::FilePath> ResourceIdToFilePathMap; | 32 typedef std::map<std::string, base::FilePath> ResourceIdToFilePathMap; |
31 | 33 |
32 // Scans cache subdirectory and build or update |cache_map| with found files. | 34 // Scans cache subdirectory and build or update |cache_map| with found files. |
33 // | 35 // |
34 // The resource IDs and file paths of discovered files are collected as a | 36 // The resource IDs and file paths of discovered files are collected as a |
35 // ResourceIdToFilePathMap, if these are processed properly. | 37 // ResourceIdToFilePathMap, if these are processed properly. |
36 void ScanCacheDirectory( | 38 void ScanCacheDirectory(const std::vector<base::FilePath>& cache_paths, |
37 const std::vector<base::FilePath>& cache_paths, | 39 FileCache::CacheSubDirectoryType sub_dir_type, |
38 FileCache::CacheSubDirectoryType sub_dir_type, | 40 CacheMap* cache_map, |
39 FileCacheMetadata::CacheMap* cache_map, | 41 ResourceIdToFilePathMap* processed_file_map) { |
40 ResourceIdToFilePathMap* processed_file_map) { | |
41 DCHECK(cache_map); | 42 DCHECK(cache_map); |
42 DCHECK(processed_file_map); | 43 DCHECK(processed_file_map); |
43 | 44 |
44 file_util::FileEnumerator enumerator(cache_paths[sub_dir_type], | 45 file_util::FileEnumerator enumerator(cache_paths[sub_dir_type], |
45 false, // not recursive | 46 false, // not recursive |
46 file_util::FileEnumerator::FILES, | 47 file_util::FileEnumerator::FILES, |
47 util::kWildCard); | 48 util::kWildCard); |
48 for (base::FilePath current = enumerator.Next(); !current.empty(); | 49 for (base::FilePath current = enumerator.Next(); !current.empty(); |
49 current = enumerator.Next()) { | 50 current = enumerator.Next()) { |
50 // Extract resource_id and md5 from filename. | 51 // Extract resource_id and md5 from filename. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 } | 84 } |
84 } | 85 } |
85 | 86 |
86 // Create and insert new entry into cache map. | 87 // Create and insert new entry into cache map. |
87 cache_map->insert(std::make_pair(resource_id, cache_entry)); | 88 cache_map->insert(std::make_pair(resource_id, cache_entry)); |
88 processed_file_map->insert(std::make_pair(resource_id, current)); | 89 processed_file_map->insert(std::make_pair(resource_id, current)); |
89 } | 90 } |
90 } | 91 } |
91 | 92 |
92 void ScanCachePaths(const std::vector<base::FilePath>& cache_paths, | 93 void ScanCachePaths(const std::vector<base::FilePath>& cache_paths, |
93 FileCacheMetadata::CacheMap* cache_map) { | 94 CacheMap* cache_map) { |
94 DVLOG(1) << "Scanning directories"; | 95 DVLOG(1) << "Scanning directories"; |
95 | 96 |
96 // Scan cache persistent and tmp directories to enumerate all files and create | 97 // Scan cache persistent and tmp directories to enumerate all files and create |
97 // corresponding entries for cache map. | 98 // corresponding entries for cache map. |
98 ResourceIdToFilePathMap persistent_file_map; | 99 ResourceIdToFilePathMap persistent_file_map; |
99 ScanCacheDirectory(cache_paths, | 100 ScanCacheDirectory(cache_paths, |
100 FileCache::CACHE_TYPE_PERSISTENT, | 101 FileCache::CACHE_TYPE_PERSISTENT, |
101 cache_map, | 102 cache_map, |
102 &persistent_file_map); | 103 &persistent_file_map); |
103 ResourceIdToFilePathMap tmp_file_map; | 104 ResourceIdToFilePathMap tmp_file_map; |
104 ScanCacheDirectory(cache_paths, | 105 ScanCacheDirectory(cache_paths, |
105 FileCache::CACHE_TYPE_TMP, | 106 FileCache::CACHE_TYPE_TMP, |
106 cache_map, | 107 cache_map, |
107 &tmp_file_map); | 108 &tmp_file_map); |
108 | 109 |
109 // On DB corruption, keep only dirty-and-committed files in persistent | 110 // On DB corruption, keep only dirty-and-committed files in persistent |
110 // directory. Other files are deleted or moved to temporary directory. | 111 // directory. Other files are deleted or moved to temporary directory. |
111 for (ResourceIdToFilePathMap::const_iterator iter = | 112 for (ResourceIdToFilePathMap::const_iterator iter = |
112 persistent_file_map.begin(); | 113 persistent_file_map.begin(); |
113 iter != persistent_file_map.end(); ++iter) { | 114 iter != persistent_file_map.end(); ++iter) { |
114 const std::string& resource_id = iter->first; | 115 const std::string& resource_id = iter->first; |
115 const base::FilePath& file_path = iter->second; | 116 const base::FilePath& file_path = iter->second; |
116 | 117 |
117 FileCacheMetadata::CacheMap::iterator cache_map_iter = | 118 CacheMap::iterator cache_map_iter = cache_map->find(resource_id); |
118 cache_map->find(resource_id); | |
119 if (cache_map_iter != cache_map->end()) { | 119 if (cache_map_iter != cache_map->end()) { |
120 FileCacheEntry* cache_entry = &cache_map_iter->second; | 120 FileCacheEntry* cache_entry = &cache_map_iter->second; |
121 const bool is_dirty = cache_entry->is_dirty(); | 121 const bool is_dirty = cache_entry->is_dirty(); |
122 if (!is_dirty) { | 122 if (!is_dirty) { |
123 // If the file is not dirty, move to temporary directory. | 123 // If the file is not dirty, move to temporary directory. |
124 base::FilePath new_file_path = | 124 base::FilePath new_file_path = |
125 cache_paths[FileCache::CACHE_TYPE_TMP].Append( | 125 cache_paths[FileCache::CACHE_TYPE_TMP].Append( |
126 file_path.BaseName()); | 126 file_path.BaseName()); |
127 DLOG(WARNING) << "Moving: " << file_path.value() | 127 DLOG(WARNING) << "Moving: " << file_path.value() |
128 << " to: " << new_file_path.value(); | 128 << " to: " << new_file_path.value(); |
129 file_util::Move(file_path, new_file_path); | 129 file_util::Move(file_path, new_file_path); |
130 cache_entry->set_is_persistent(false); | 130 cache_entry->set_is_persistent(false); |
131 } | 131 } |
132 } | 132 } |
133 } | 133 } |
134 DVLOG(1) << "Directory scan finished"; | 134 DVLOG(1) << "Directory scan finished"; |
135 } | 135 } |
136 | 136 |
137 // Returns true if |md5| matches the one in |cache_entry| with some | 137 // Returns true if |md5| matches the one in |cache_entry| with some |
138 // exceptions. See the function definition for details. | 138 // exceptions. See the function definition for details. |
139 bool CheckIfMd5Matches( | 139 bool CheckIfMd5Matches(const std::string& md5, |
140 const std::string& md5, | 140 const FileCacheEntry& cache_entry) { |
141 const FileCacheEntry& cache_entry) { | |
142 if (cache_entry.is_dirty()) { | 141 if (cache_entry.is_dirty()) { |
143 // If the entry is dirty, its MD5 may have been replaced by "local" | 142 // If the entry is dirty, its MD5 may have been replaced by "local" |
144 // during cache initialization, so we don't compare MD5. | 143 // during cache initialization, so we don't compare MD5. |
145 return true; | 144 return true; |
146 } else if (cache_entry.is_pinned() && cache_entry.md5().empty()) { | 145 } else if (cache_entry.is_pinned() && cache_entry.md5().empty()) { |
147 // If the entry is pinned, it's ok for the entry to have an empty | 146 // If the entry is pinned, it's ok for the entry to have an empty |
148 // MD5. This can happen if the pinned file is not fetched. MD5 for pinned | 147 // MD5. This can happen if the pinned file is not fetched. MD5 for pinned |
149 // files are collected from files in "persistent" directory, but the | 148 // files are collected from files in "persistent" directory, but the |
150 // persistent files do not exist if these are not fetched yet. | 149 // persistent files do not exist if these are not fetched yet. |
151 return true; | 150 return true; |
152 } else if (md5.empty()) { | 151 } else if (md5.empty()) { |
153 // If the MD5 matching is not requested, don't check MD5. | 152 // If the MD5 matching is not requested, don't check MD5. |
154 return true; | 153 return true; |
155 } else if (md5 == cache_entry.md5()) { | 154 } else if (md5 == cache_entry.md5()) { |
156 // Otherwise, compare the MD5. | 155 // Otherwise, compare the MD5. |
157 return true; | 156 return true; |
158 } | 157 } |
159 return false; | 158 return false; |
160 } | 159 } |
161 | 160 |
162 //////////////////////////////////////////////////////////////////////////////// | 161 } // namespace |
163 // FileCacheMetadata implementation with std::map. | |
164 // Used for testing. | |
165 | 162 |
166 class FakeCacheMetadata : public FileCacheMetadata { | 163 // static |
167 public: | 164 const base::FilePath::CharType* FileCacheMetadata::kCacheMetadataDBPath = |
168 explicit FakeCacheMetadata( | 165 FILE_PATH_LITERAL("cache_metadata.db"); |
169 base::SequencedTaskRunner* blocking_task_runner); | |
170 | 166 |
171 private: | 167 FileCacheMetadata::FileCacheMetadata( |
172 virtual ~FakeCacheMetadata(); | |
173 | |
174 // FileCacheMetadata overrides: | |
175 virtual bool Initialize( | |
176 const std::vector<base::FilePath>& cache_paths) OVERRIDE; | |
177 virtual void AddOrUpdateCacheEntry( | |
178 const std::string& resource_id, | |
179 const FileCacheEntry& cache_entry) OVERRIDE; | |
180 virtual void RemoveCacheEntry(const std::string& resource_id) OVERRIDE; | |
181 virtual bool GetCacheEntry(const std::string& resource_id, | |
182 const std::string& md5, | |
183 FileCacheEntry* cache_entry) OVERRIDE; | |
184 virtual void RemoveTemporaryFiles() OVERRIDE; | |
185 virtual void Iterate(const CacheIterateCallback& callback) OVERRIDE; | |
186 | |
187 CacheMap cache_map_; | |
188 | |
189 DISALLOW_COPY_AND_ASSIGN(FakeCacheMetadata); | |
190 }; | |
191 | |
192 FakeCacheMetadata::FakeCacheMetadata( | |
193 base::SequencedTaskRunner* blocking_task_runner) | 168 base::SequencedTaskRunner* blocking_task_runner) |
194 : FileCacheMetadata(blocking_task_runner) { | 169 : blocking_task_runner_(blocking_task_runner) { |
195 AssertOnSequencedWorkerPool(); | 170 AssertOnSequencedWorkerPool(); |
196 } | 171 } |
197 | 172 |
198 FakeCacheMetadata::~FakeCacheMetadata() { | 173 FileCacheMetadata::~FileCacheMetadata() { |
199 AssertOnSequencedWorkerPool(); | 174 AssertOnSequencedWorkerPool(); |
200 } | 175 } |
201 | 176 |
202 bool FakeCacheMetadata::Initialize( | 177 bool FileCacheMetadata::Initialize( |
203 const std::vector<base::FilePath>& cache_paths) { | |
204 AssertOnSequencedWorkerPool(); | |
205 | |
206 ScanCachePaths(cache_paths, &cache_map_); | |
207 return true; | |
208 } | |
209 | |
210 void FakeCacheMetadata::AddOrUpdateCacheEntry( | |
211 const std::string& resource_id, | |
212 const FileCacheEntry& cache_entry) { | |
213 AssertOnSequencedWorkerPool(); | |
214 | |
215 CacheMap::iterator iter = cache_map_.find(resource_id); | |
216 if (iter == cache_map_.end()) { // New resource, create new entry. | |
217 cache_map_.insert(std::make_pair(resource_id, cache_entry)); | |
218 } else { // Resource exists. | |
219 cache_map_[resource_id] = cache_entry; | |
220 } | |
221 } | |
222 | |
223 void FakeCacheMetadata::RemoveCacheEntry(const std::string& resource_id) { | |
224 AssertOnSequencedWorkerPool(); | |
225 | |
226 CacheMap::iterator iter = cache_map_.find(resource_id); | |
227 if (iter != cache_map_.end()) { | |
228 // Delete the FileCacheEntry and remove it from the map. | |
229 cache_map_.erase(iter); | |
230 } | |
231 } | |
232 | |
233 bool FakeCacheMetadata::GetCacheEntry(const std::string& resource_id, | |
234 const std::string& md5, | |
235 FileCacheEntry* entry) { | |
236 DCHECK(entry); | |
237 AssertOnSequencedWorkerPool(); | |
238 | |
239 CacheMap::iterator iter = cache_map_.find(resource_id); | |
240 if (iter == cache_map_.end()) { | |
241 DVLOG(1) << "Can't find " << resource_id << " in cache map"; | |
242 return false; | |
243 } | |
244 | |
245 const FileCacheEntry& cache_entry = iter->second; | |
246 | |
247 if (!CheckIfMd5Matches(md5, cache_entry)) { | |
248 return false; | |
249 } | |
250 | |
251 *entry = cache_entry; | |
252 return true; | |
253 } | |
254 | |
255 void FakeCacheMetadata::RemoveTemporaryFiles() { | |
256 AssertOnSequencedWorkerPool(); | |
257 | |
258 CacheMap::iterator iter = cache_map_.begin(); | |
259 while (iter != cache_map_.end()) { | |
260 if (!iter->second.is_persistent()) { | |
261 // Post-increment the iterator to avoid iterator invalidation. | |
262 cache_map_.erase(iter++); | |
263 } else { | |
264 ++iter; | |
265 } | |
266 } | |
267 } | |
268 | |
269 void FakeCacheMetadata::Iterate(const CacheIterateCallback& callback) { | |
270 AssertOnSequencedWorkerPool(); | |
271 | |
272 for (CacheMap::const_iterator iter = cache_map_.begin(); | |
273 iter != cache_map_.end(); ++iter) { | |
274 callback.Run(iter->first, iter->second); | |
275 } | |
276 } | |
277 | |
278 //////////////////////////////////////////////////////////////////////////////// | |
279 // FileCacheMetadata implementation with level::db. | |
280 | |
281 class FileCacheMetadataDB : public FileCacheMetadata { | |
282 public: | |
283 explicit FileCacheMetadataDB( | |
284 base::SequencedTaskRunner* blocking_task_runner); | |
285 | |
286 private: | |
287 virtual ~FileCacheMetadataDB(); | |
288 | |
289 // FileCacheMetadata overrides: | |
290 virtual bool Initialize( | |
291 const std::vector<base::FilePath>& cache_paths) OVERRIDE; | |
292 virtual void AddOrUpdateCacheEntry( | |
293 const std::string& resource_id, | |
294 const FileCacheEntry& cache_entry) OVERRIDE; | |
295 virtual void RemoveCacheEntry(const std::string& resource_id) OVERRIDE; | |
296 virtual bool GetCacheEntry(const std::string& resource_id, | |
297 const std::string& md5, | |
298 FileCacheEntry* cache_entry) OVERRIDE; | |
299 virtual void RemoveTemporaryFiles() OVERRIDE; | |
300 virtual void Iterate(const CacheIterateCallback& callback) OVERRIDE; | |
301 | |
302 // Helper function to insert |cache_map| entries into the database. | |
303 void InsertMapIntoDB(const CacheMap& cache_map); | |
304 | |
305 scoped_ptr<leveldb::DB> level_db_; | |
306 | |
307 DISALLOW_COPY_AND_ASSIGN(FileCacheMetadataDB); | |
308 }; | |
309 | |
310 FileCacheMetadataDB::FileCacheMetadataDB( | |
311 base::SequencedTaskRunner* blocking_task_runner) | |
312 : FileCacheMetadata(blocking_task_runner) { | |
313 AssertOnSequencedWorkerPool(); | |
314 } | |
315 | |
316 FileCacheMetadataDB::~FileCacheMetadataDB() { | |
317 AssertOnSequencedWorkerPool(); | |
318 } | |
319 | |
320 bool FileCacheMetadataDB::Initialize( | |
321 const std::vector<base::FilePath>& cache_paths) { | 178 const std::vector<base::FilePath>& cache_paths) { |
322 AssertOnSequencedWorkerPool(); | 179 AssertOnSequencedWorkerPool(); |
323 | 180 |
324 const base::FilePath db_path = | 181 const base::FilePath db_path = |
325 cache_paths[FileCache::CACHE_TYPE_META].Append( | 182 cache_paths[FileCache::CACHE_TYPE_META].Append(kCacheMetadataDBPath); |
326 kCacheMetadataDBPath); | |
327 DVLOG(1) << "db path=" << db_path.value(); | 183 DVLOG(1) << "db path=" << db_path.value(); |
328 | 184 |
329 bool scan_cache = !file_util::PathExists(db_path); | 185 bool scan_cache = !file_util::PathExists(db_path); |
330 | 186 |
331 leveldb::DB* level_db = NULL; | 187 leveldb::DB* level_db = NULL; |
332 leveldb::Options options; | 188 leveldb::Options options; |
333 options.create_if_missing = true; | 189 options.create_if_missing = true; |
334 leveldb::Status db_status = leveldb::DB::Open(options, db_path.AsUTF8Unsafe(), | 190 leveldb::Status db_status = leveldb::DB::Open(options, db_path.AsUTF8Unsafe(), |
335 &level_db); | 191 &level_db); |
336 | 192 |
(...skipping 21 matching lines...) Expand all Loading... |
358 UMA_HISTOGRAM_ENUMERATION("Drive.CacheDBOpenStatus", uma_status, | 214 UMA_HISTOGRAM_ENUMERATION("Drive.CacheDBOpenStatus", uma_status, |
359 DB_OPEN_MAX_VALUE); | 215 DB_OPEN_MAX_VALUE); |
360 DCHECK(level_db); | 216 DCHECK(level_db); |
361 level_db_.reset(level_db); | 217 level_db_.reset(level_db); |
362 | 218 |
363 // We scan the cache directories to initialize the cache database if we | 219 // We scan the cache directories to initialize the cache database if we |
364 // were previously using the cache map. | 220 // were previously using the cache map. |
365 if (scan_cache) { | 221 if (scan_cache) { |
366 CacheMap cache_map; | 222 CacheMap cache_map; |
367 ScanCachePaths(cache_paths, &cache_map); | 223 ScanCachePaths(cache_paths, &cache_map); |
368 InsertMapIntoDB(cache_map); | 224 for (CacheMap::const_iterator it = cache_map.begin(); |
| 225 it != cache_map.end(); ++it) { |
| 226 AddOrUpdateCacheEntry(it->first, it->second); |
| 227 } |
369 } | 228 } |
370 | 229 |
371 return true; | 230 return true; |
372 } | 231 } |
373 | 232 |
374 void FileCacheMetadataDB::InsertMapIntoDB(const CacheMap& cache_map) { | 233 void FileCacheMetadata::AddOrUpdateCacheEntry( |
375 DVLOG(1) << "InsertMapIntoDB"; | |
376 for (CacheMap::const_iterator it = cache_map.begin(); | |
377 it != cache_map.end(); ++it) { | |
378 AddOrUpdateCacheEntry(it->first, it->second); | |
379 } | |
380 } | |
381 | |
382 void FileCacheMetadataDB::AddOrUpdateCacheEntry( | |
383 const std::string& resource_id, | 234 const std::string& resource_id, |
384 const FileCacheEntry& cache_entry) { | 235 const FileCacheEntry& cache_entry) { |
385 AssertOnSequencedWorkerPool(); | 236 AssertOnSequencedWorkerPool(); |
386 | 237 |
387 DVLOG(1) << "AddOrUpdateCacheEntry, resource_id=" << resource_id; | 238 DVLOG(1) << "AddOrUpdateCacheEntry, resource_id=" << resource_id; |
388 std::string serialized; | 239 std::string serialized; |
389 const bool ok = cache_entry.SerializeToString(&serialized); | 240 const bool ok = cache_entry.SerializeToString(&serialized); |
390 if (ok) | 241 if (ok) |
391 level_db_->Put(leveldb::WriteOptions(), | 242 level_db_->Put(leveldb::WriteOptions(), |
392 leveldb::Slice(resource_id), | 243 leveldb::Slice(resource_id), |
393 leveldb::Slice(serialized)); | 244 leveldb::Slice(serialized)); |
394 } | 245 } |
395 | 246 |
396 void FileCacheMetadataDB::RemoveCacheEntry(const std::string& resource_id) { | 247 void FileCacheMetadata::RemoveCacheEntry(const std::string& resource_id) { |
397 AssertOnSequencedWorkerPool(); | 248 AssertOnSequencedWorkerPool(); |
398 | 249 |
399 DVLOG(1) << "RemoveCacheEntry, resource_id=" << resource_id; | 250 DVLOG(1) << "RemoveCacheEntry, resource_id=" << resource_id; |
400 level_db_->Delete(leveldb::WriteOptions(), leveldb::Slice(resource_id)); | 251 level_db_->Delete(leveldb::WriteOptions(), leveldb::Slice(resource_id)); |
401 } | 252 } |
402 | 253 |
403 bool FileCacheMetadataDB::GetCacheEntry(const std::string& resource_id, | 254 bool FileCacheMetadata::GetCacheEntry(const std::string& resource_id, |
404 const std::string& md5, | 255 const std::string& md5, |
405 FileCacheEntry* entry) { | 256 FileCacheEntry* entry) { |
406 DCHECK(entry); | 257 DCHECK(entry); |
407 AssertOnSequencedWorkerPool(); | 258 AssertOnSequencedWorkerPool(); |
408 | 259 |
409 std::string serialized; | 260 std::string serialized; |
410 const leveldb::Status status = level_db_->Get( | 261 const leveldb::Status status = level_db_->Get( |
411 leveldb::ReadOptions(), | 262 leveldb::ReadOptions(), |
412 leveldb::Slice(resource_id), &serialized); | 263 leveldb::Slice(resource_id), &serialized); |
413 if (!status.ok()) { | 264 if (!status.ok()) { |
414 DVLOG(1) << "Can't find " << resource_id << " in cache db"; | 265 DVLOG(1) << "Can't find " << resource_id << " in cache db"; |
415 return false; | 266 return false; |
416 } | 267 } |
417 | 268 |
418 FileCacheEntry cache_entry; | 269 FileCacheEntry cache_entry; |
419 const bool ok = cache_entry.ParseFromString(serialized); | 270 const bool ok = cache_entry.ParseFromString(serialized); |
420 if (!ok) { | 271 if (!ok) { |
421 LOG(ERROR) << "Failed to parse " << serialized; | 272 LOG(ERROR) << "Failed to parse " << serialized; |
422 return false; | 273 return false; |
423 } | 274 } |
424 | 275 |
425 if (!CheckIfMd5Matches(md5, cache_entry)) { | 276 if (!CheckIfMd5Matches(md5, cache_entry)) { |
426 return false; | 277 return false; |
427 } | 278 } |
428 | 279 |
429 *entry = cache_entry; | 280 *entry = cache_entry; |
430 return true; | 281 return true; |
431 } | 282 } |
432 | 283 |
433 void FileCacheMetadataDB::RemoveTemporaryFiles() { | 284 void FileCacheMetadata::RemoveTemporaryFiles() { |
434 AssertOnSequencedWorkerPool(); | 285 AssertOnSequencedWorkerPool(); |
435 | 286 |
436 scoped_ptr<leveldb::Iterator> iter(level_db_->NewIterator( | 287 scoped_ptr<leveldb::Iterator> iter(level_db_->NewIterator( |
437 leveldb::ReadOptions())); | 288 leveldb::ReadOptions())); |
438 for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { | 289 for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { |
439 FileCacheEntry cache_entry; | 290 FileCacheEntry cache_entry; |
440 const bool ok = cache_entry.ParseFromArray(iter->value().data(), | 291 const bool ok = cache_entry.ParseFromArray(iter->value().data(), |
441 iter->value().size()); | 292 iter->value().size()); |
442 if (ok && !cache_entry.is_persistent()) | 293 if (ok && !cache_entry.is_persistent()) |
443 level_db_->Delete(leveldb::WriteOptions(), iter->key()); | 294 level_db_->Delete(leveldb::WriteOptions(), iter->key()); |
444 } | 295 } |
445 } | 296 } |
446 | 297 |
447 void FileCacheMetadataDB::Iterate(const CacheIterateCallback& callback) { | 298 void FileCacheMetadata::Iterate(const CacheIterateCallback& callback) { |
448 AssertOnSequencedWorkerPool(); | 299 AssertOnSequencedWorkerPool(); |
449 | 300 |
450 scoped_ptr<leveldb::Iterator> iter(level_db_->NewIterator( | 301 scoped_ptr<leveldb::Iterator> iter(level_db_->NewIterator( |
451 leveldb::ReadOptions())); | 302 leveldb::ReadOptions())); |
452 for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { | 303 for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { |
453 FileCacheEntry cache_entry; | 304 FileCacheEntry cache_entry; |
454 const bool ok = cache_entry.ParseFromArray(iter->value().data(), | 305 const bool ok = cache_entry.ParseFromArray(iter->value().data(), |
455 iter->value().size()); | 306 iter->value().size()); |
456 if (ok) | 307 if (ok) |
457 callback.Run(iter->key().ToString(), cache_entry); | 308 callback.Run(iter->key().ToString(), cache_entry); |
458 } | 309 } |
459 } | 310 } |
460 | 311 |
461 } // namespace | |
462 | |
463 // static | |
464 const base::FilePath::CharType* FileCacheMetadata::kCacheMetadataDBPath = | |
465 FILE_PATH_LITERAL("cache_metadata.db"); | |
466 | |
467 | |
468 FileCacheMetadata::FileCacheMetadata( | |
469 base::SequencedTaskRunner* blocking_task_runner) | |
470 : blocking_task_runner_(blocking_task_runner) { | |
471 AssertOnSequencedWorkerPool(); | |
472 } | |
473 | |
474 FileCacheMetadata::~FileCacheMetadata() { | |
475 AssertOnSequencedWorkerPool(); | |
476 } | |
477 | |
478 // static | |
479 scoped_ptr<FileCacheMetadata> FileCacheMetadata::CreateCacheMetadata( | |
480 base::SequencedTaskRunner* blocking_task_runner) { | |
481 return scoped_ptr<FileCacheMetadata>( | |
482 new FileCacheMetadataDB(blocking_task_runner)); | |
483 } | |
484 | |
485 // static | |
486 scoped_ptr<FileCacheMetadata> | |
487 FileCacheMetadata::CreateCacheMetadataForTesting( | |
488 base::SequencedTaskRunner* blocking_task_runner) { | |
489 return scoped_ptr<FileCacheMetadata>( | |
490 new FakeCacheMetadata(blocking_task_runner)); | |
491 } | |
492 | |
493 void FileCacheMetadata::AssertOnSequencedWorkerPool() { | 312 void FileCacheMetadata::AssertOnSequencedWorkerPool() { |
494 DCHECK(!blocking_task_runner_ || | 313 DCHECK(!blocking_task_runner_ || |
495 blocking_task_runner_->RunsTasksOnCurrentThread()); | 314 blocking_task_runner_->RunsTasksOnCurrentThread()); |
496 } | 315 } |
497 | 316 |
498 } // namespace internal | 317 } // namespace internal |
499 } // namespace drive | 318 } // namespace drive |
OLD | NEW |