| 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/gdata/gdata_cache_metadata.h" | 5 #include "chrome/browser/chromeos/gdata/drive_cache_metadata.h" |
| 6 | 6 |
| 7 #include <leveldb/db.h> | 7 #include <leveldb/db.h> |
| 8 | 8 |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/sequenced_task_runner.h" | 10 #include "base/sequenced_task_runner.h" |
| 11 #include "chrome/browser/chromeos/gdata/drive.pb.h" | 11 #include "chrome/browser/chromeos/gdata/drive.pb.h" |
| 12 #include "chrome/browser/chromeos/gdata/gdata_util.h" | 12 #include "chrome/browser/chromeos/gdata/gdata_util.h" |
| 13 | 13 |
| 14 namespace gdata { | 14 namespace gdata { |
| 15 | 15 |
| 16 namespace { | 16 namespace { |
| 17 | 17 |
| 18 // A map table of resource ID to file path. | 18 // A map table of resource ID to file path. |
| 19 typedef std::map<std::string, FilePath> ResourceIdToFilePathMap; | 19 typedef std::map<std::string, FilePath> ResourceIdToFilePathMap; |
| 20 | 20 |
| 21 const FilePath::CharType kGDataCacheMetadataDBPath[] = | 21 const FilePath::CharType kDriveCacheMetadataDBPath[] = |
| 22 FILE_PATH_LITERAL("cache_metadata.db"); | 22 FILE_PATH_LITERAL("cache_metadata.db"); |
| 23 | 23 |
| 24 // Returns true if |file_path| is a valid symbolic link as |sub_dir_type|. | 24 // Returns true if |file_path| is a valid symbolic link as |sub_dir_type|. |
| 25 // Otherwise, returns false with the reason. | 25 // Otherwise, returns false with the reason. |
| 26 bool IsValidSymbolicLink(const FilePath& file_path, | 26 bool IsValidSymbolicLink(const FilePath& file_path, |
| 27 GDataCache::CacheSubDirectoryType sub_dir_type, | 27 DriveCache::CacheSubDirectoryType sub_dir_type, |
| 28 const std::vector<FilePath>& cache_paths, | 28 const std::vector<FilePath>& cache_paths, |
| 29 std::string* reason) { | 29 std::string* reason) { |
| 30 DCHECK(sub_dir_type == GDataCache::CACHE_TYPE_PINNED || | 30 DCHECK(sub_dir_type == DriveCache::CACHE_TYPE_PINNED || |
| 31 sub_dir_type == GDataCache::CACHE_TYPE_OUTGOING); | 31 sub_dir_type == DriveCache::CACHE_TYPE_OUTGOING); |
| 32 | 32 |
| 33 FilePath destination; | 33 FilePath destination; |
| 34 if (!file_util::ReadSymbolicLink(file_path, &destination)) { | 34 if (!file_util::ReadSymbolicLink(file_path, &destination)) { |
| 35 *reason = "failed to read the symlink (maybe not a symlink)"; | 35 *reason = "failed to read the symlink (maybe not a symlink)"; |
| 36 return false; | 36 return false; |
| 37 } | 37 } |
| 38 | 38 |
| 39 if (!file_util::PathExists(destination)) { | 39 if (!file_util::PathExists(destination)) { |
| 40 *reason = "pointing to a non-existent file"; | 40 *reason = "pointing to a non-existent file"; |
| 41 return false; | 41 return false; |
| 42 } | 42 } |
| 43 | 43 |
| 44 // pinned-but-not-fetched files are symlinks to kSymLinkToDevNull. | 44 // pinned-but-not-fetched files are symlinks to kSymLinkToDevNull. |
| 45 if (sub_dir_type == GDataCache::CACHE_TYPE_PINNED && | 45 if (sub_dir_type == DriveCache::CACHE_TYPE_PINNED && |
| 46 destination == FilePath::FromUTF8Unsafe(util::kSymLinkToDevNull)) { | 46 destination == FilePath::FromUTF8Unsafe(util::kSymLinkToDevNull)) { |
| 47 return true; | 47 return true; |
| 48 } | 48 } |
| 49 | 49 |
| 50 // The destination file should be in the persistent directory. | 50 // The destination file should be in the persistent directory. |
| 51 if (!cache_paths[GDataCache::CACHE_TYPE_PERSISTENT].IsParent(destination)) { | 51 if (!cache_paths[DriveCache::CACHE_TYPE_PERSISTENT].IsParent(destination)) { |
| 52 *reason = "pointing to a file outside of persistent directory"; | 52 *reason = "pointing to a file outside of persistent directory"; |
| 53 return false; | 53 return false; |
| 54 } | 54 } |
| 55 | 55 |
| 56 return true; | 56 return true; |
| 57 } | 57 } |
| 58 | 58 |
| 59 // Remove invalid files from persistent directory. | 59 // Remove invalid files from persistent directory. |
| 60 // | 60 // |
| 61 // 1) dirty-but-not-committed files. The dirty files should be committed | 61 // 1) dirty-but-not-committed files. The dirty files should be committed |
| 62 // (i.e. symlinks created in 'outgoing' directory) before shutdown, but the | 62 // (i.e. symlinks created in 'outgoing' directory) before shutdown, but the |
| 63 // symlinks may not be created if the system shuts down unexpectedly. | 63 // symlinks may not be created if the system shuts down unexpectedly. |
| 64 // | 64 // |
| 65 // 2) neither dirty nor pinned. Files in the persistent directory should be | 65 // 2) neither dirty nor pinned. Files in the persistent directory should be |
| 66 // in the either of the states. | 66 // in the either of the states. |
| 67 void RemoveInvalidFilesFromPersistentDirectory( | 67 void RemoveInvalidFilesFromPersistentDirectory( |
| 68 const ResourceIdToFilePathMap& persistent_file_map, | 68 const ResourceIdToFilePathMap& persistent_file_map, |
| 69 const ResourceIdToFilePathMap& outgoing_file_map, | 69 const ResourceIdToFilePathMap& outgoing_file_map, |
| 70 GDataCacheMetadata::CacheMap* cache_map) { | 70 DriveCacheMetadata::CacheMap* cache_map) { |
| 71 for (ResourceIdToFilePathMap::const_iterator iter = | 71 for (ResourceIdToFilePathMap::const_iterator iter = |
| 72 persistent_file_map.begin(); | 72 persistent_file_map.begin(); |
| 73 iter != persistent_file_map.end(); ++iter) { | 73 iter != persistent_file_map.end(); ++iter) { |
| 74 const std::string& resource_id = iter->first; | 74 const std::string& resource_id = iter->first; |
| 75 const FilePath& file_path = iter->second; | 75 const FilePath& file_path = iter->second; |
| 76 | 76 |
| 77 GDataCacheMetadata::CacheMap::iterator cache_map_iter = | 77 DriveCacheMetadata::CacheMap::iterator cache_map_iter = |
| 78 cache_map->find(resource_id); | 78 cache_map->find(resource_id); |
| 79 if (cache_map_iter != cache_map->end()) { | 79 if (cache_map_iter != cache_map->end()) { |
| 80 const DriveCacheEntry& cache_entry = cache_map_iter->second; | 80 const DriveCacheEntry& cache_entry = cache_map_iter->second; |
| 81 // If the file is dirty but not committed, remove it. | 81 // If the file is dirty but not committed, remove it. |
| 82 if (cache_entry.is_dirty() && | 82 if (cache_entry.is_dirty() && |
| 83 outgoing_file_map.count(resource_id) == 0) { | 83 outgoing_file_map.count(resource_id) == 0) { |
| 84 LOG(WARNING) << "Removing dirty-but-not-committed file: " | 84 LOG(WARNING) << "Removing dirty-but-not-committed file: " |
| 85 << file_path.value(); | 85 << file_path.value(); |
| 86 file_util::Delete(file_path, false); | 86 file_util::Delete(file_path, false); |
| 87 cache_map->erase(cache_map_iter); | 87 cache_map->erase(cache_map_iter); |
| 88 } else if (!cache_entry.is_dirty() && | 88 } else if (!cache_entry.is_dirty() && |
| 89 !cache_entry.is_pinned()) { | 89 !cache_entry.is_pinned()) { |
| 90 // If the file is neither dirty nor pinned, remove it. | 90 // If the file is neither dirty nor pinned, remove it. |
| 91 LOG(WARNING) << "Removing persistent-but-dangling file: " | 91 LOG(WARNING) << "Removing persistent-but-dangling file: " |
| 92 << file_path.value(); | 92 << file_path.value(); |
| 93 file_util::Delete(file_path, false); | 93 file_util::Delete(file_path, false); |
| 94 cache_map->erase(cache_map_iter); | 94 cache_map->erase(cache_map_iter); |
| 95 } | 95 } |
| 96 } | 96 } |
| 97 } | 97 } |
| 98 } | 98 } |
| 99 | 99 |
| 100 // Scans cache subdirectory and build or update |cache_map| | 100 // Scans cache subdirectory and build or update |cache_map| |
| 101 // with found file blobs or symlinks. | 101 // with found file blobs or symlinks. |
| 102 // | 102 // |
| 103 // The resource IDs and file paths of discovered files are collected as a | 103 // The resource IDs and file paths of discovered files are collected as a |
| 104 // ResourceIdToFilePathMap, if these are processed properly. | 104 // ResourceIdToFilePathMap, if these are processed properly. |
| 105 void ScanCacheDirectory( | 105 void ScanCacheDirectory( |
| 106 const std::vector<FilePath>& cache_paths, | 106 const std::vector<FilePath>& cache_paths, |
| 107 GDataCache::CacheSubDirectoryType sub_dir_type, | 107 DriveCache::CacheSubDirectoryType sub_dir_type, |
| 108 GDataCacheMetadata::CacheMap* cache_map, | 108 DriveCacheMetadata::CacheMap* cache_map, |
| 109 ResourceIdToFilePathMap* processed_file_map) { | 109 ResourceIdToFilePathMap* processed_file_map) { |
| 110 DCHECK(cache_map); | 110 DCHECK(cache_map); |
| 111 DCHECK(processed_file_map); | 111 DCHECK(processed_file_map); |
| 112 | 112 |
| 113 file_util::FileEnumerator enumerator(cache_paths[sub_dir_type], | 113 file_util::FileEnumerator enumerator(cache_paths[sub_dir_type], |
| 114 false, // not recursive | 114 false, // not recursive |
| 115 file_util::FileEnumerator::FILES | | 115 file_util::FileEnumerator::FILES | |
| 116 file_util::FileEnumerator::SHOW_SYM_LINKS, | 116 file_util::FileEnumerator::SHOW_SYM_LINKS, |
| 117 util::kWildCard); | 117 util::kWildCard); |
| 118 for (FilePath current = enumerator.Next(); !current.empty(); | 118 for (FilePath current = enumerator.Next(); !current.empty(); |
| 119 current = enumerator.Next()) { | 119 current = enumerator.Next()) { |
| 120 // Extract resource_id and md5 from filename. | 120 // Extract resource_id and md5 from filename. |
| 121 std::string resource_id; | 121 std::string resource_id; |
| 122 std::string md5; | 122 std::string md5; |
| 123 std::string extra_extension; | 123 std::string extra_extension; |
| 124 util::ParseCacheFilePath(current, &resource_id, &md5, &extra_extension); | 124 util::ParseCacheFilePath(current, &resource_id, &md5, &extra_extension); |
| 125 | 125 |
| 126 // Determine cache state. | 126 // Determine cache state. |
| 127 DriveCacheEntry cache_entry; | 127 DriveCacheEntry cache_entry; |
| 128 cache_entry.set_md5(md5); | 128 cache_entry.set_md5(md5); |
| 129 // If we're scanning pinned directory and if entry already exists, just | 129 // If we're scanning pinned directory and if entry already exists, just |
| 130 // update its pinned state. | 130 // update its pinned state. |
| 131 if (sub_dir_type == GDataCache::CACHE_TYPE_PINNED) { | 131 if (sub_dir_type == DriveCache::CACHE_TYPE_PINNED) { |
| 132 std::string reason; | 132 std::string reason; |
| 133 if (!IsValidSymbolicLink(current, sub_dir_type, cache_paths, &reason)) { | 133 if (!IsValidSymbolicLink(current, sub_dir_type, cache_paths, &reason)) { |
| 134 LOG(WARNING) << "Removing an invalid symlink: " << current.value() | 134 LOG(WARNING) << "Removing an invalid symlink: " << current.value() |
| 135 << ": " << reason; | 135 << ": " << reason; |
| 136 file_util::Delete(current, false); | 136 file_util::Delete(current, false); |
| 137 continue; | 137 continue; |
| 138 } | 138 } |
| 139 | 139 |
| 140 GDataCacheMetadata::CacheMap::iterator iter = | 140 DriveCacheMetadata::CacheMap::iterator iter = |
| 141 cache_map->find(resource_id); | 141 cache_map->find(resource_id); |
| 142 if (iter != cache_map->end()) { // Entry exists, update pinned state. | 142 if (iter != cache_map->end()) { // Entry exists, update pinned state. |
| 143 iter->second.set_is_pinned(true); | 143 iter->second.set_is_pinned(true); |
| 144 | 144 |
| 145 processed_file_map->insert(std::make_pair(resource_id, current)); | 145 processed_file_map->insert(std::make_pair(resource_id, current)); |
| 146 continue; | 146 continue; |
| 147 } | 147 } |
| 148 // Entry doesn't exist, this is a special symlink that refers to | 148 // Entry doesn't exist, this is a special symlink that refers to |
| 149 // /dev/null; follow through to create an entry with the PINNED but not | 149 // /dev/null; follow through to create an entry with the PINNED but not |
| 150 // PRESENT state. | 150 // PRESENT state. |
| 151 cache_entry.set_is_pinned(true); | 151 cache_entry.set_is_pinned(true); |
| 152 } else if (sub_dir_type == GDataCache::CACHE_TYPE_OUTGOING) { | 152 } else if (sub_dir_type == DriveCache::CACHE_TYPE_OUTGOING) { |
| 153 std::string reason; | 153 std::string reason; |
| 154 if (!IsValidSymbolicLink(current, sub_dir_type, cache_paths, &reason)) { | 154 if (!IsValidSymbolicLink(current, sub_dir_type, cache_paths, &reason)) { |
| 155 LOG(WARNING) << "Removing an invalid symlink: " << current.value() | 155 LOG(WARNING) << "Removing an invalid symlink: " << current.value() |
| 156 << ": " << reason; | 156 << ": " << reason; |
| 157 file_util::Delete(current, false); | 157 file_util::Delete(current, false); |
| 158 continue; | 158 continue; |
| 159 } | 159 } |
| 160 | 160 |
| 161 // If we're scanning outgoing directory, entry must exist and be dirty. | 161 // If we're scanning outgoing directory, entry must exist and be dirty. |
| 162 // Otherwise, it's a logic error from previous execution, remove this | 162 // Otherwise, it's a logic error from previous execution, remove this |
| 163 // outgoing symlink and move on. | 163 // outgoing symlink and move on. |
| 164 GDataCacheMetadata::CacheMap::iterator iter = | 164 DriveCacheMetadata::CacheMap::iterator iter = |
| 165 cache_map->find(resource_id); | 165 cache_map->find(resource_id); |
| 166 if (iter == cache_map->end() || !iter->second.is_dirty()) { | 166 if (iter == cache_map->end() || !iter->second.is_dirty()) { |
| 167 LOG(WARNING) << "Removing an symlink to a non-dirty file: " | 167 LOG(WARNING) << "Removing an symlink to a non-dirty file: " |
| 168 << current.value(); | 168 << current.value(); |
| 169 file_util::Delete(current, false); | 169 file_util::Delete(current, false); |
| 170 continue; | 170 continue; |
| 171 } | 171 } |
| 172 | 172 |
| 173 processed_file_map->insert(std::make_pair(resource_id, current)); | 173 processed_file_map->insert(std::make_pair(resource_id, current)); |
| 174 continue; | 174 continue; |
| 175 } else if (sub_dir_type == GDataCache::CACHE_TYPE_PERSISTENT || | 175 } else if (sub_dir_type == DriveCache::CACHE_TYPE_PERSISTENT || |
| 176 sub_dir_type == GDataCache::CACHE_TYPE_TMP) { | 176 sub_dir_type == DriveCache::CACHE_TYPE_TMP) { |
| 177 if (sub_dir_type == GDataCache::CACHE_TYPE_PERSISTENT) | 177 if (sub_dir_type == DriveCache::CACHE_TYPE_PERSISTENT) |
| 178 cache_entry.set_is_persistent(true); | 178 cache_entry.set_is_persistent(true); |
| 179 | 179 |
| 180 if (file_util::IsLink(current)) { | 180 if (file_util::IsLink(current)) { |
| 181 LOG(WARNING) << "Removing a symlink in persistent/tmp directory" | 181 LOG(WARNING) << "Removing a symlink in persistent/tmp directory" |
| 182 << current.value(); | 182 << current.value(); |
| 183 file_util::Delete(current, false); | 183 file_util::Delete(current, false); |
| 184 continue; | 184 continue; |
| 185 } | 185 } |
| 186 if (extra_extension == util::kMountedArchiveFileExtension) { | 186 if (extra_extension == util::kMountedArchiveFileExtension) { |
| 187 // Mounted archives in cache should be unmounted upon logout/shutdown. | 187 // Mounted archives in cache should be unmounted upon logout/shutdown. |
| 188 // But if we encounter a mounted file at start, delete it and create an | 188 // But if we encounter a mounted file at start, delete it and create an |
| 189 // entry with not PRESENT state. | 189 // entry with not PRESENT state. |
| 190 DCHECK(sub_dir_type == GDataCache::CACHE_TYPE_PERSISTENT); | 190 DCHECK(sub_dir_type == DriveCache::CACHE_TYPE_PERSISTENT); |
| 191 file_util::Delete(current, false); | 191 file_util::Delete(current, false); |
| 192 } else { | 192 } else { |
| 193 // The cache file is present. | 193 // The cache file is present. |
| 194 cache_entry.set_is_present(true); | 194 cache_entry.set_is_present(true); |
| 195 | 195 |
| 196 // Adds the dirty bit if |md5| indicates that the file is dirty, and | 196 // Adds the dirty bit if |md5| indicates that the file is dirty, and |
| 197 // the file is in the persistent directory. | 197 // the file is in the persistent directory. |
| 198 if (md5 == util::kLocallyModifiedFileExtension) { | 198 if (md5 == util::kLocallyModifiedFileExtension) { |
| 199 if (sub_dir_type == GDataCache::CACHE_TYPE_PERSISTENT) { | 199 if (sub_dir_type == DriveCache::CACHE_TYPE_PERSISTENT) { |
| 200 cache_entry.set_is_dirty(true); | 200 cache_entry.set_is_dirty(true); |
| 201 } else { | 201 } else { |
| 202 LOG(WARNING) << "Removing a dirty file in tmp directory: " | 202 LOG(WARNING) << "Removing a dirty file in tmp directory: " |
| 203 << current.value(); | 203 << current.value(); |
| 204 file_util::Delete(current, false); | 204 file_util::Delete(current, false); |
| 205 continue; | 205 continue; |
| 206 } | 206 } |
| 207 } | 207 } |
| 208 } | 208 } |
| 209 } else { | 209 } else { |
| 210 NOTREACHED() << "Unexpected sub directory type: " << sub_dir_type; | 210 NOTREACHED() << "Unexpected sub directory type: " << sub_dir_type; |
| 211 } | 211 } |
| 212 | 212 |
| 213 // Create and insert new entry into cache map. | 213 // Create and insert new entry into cache map. |
| 214 cache_map->insert(std::make_pair(resource_id, cache_entry)); | 214 cache_map->insert(std::make_pair(resource_id, cache_entry)); |
| 215 processed_file_map->insert(std::make_pair(resource_id, current)); | 215 processed_file_map->insert(std::make_pair(resource_id, current)); |
| 216 } | 216 } |
| 217 } | 217 } |
| 218 | 218 |
| 219 void ScanCachePaths(const std::vector<FilePath>& cache_paths, | 219 void ScanCachePaths(const std::vector<FilePath>& cache_paths, |
| 220 GDataCacheMetadata::CacheMap* cache_map) { | 220 DriveCacheMetadata::CacheMap* cache_map) { |
| 221 DVLOG(1) << "Scanning directories"; | 221 DVLOG(1) << "Scanning directories"; |
| 222 | 222 |
| 223 // Scan cache persistent and tmp directories to enumerate all files and create | 223 // Scan cache persistent and tmp directories to enumerate all files and create |
| 224 // corresponding entries for cache map. | 224 // corresponding entries for cache map. |
| 225 ResourceIdToFilePathMap persistent_file_map; | 225 ResourceIdToFilePathMap persistent_file_map; |
| 226 ScanCacheDirectory(cache_paths, | 226 ScanCacheDirectory(cache_paths, |
| 227 GDataCache::CACHE_TYPE_PERSISTENT, | 227 DriveCache::CACHE_TYPE_PERSISTENT, |
| 228 cache_map, | 228 cache_map, |
| 229 &persistent_file_map); | 229 &persistent_file_map); |
| 230 ResourceIdToFilePathMap tmp_file_map; | 230 ResourceIdToFilePathMap tmp_file_map; |
| 231 ScanCacheDirectory(cache_paths, | 231 ScanCacheDirectory(cache_paths, |
| 232 GDataCache::CACHE_TYPE_TMP, | 232 DriveCache::CACHE_TYPE_TMP, |
| 233 cache_map, | 233 cache_map, |
| 234 &tmp_file_map); | 234 &tmp_file_map); |
| 235 | 235 |
| 236 // Then scan pinned directory to update existing entries in cache map, or | 236 // Then scan pinned directory to update existing entries in cache map, or |
| 237 // create new ones for pinned symlinks to /dev/null which target nothing. | 237 // create new ones for pinned symlinks to /dev/null which target nothing. |
| 238 // | 238 // |
| 239 // Pinned directory should be scanned after the persistent directory as | 239 // Pinned directory should be scanned after the persistent directory as |
| 240 // we'll add PINNED states to the existing files in the persistent | 240 // we'll add PINNED states to the existing files in the persistent |
| 241 // directory per the contents of the pinned directory. | 241 // directory per the contents of the pinned directory. |
| 242 ResourceIdToFilePathMap pinned_file_map; | 242 ResourceIdToFilePathMap pinned_file_map; |
| 243 ScanCacheDirectory(cache_paths, | 243 ScanCacheDirectory(cache_paths, |
| 244 GDataCache::CACHE_TYPE_PINNED, | 244 DriveCache::CACHE_TYPE_PINNED, |
| 245 cache_map, | 245 cache_map, |
| 246 &pinned_file_map); | 246 &pinned_file_map); |
| 247 // Then scan outgoing directory to check if dirty-files are committed | 247 // Then scan outgoing directory to check if dirty-files are committed |
| 248 // properly (i.e. symlinks created in outgoing directory). | 248 // properly (i.e. symlinks created in outgoing directory). |
| 249 ResourceIdToFilePathMap outgoing_file_map; | 249 ResourceIdToFilePathMap outgoing_file_map; |
| 250 ScanCacheDirectory(cache_paths, | 250 ScanCacheDirectory(cache_paths, |
| 251 GDataCache::CACHE_TYPE_OUTGOING, | 251 DriveCache::CACHE_TYPE_OUTGOING, |
| 252 cache_map, | 252 cache_map, |
| 253 &outgoing_file_map); | 253 &outgoing_file_map); |
| 254 | 254 |
| 255 RemoveInvalidFilesFromPersistentDirectory(persistent_file_map, | 255 RemoveInvalidFilesFromPersistentDirectory(persistent_file_map, |
| 256 outgoing_file_map, | 256 outgoing_file_map, |
| 257 cache_map); | 257 cache_map); |
| 258 DVLOG(1) << "Directory scan finished"; | 258 DVLOG(1) << "Directory scan finished"; |
| 259 } | 259 } |
| 260 | 260 |
| 261 // Returns true if |md5| matches the one in |cache_entry| with some | 261 // Returns true if |md5| matches the one in |cache_entry| with some |
| (...skipping 15 matching lines...) Expand all Loading... |
| 277 // If the MD5 matching is not requested, don't check MD5. | 277 // If the MD5 matching is not requested, don't check MD5. |
| 278 return true; | 278 return true; |
| 279 } else if (md5 == cache_entry.md5()) { | 279 } else if (md5 == cache_entry.md5()) { |
| 280 // Otherwise, compare the MD5. | 280 // Otherwise, compare the MD5. |
| 281 return true; | 281 return true; |
| 282 } | 282 } |
| 283 return false; | 283 return false; |
| 284 } | 284 } |
| 285 | 285 |
| 286 //////////////////////////////////////////////////////////////////////////////// | 286 //////////////////////////////////////////////////////////////////////////////// |
| 287 // GDataCacheMetadata implementation with std::map. | 287 // DriveCacheMetadata implementation with std::map. |
| 288 // Used for testing. | 288 // Used for testing. |
| 289 | 289 |
| 290 class FakeGDataCacheMetadata : public GDataCacheMetadata { | 290 class FakeDriveCacheMetadata : public DriveCacheMetadata { |
| 291 public: | 291 public: |
| 292 explicit FakeGDataCacheMetadata( | 292 explicit FakeDriveCacheMetadata( |
| 293 base::SequencedTaskRunner* blocking_task_runner); | 293 base::SequencedTaskRunner* blocking_task_runner); |
| 294 | 294 |
| 295 private: | 295 private: |
| 296 virtual ~FakeGDataCacheMetadata(); | 296 virtual ~FakeDriveCacheMetadata(); |
| 297 | 297 |
| 298 // GDataCacheMetadata overrides: | 298 // DriveCacheMetadata overrides: |
| 299 virtual void Initialize(const std::vector<FilePath>& cache_paths) OVERRIDE; | 299 virtual void Initialize(const std::vector<FilePath>& cache_paths) OVERRIDE; |
| 300 virtual void AddOrUpdateCacheEntry( | 300 virtual void AddOrUpdateCacheEntry( |
| 301 const std::string& resource_id, | 301 const std::string& resource_id, |
| 302 const DriveCacheEntry& cache_entry) OVERRIDE; | 302 const DriveCacheEntry& cache_entry) OVERRIDE; |
| 303 virtual void RemoveCacheEntry(const std::string& resource_id) OVERRIDE; | 303 virtual void RemoveCacheEntry(const std::string& resource_id) OVERRIDE; |
| 304 virtual bool GetCacheEntry(const std::string& resource_id, | 304 virtual bool GetCacheEntry(const std::string& resource_id, |
| 305 const std::string& md5, | 305 const std::string& md5, |
| 306 DriveCacheEntry* cache_entry) OVERRIDE; | 306 DriveCacheEntry* cache_entry) OVERRIDE; |
| 307 virtual void RemoveTemporaryFiles() OVERRIDE; | 307 virtual void RemoveTemporaryFiles() OVERRIDE; |
| 308 virtual void Iterate(const IterateCallback& callback) OVERRIDE; | 308 virtual void Iterate(const IterateCallback& callback) OVERRIDE; |
| 309 virtual void ForceRescanForTesting( | 309 virtual void ForceRescanForTesting( |
| 310 const std::vector<FilePath>& cache_paths) OVERRIDE; | 310 const std::vector<FilePath>& cache_paths) OVERRIDE; |
| 311 | 311 |
| 312 CacheMap cache_map_; | 312 CacheMap cache_map_; |
| 313 | 313 |
| 314 DISALLOW_COPY_AND_ASSIGN(FakeGDataCacheMetadata); | 314 DISALLOW_COPY_AND_ASSIGN(FakeDriveCacheMetadata); |
| 315 }; | 315 }; |
| 316 | 316 |
| 317 FakeGDataCacheMetadata::FakeGDataCacheMetadata( | 317 FakeDriveCacheMetadata::FakeDriveCacheMetadata( |
| 318 base::SequencedTaskRunner* blocking_task_runner) | 318 base::SequencedTaskRunner* blocking_task_runner) |
| 319 : GDataCacheMetadata(blocking_task_runner) { | 319 : DriveCacheMetadata(blocking_task_runner) { |
| 320 AssertOnSequencedWorkerPool(); | 320 AssertOnSequencedWorkerPool(); |
| 321 } | 321 } |
| 322 | 322 |
| 323 FakeGDataCacheMetadata::~FakeGDataCacheMetadata() { | 323 FakeDriveCacheMetadata::~FakeDriveCacheMetadata() { |
| 324 AssertOnSequencedWorkerPool(); | 324 AssertOnSequencedWorkerPool(); |
| 325 } | 325 } |
| 326 | 326 |
| 327 void FakeGDataCacheMetadata::Initialize( | 327 void FakeDriveCacheMetadata::Initialize( |
| 328 const std::vector<FilePath>& cache_paths) { | 328 const std::vector<FilePath>& cache_paths) { |
| 329 AssertOnSequencedWorkerPool(); | 329 AssertOnSequencedWorkerPool(); |
| 330 | 330 |
| 331 ScanCachePaths(cache_paths, &cache_map_); | 331 ScanCachePaths(cache_paths, &cache_map_); |
| 332 } | 332 } |
| 333 | 333 |
| 334 void FakeGDataCacheMetadata::AddOrUpdateCacheEntry( | 334 void FakeDriveCacheMetadata::AddOrUpdateCacheEntry( |
| 335 const std::string& resource_id, | 335 const std::string& resource_id, |
| 336 const DriveCacheEntry& cache_entry) { | 336 const DriveCacheEntry& cache_entry) { |
| 337 AssertOnSequencedWorkerPool(); | 337 AssertOnSequencedWorkerPool(); |
| 338 | 338 |
| 339 CacheMap::iterator iter = cache_map_.find(resource_id); | 339 CacheMap::iterator iter = cache_map_.find(resource_id); |
| 340 if (iter == cache_map_.end()) { // New resource, create new entry. | 340 if (iter == cache_map_.end()) { // New resource, create new entry. |
| 341 cache_map_.insert(std::make_pair(resource_id, cache_entry)); | 341 cache_map_.insert(std::make_pair(resource_id, cache_entry)); |
| 342 } else { // Resource exists. | 342 } else { // Resource exists. |
| 343 cache_map_[resource_id] = cache_entry; | 343 cache_map_[resource_id] = cache_entry; |
| 344 } | 344 } |
| 345 } | 345 } |
| 346 | 346 |
| 347 void FakeGDataCacheMetadata::RemoveCacheEntry(const std::string& resource_id) { | 347 void FakeDriveCacheMetadata::RemoveCacheEntry(const std::string& resource_id) { |
| 348 AssertOnSequencedWorkerPool(); | 348 AssertOnSequencedWorkerPool(); |
| 349 | 349 |
| 350 CacheMap::iterator iter = cache_map_.find(resource_id); | 350 CacheMap::iterator iter = cache_map_.find(resource_id); |
| 351 if (iter != cache_map_.end()) { | 351 if (iter != cache_map_.end()) { |
| 352 // Delete the CacheEntry and remove it from the map. | 352 // Delete the CacheEntry and remove it from the map. |
| 353 cache_map_.erase(iter); | 353 cache_map_.erase(iter); |
| 354 } | 354 } |
| 355 } | 355 } |
| 356 | 356 |
| 357 bool FakeGDataCacheMetadata::GetCacheEntry(const std::string& resource_id, | 357 bool FakeDriveCacheMetadata::GetCacheEntry(const std::string& resource_id, |
| 358 const std::string& md5, | 358 const std::string& md5, |
| 359 DriveCacheEntry* entry) { | 359 DriveCacheEntry* entry) { |
| 360 DCHECK(entry); | 360 DCHECK(entry); |
| 361 AssertOnSequencedWorkerPool(); | 361 AssertOnSequencedWorkerPool(); |
| 362 | 362 |
| 363 CacheMap::iterator iter = cache_map_.find(resource_id); | 363 CacheMap::iterator iter = cache_map_.find(resource_id); |
| 364 if (iter == cache_map_.end()) { | 364 if (iter == cache_map_.end()) { |
| 365 DVLOG(1) << "Can't find " << resource_id << " in cache map"; | 365 DVLOG(1) << "Can't find " << resource_id << " in cache map"; |
| 366 return false; | 366 return false; |
| 367 } | 367 } |
| 368 | 368 |
| 369 const DriveCacheEntry& cache_entry = iter->second; | 369 const DriveCacheEntry& cache_entry = iter->second; |
| 370 | 370 |
| 371 if (!CheckIfMd5Matches(md5, cache_entry)) { | 371 if (!CheckIfMd5Matches(md5, cache_entry)) { |
| 372 return false; | 372 return false; |
| 373 } | 373 } |
| 374 | 374 |
| 375 *entry = cache_entry; | 375 *entry = cache_entry; |
| 376 return true; | 376 return true; |
| 377 } | 377 } |
| 378 | 378 |
| 379 void FakeGDataCacheMetadata::RemoveTemporaryFiles() { | 379 void FakeDriveCacheMetadata::RemoveTemporaryFiles() { |
| 380 AssertOnSequencedWorkerPool(); | 380 AssertOnSequencedWorkerPool(); |
| 381 | 381 |
| 382 CacheMap::iterator iter = cache_map_.begin(); | 382 CacheMap::iterator iter = cache_map_.begin(); |
| 383 while (iter != cache_map_.end()) { | 383 while (iter != cache_map_.end()) { |
| 384 if (!iter->second.is_persistent()) { | 384 if (!iter->second.is_persistent()) { |
| 385 // Post-increment the iterator to avoid iterator invalidation. | 385 // Post-increment the iterator to avoid iterator invalidation. |
| 386 cache_map_.erase(iter++); | 386 cache_map_.erase(iter++); |
| 387 } else { | 387 } else { |
| 388 ++iter; | 388 ++iter; |
| 389 } | 389 } |
| 390 } | 390 } |
| 391 } | 391 } |
| 392 | 392 |
| 393 void FakeGDataCacheMetadata::Iterate(const IterateCallback& callback) { | 393 void FakeDriveCacheMetadata::Iterate(const IterateCallback& callback) { |
| 394 AssertOnSequencedWorkerPool(); | 394 AssertOnSequencedWorkerPool(); |
| 395 | 395 |
| 396 for (CacheMap::const_iterator iter = cache_map_.begin(); | 396 for (CacheMap::const_iterator iter = cache_map_.begin(); |
| 397 iter != cache_map_.end(); ++iter) { | 397 iter != cache_map_.end(); ++iter) { |
| 398 callback.Run(iter->first, iter->second); | 398 callback.Run(iter->first, iter->second); |
| 399 } | 399 } |
| 400 } | 400 } |
| 401 | 401 |
| 402 void FakeGDataCacheMetadata::ForceRescanForTesting( | 402 void FakeDriveCacheMetadata::ForceRescanForTesting( |
| 403 const std::vector<FilePath>& cache_paths) { | 403 const std::vector<FilePath>& cache_paths) { |
| 404 AssertOnSequencedWorkerPool(); | 404 AssertOnSequencedWorkerPool(); |
| 405 | 405 |
| 406 ScanCachePaths(cache_paths, &cache_map_); | 406 ScanCachePaths(cache_paths, &cache_map_); |
| 407 } | 407 } |
| 408 | 408 |
| 409 //////////////////////////////////////////////////////////////////////////////// | 409 //////////////////////////////////////////////////////////////////////////////// |
| 410 // GDataCacheMetadata implementation with level::db. | 410 // DriveCacheMetadata implementation with level::db. |
| 411 | 411 |
| 412 class GDataCacheMetadataDB : public GDataCacheMetadata { | 412 class DriveCacheMetadataDB : public DriveCacheMetadata { |
| 413 public: | 413 public: |
| 414 explicit GDataCacheMetadataDB( | 414 explicit DriveCacheMetadataDB( |
| 415 base::SequencedTaskRunner* blocking_task_runner); | 415 base::SequencedTaskRunner* blocking_task_runner); |
| 416 | 416 |
| 417 private: | 417 private: |
| 418 virtual ~GDataCacheMetadataDB(); | 418 virtual ~DriveCacheMetadataDB(); |
| 419 | 419 |
| 420 // GDataCacheMetadata overrides: | 420 // DriveCacheMetadata overrides: |
| 421 virtual void Initialize(const std::vector<FilePath>& cache_paths) OVERRIDE; | 421 virtual void Initialize(const std::vector<FilePath>& cache_paths) OVERRIDE; |
| 422 virtual void AddOrUpdateCacheEntry( | 422 virtual void AddOrUpdateCacheEntry( |
| 423 const std::string& resource_id, | 423 const std::string& resource_id, |
| 424 const DriveCacheEntry& cache_entry) OVERRIDE; | 424 const DriveCacheEntry& cache_entry) OVERRIDE; |
| 425 virtual void RemoveCacheEntry(const std::string& resource_id) OVERRIDE; | 425 virtual void RemoveCacheEntry(const std::string& resource_id) OVERRIDE; |
| 426 virtual bool GetCacheEntry(const std::string& resource_id, | 426 virtual bool GetCacheEntry(const std::string& resource_id, |
| 427 const std::string& md5, | 427 const std::string& md5, |
| 428 DriveCacheEntry* cache_entry) OVERRIDE; | 428 DriveCacheEntry* cache_entry) OVERRIDE; |
| 429 virtual void RemoveTemporaryFiles() OVERRIDE; | 429 virtual void RemoveTemporaryFiles() OVERRIDE; |
| 430 virtual void Iterate(const IterateCallback& callback) OVERRIDE; | 430 virtual void Iterate(const IterateCallback& callback) OVERRIDE; |
| 431 virtual void ForceRescanForTesting( | 431 virtual void ForceRescanForTesting( |
| 432 const std::vector<FilePath>& cache_paths) OVERRIDE; | 432 const std::vector<FilePath>& cache_paths) OVERRIDE; |
| 433 | 433 |
| 434 // Helper function to insert |cache_map| entries into the database. | 434 // Helper function to insert |cache_map| entries into the database. |
| 435 void InsertMapIntoDB(const CacheMap& cache_map); | 435 void InsertMapIntoDB(const CacheMap& cache_map); |
| 436 | 436 |
| 437 scoped_ptr<leveldb::DB> level_db_; | 437 scoped_ptr<leveldb::DB> level_db_; |
| 438 | 438 |
| 439 DISALLOW_COPY_AND_ASSIGN(GDataCacheMetadataDB); | 439 DISALLOW_COPY_AND_ASSIGN(DriveCacheMetadataDB); |
| 440 }; | 440 }; |
| 441 | 441 |
| 442 GDataCacheMetadataDB::GDataCacheMetadataDB( | 442 DriveCacheMetadataDB::DriveCacheMetadataDB( |
| 443 base::SequencedTaskRunner* blocking_task_runner) | 443 base::SequencedTaskRunner* blocking_task_runner) |
| 444 : GDataCacheMetadata(blocking_task_runner) { | 444 : DriveCacheMetadata(blocking_task_runner) { |
| 445 AssertOnSequencedWorkerPool(); | 445 AssertOnSequencedWorkerPool(); |
| 446 } | 446 } |
| 447 | 447 |
| 448 GDataCacheMetadataDB::~GDataCacheMetadataDB() { | 448 DriveCacheMetadataDB::~DriveCacheMetadataDB() { |
| 449 AssertOnSequencedWorkerPool(); | 449 AssertOnSequencedWorkerPool(); |
| 450 } | 450 } |
| 451 | 451 |
| 452 void GDataCacheMetadataDB::Initialize( | 452 void DriveCacheMetadataDB::Initialize( |
| 453 const std::vector<FilePath>& cache_paths) { | 453 const std::vector<FilePath>& cache_paths) { |
| 454 AssertOnSequencedWorkerPool(); | 454 AssertOnSequencedWorkerPool(); |
| 455 | 455 |
| 456 const FilePath db_path = | 456 const FilePath db_path = |
| 457 cache_paths[GDataCache::CACHE_TYPE_META].Append( | 457 cache_paths[DriveCache::CACHE_TYPE_META].Append( |
| 458 kGDataCacheMetadataDBPath); | 458 kDriveCacheMetadataDBPath); |
| 459 DVLOG(1) << "db path=" << db_path.value(); | 459 DVLOG(1) << "db path=" << db_path.value(); |
| 460 | 460 |
| 461 const bool db_exists = file_util::PathExists(db_path); | 461 const bool db_exists = file_util::PathExists(db_path); |
| 462 | 462 |
| 463 leveldb::DB* level_db = NULL; | 463 leveldb::DB* level_db = NULL; |
| 464 leveldb::Options options; | 464 leveldb::Options options; |
| 465 options.create_if_missing = true; | 465 options.create_if_missing = true; |
| 466 leveldb::Status db_status = leveldb::DB::Open(options, db_path.value(), | 466 leveldb::Status db_status = leveldb::DB::Open(options, db_path.value(), |
| 467 &level_db); | 467 &level_db); |
| 468 DCHECK(level_db); | 468 DCHECK(level_db); |
| 469 // TODO(achuith,hashimoto,satorux): If db cannot be opened, we should try to | 469 // TODO(achuith,hashimoto,satorux): If db cannot be opened, we should try to |
| 470 // recover it. If that fails, we should just delete it and either rescan or | 470 // recover it. If that fails, we should just delete it and either rescan or |
| 471 // refetch the feed. crbug.com/137545. | 471 // refetch the feed. crbug.com/137545. |
| 472 DCHECK(db_status.ok()); | 472 DCHECK(db_status.ok()); |
| 473 level_db_.reset(level_db); | 473 level_db_.reset(level_db); |
| 474 | 474 |
| 475 // We scan the cache directories to initialize the cache database if we | 475 // We scan the cache directories to initialize the cache database if we |
| 476 // were previously using the cache map. | 476 // were previously using the cache map. |
| 477 // TODO(achuith,hashimoto,satorux): Delete ScanCachePaths in M23. | 477 // TODO(achuith,hashimoto,satorux): Delete ScanCachePaths in M23. |
| 478 // crbug.com/137542 | 478 // crbug.com/137542 |
| 479 if (!db_exists) { | 479 if (!db_exists) { |
| 480 CacheMap cache_map; | 480 CacheMap cache_map; |
| 481 ScanCachePaths(cache_paths, &cache_map); | 481 ScanCachePaths(cache_paths, &cache_map); |
| 482 InsertMapIntoDB(cache_map); | 482 InsertMapIntoDB(cache_map); |
| 483 } | 483 } |
| 484 } | 484 } |
| 485 | 485 |
| 486 void GDataCacheMetadataDB::InsertMapIntoDB(const CacheMap& cache_map) { | 486 void DriveCacheMetadataDB::InsertMapIntoDB(const CacheMap& cache_map) { |
| 487 DVLOG(1) << "InsertMapIntoDB"; | 487 DVLOG(1) << "InsertMapIntoDB"; |
| 488 for (CacheMap::const_iterator it = cache_map.begin(); | 488 for (CacheMap::const_iterator it = cache_map.begin(); |
| 489 it != cache_map.end(); ++it) { | 489 it != cache_map.end(); ++it) { |
| 490 AddOrUpdateCacheEntry(it->first, it->second); | 490 AddOrUpdateCacheEntry(it->first, it->second); |
| 491 } | 491 } |
| 492 } | 492 } |
| 493 | 493 |
| 494 void GDataCacheMetadataDB::AddOrUpdateCacheEntry( | 494 void DriveCacheMetadataDB::AddOrUpdateCacheEntry( |
| 495 const std::string& resource_id, | 495 const std::string& resource_id, |
| 496 const DriveCacheEntry& cache_entry) { | 496 const DriveCacheEntry& cache_entry) { |
| 497 AssertOnSequencedWorkerPool(); | 497 AssertOnSequencedWorkerPool(); |
| 498 | 498 |
| 499 DVLOG(1) << "AddOrUpdateCacheEntry, resource_id=" << resource_id; | 499 DVLOG(1) << "AddOrUpdateCacheEntry, resource_id=" << resource_id; |
| 500 std::string serialized; | 500 std::string serialized; |
| 501 const bool ok = cache_entry.SerializeToString(&serialized); | 501 const bool ok = cache_entry.SerializeToString(&serialized); |
| 502 if (ok) | 502 if (ok) |
| 503 level_db_->Put(leveldb::WriteOptions(), | 503 level_db_->Put(leveldb::WriteOptions(), |
| 504 leveldb::Slice(resource_id), | 504 leveldb::Slice(resource_id), |
| 505 leveldb::Slice(serialized)); | 505 leveldb::Slice(serialized)); |
| 506 } | 506 } |
| 507 | 507 |
| 508 void GDataCacheMetadataDB::RemoveCacheEntry(const std::string& resource_id) { | 508 void DriveCacheMetadataDB::RemoveCacheEntry(const std::string& resource_id) { |
| 509 AssertOnSequencedWorkerPool(); | 509 AssertOnSequencedWorkerPool(); |
| 510 | 510 |
| 511 DVLOG(1) << "RemoveCacheEntry, resource_id=" << resource_id; | 511 DVLOG(1) << "RemoveCacheEntry, resource_id=" << resource_id; |
| 512 level_db_->Delete(leveldb::WriteOptions(), leveldb::Slice(resource_id)); | 512 level_db_->Delete(leveldb::WriteOptions(), leveldb::Slice(resource_id)); |
| 513 } | 513 } |
| 514 | 514 |
| 515 bool GDataCacheMetadataDB::GetCacheEntry(const std::string& resource_id, | 515 bool DriveCacheMetadataDB::GetCacheEntry(const std::string& resource_id, |
| 516 const std::string& md5, | 516 const std::string& md5, |
| 517 DriveCacheEntry* entry) { | 517 DriveCacheEntry* entry) { |
| 518 DCHECK(entry); | 518 DCHECK(entry); |
| 519 AssertOnSequencedWorkerPool(); | 519 AssertOnSequencedWorkerPool(); |
| 520 | 520 |
| 521 std::string serialized; | 521 std::string serialized; |
| 522 const leveldb::Status status = level_db_->Get(leveldb::ReadOptions(), | 522 const leveldb::Status status = level_db_->Get(leveldb::ReadOptions(), |
| 523 leveldb::Slice(resource_id), &serialized); | 523 leveldb::Slice(resource_id), &serialized); |
| 524 if (!status.ok()) { | 524 if (!status.ok()) { |
| 525 DVLOG(1) << "Can't find " << resource_id << " in cache db"; | 525 DVLOG(1) << "Can't find " << resource_id << " in cache db"; |
| 526 return false; | 526 return false; |
| 527 } | 527 } |
| 528 | 528 |
| 529 DriveCacheEntry cache_entry; | 529 DriveCacheEntry cache_entry; |
| 530 const bool ok = cache_entry.ParseFromString(serialized); | 530 const bool ok = cache_entry.ParseFromString(serialized); |
| 531 if (!ok) { | 531 if (!ok) { |
| 532 LOG(ERROR) << "Failed to parse " << serialized; | 532 LOG(ERROR) << "Failed to parse " << serialized; |
| 533 return false; | 533 return false; |
| 534 } | 534 } |
| 535 | 535 |
| 536 if (!CheckIfMd5Matches(md5, cache_entry)) { | 536 if (!CheckIfMd5Matches(md5, cache_entry)) { |
| 537 return false; | 537 return false; |
| 538 } | 538 } |
| 539 | 539 |
| 540 *entry = cache_entry; | 540 *entry = cache_entry; |
| 541 return true; | 541 return true; |
| 542 } | 542 } |
| 543 | 543 |
| 544 void GDataCacheMetadataDB::RemoveTemporaryFiles() { | 544 void DriveCacheMetadataDB::RemoveTemporaryFiles() { |
| 545 AssertOnSequencedWorkerPool(); | 545 AssertOnSequencedWorkerPool(); |
| 546 | 546 |
| 547 scoped_ptr<leveldb::Iterator> iter(level_db_->NewIterator( | 547 scoped_ptr<leveldb::Iterator> iter(level_db_->NewIterator( |
| 548 leveldb::ReadOptions())); | 548 leveldb::ReadOptions())); |
| 549 for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { | 549 for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { |
| 550 DriveCacheEntry cache_entry; | 550 DriveCacheEntry cache_entry; |
| 551 const bool ok = cache_entry.ParseFromString(iter->value().ToString()); | 551 const bool ok = cache_entry.ParseFromString(iter->value().ToString()); |
| 552 if (ok && !cache_entry.is_persistent()) | 552 if (ok && !cache_entry.is_persistent()) |
| 553 level_db_->Delete(leveldb::WriteOptions(), iter->key()); | 553 level_db_->Delete(leveldb::WriteOptions(), iter->key()); |
| 554 } | 554 } |
| 555 } | 555 } |
| 556 | 556 |
| 557 void GDataCacheMetadataDB::Iterate(const IterateCallback& callback) { | 557 void DriveCacheMetadataDB::Iterate(const IterateCallback& callback) { |
| 558 AssertOnSequencedWorkerPool(); | 558 AssertOnSequencedWorkerPool(); |
| 559 | 559 |
| 560 scoped_ptr<leveldb::Iterator> iter(level_db_->NewIterator( | 560 scoped_ptr<leveldb::Iterator> iter(level_db_->NewIterator( |
| 561 leveldb::ReadOptions())); | 561 leveldb::ReadOptions())); |
| 562 for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { | 562 for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { |
| 563 DriveCacheEntry cache_entry; | 563 DriveCacheEntry cache_entry; |
| 564 const bool ok = cache_entry.ParseFromString(iter->value().ToString()); | 564 const bool ok = cache_entry.ParseFromString(iter->value().ToString()); |
| 565 if (ok) | 565 if (ok) |
| 566 callback.Run(iter->key().ToString(), cache_entry); | 566 callback.Run(iter->key().ToString(), cache_entry); |
| 567 } | 567 } |
| 568 } | 568 } |
| 569 | 569 |
| 570 void GDataCacheMetadataDB::ForceRescanForTesting( | 570 void DriveCacheMetadataDB::ForceRescanForTesting( |
| 571 const std::vector<FilePath>& cache_paths) { | 571 const std::vector<FilePath>& cache_paths) { |
| 572 AssertOnSequencedWorkerPool(); | 572 AssertOnSequencedWorkerPool(); |
| 573 | 573 |
| 574 CacheMap cache_map; | 574 CacheMap cache_map; |
| 575 ScanCachePaths(cache_paths, &cache_map); | 575 ScanCachePaths(cache_paths, &cache_map); |
| 576 InsertMapIntoDB(cache_map); | 576 InsertMapIntoDB(cache_map); |
| 577 } | 577 } |
| 578 | 578 |
| 579 } // namespace | 579 } // namespace |
| 580 | 580 |
| 581 GDataCacheMetadata::GDataCacheMetadata( | 581 DriveCacheMetadata::DriveCacheMetadata( |
| 582 base::SequencedTaskRunner* blocking_task_runner) | 582 base::SequencedTaskRunner* blocking_task_runner) |
| 583 : blocking_task_runner_(blocking_task_runner) { | 583 : blocking_task_runner_(blocking_task_runner) { |
| 584 AssertOnSequencedWorkerPool(); | 584 AssertOnSequencedWorkerPool(); |
| 585 } | 585 } |
| 586 | 586 |
| 587 GDataCacheMetadata::~GDataCacheMetadata() { | 587 DriveCacheMetadata::~DriveCacheMetadata() { |
| 588 AssertOnSequencedWorkerPool(); | 588 AssertOnSequencedWorkerPool(); |
| 589 } | 589 } |
| 590 | 590 |
| 591 // static | 591 // static |
| 592 scoped_ptr<GDataCacheMetadata> GDataCacheMetadata::CreateGDataCacheMetadata( | 592 scoped_ptr<DriveCacheMetadata> DriveCacheMetadata::CreateDriveCacheMetadata( |
| 593 base::SequencedTaskRunner* blocking_task_runner) { | 593 base::SequencedTaskRunner* blocking_task_runner) { |
| 594 return scoped_ptr<GDataCacheMetadata>( | 594 return scoped_ptr<DriveCacheMetadata>( |
| 595 new GDataCacheMetadataDB(blocking_task_runner)); | 595 new DriveCacheMetadataDB(blocking_task_runner)); |
| 596 } | 596 } |
| 597 | 597 |
| 598 // static | 598 // static |
| 599 scoped_ptr<GDataCacheMetadata> | 599 scoped_ptr<DriveCacheMetadata> |
| 600 GDataCacheMetadata::CreateGDataCacheMetadataForTesting( | 600 DriveCacheMetadata::CreateDriveCacheMetadataForTesting( |
| 601 base::SequencedTaskRunner* blocking_task_runner) { | 601 base::SequencedTaskRunner* blocking_task_runner) { |
| 602 return scoped_ptr<GDataCacheMetadata>( | 602 return scoped_ptr<DriveCacheMetadata>( |
| 603 new FakeGDataCacheMetadata(blocking_task_runner)); | 603 new FakeDriveCacheMetadata(blocking_task_runner)); |
| 604 } | 604 } |
| 605 | 605 |
| 606 void GDataCacheMetadata::AssertOnSequencedWorkerPool() { | 606 void DriveCacheMetadata::AssertOnSequencedWorkerPool() { |
| 607 DCHECK(!blocking_task_runner_ || | 607 DCHECK(!blocking_task_runner_ || |
| 608 blocking_task_runner_->RunsTasksOnCurrentThread()); | 608 blocking_task_runner_->RunsTasksOnCurrentThread()); |
| 609 } | 609 } |
| 610 | 610 |
| 611 } // namespace gdata | 611 } // namespace gdata |
| OLD | NEW |