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

Side by Side Diff: chrome/browser/chromeos/gdata/drive_cache_metadata.cc

Issue 10877005: Rename GDataCache* to DriveCache* (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase. Created 8 years, 4 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 | Annotate | Revision Log
OLDNEW
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
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
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/gdata/drive_cache_metadata.h ('k') | chrome/browser/chromeos/gdata/drive_cache_metadata_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698