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/gdata_cache_metadata.h" |
6 | 6 |
7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
8 #include "chrome/browser/chromeos/gdata/gdata_util.h" | 8 #include "chrome/browser/chromeos/gdata/gdata_util.h" |
9 | 9 |
10 namespace gdata { | 10 namespace gdata { |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 &cache_map_, | 177 &cache_map_, |
178 &outgoing_file_map); | 178 &outgoing_file_map); |
179 | 179 |
180 RemoveInvalidFilesFromPersistentDirectory(persistent_file_map, | 180 RemoveInvalidFilesFromPersistentDirectory(persistent_file_map, |
181 outgoing_file_map, | 181 outgoing_file_map, |
182 &cache_map_); | 182 &cache_map_); |
183 DVLOG(1) << "Directory scan finished"; | 183 DVLOG(1) << "Directory scan finished"; |
184 } | 184 } |
185 | 185 |
186 void GDataCacheMetadataMap::UpdateCache(const std::string& resource_id, | 186 void GDataCacheMetadataMap::UpdateCache(const std::string& resource_id, |
187 const std::string& md5, | 187 const std::string& md5, |
188 int cache_state) { | 188 GDataCache::CacheSubDirectoryType subdir, |
| 189 int cache_state) { |
189 AssertOnSequencedWorkerPool(); | 190 AssertOnSequencedWorkerPool(); |
190 | 191 |
191 CacheMap::iterator iter = cache_map_.find(resource_id); | 192 CacheMap::iterator iter = cache_map_.find(resource_id); |
192 if (iter == cache_map_.end()) { // New resource, create new entry. | 193 if (iter == cache_map_.end()) { // New resource, create new entry. |
193 // Makes no sense to create new entry if cache state is NONE. | 194 // Makes no sense to create new entry if cache state is NONE. |
194 DCHECK(cache_state != GDataCache::CACHE_STATE_NONE); | 195 DCHECK(cache_state != GDataCache::CACHE_STATE_NONE); |
195 if (cache_state != GDataCache::CACHE_STATE_NONE) { | 196 if (cache_state != GDataCache::CACHE_STATE_NONE) { |
196 GDataCache::CacheEntry cache_entry(md5, cache_state); | 197 GDataCache::CacheEntry cache_entry(md5, subdir, cache_state); |
197 cache_map_.insert(std::make_pair(resource_id, cache_entry)); | 198 cache_map_.insert(std::make_pair(resource_id, cache_entry)); |
198 DVLOG(1) << "Added res_id=" << resource_id | 199 DVLOG(1) << "Added res_id=" << resource_id |
199 << ", " << cache_entry.ToString(); | 200 << ", " << cache_entry.ToString(); |
200 } | 201 } |
201 } else { // Resource exists. | 202 } else { // Resource exists. |
202 // If cache state is NONE, delete entry from cache map. | 203 // If cache state is NONE, delete entry from cache map. |
203 if (cache_state == GDataCache::CACHE_STATE_NONE) { | 204 if (cache_state == GDataCache::CACHE_STATE_NONE) { |
204 DVLOG(1) << "Deleting res_id=" << resource_id | 205 DVLOG(1) << "Deleting res_id=" << resource_id |
205 << ", " << iter->second.ToString(); | 206 << ", " << iter->second.ToString(); |
206 cache_map_.erase(iter); | 207 cache_map_.erase(iter); |
207 } else { // Otherwise, update entry in cache map. | 208 } else { // Otherwise, update entry in cache map. |
208 iter->second.md5 = md5; | 209 iter->second.md5 = md5; |
| 210 iter->second.sub_dir_type = subdir; |
209 iter->second.cache_state = cache_state; | 211 iter->second.cache_state = cache_state; |
210 DVLOG(1) << "Updated res_id=" << resource_id | 212 DVLOG(1) << "Updated res_id=" << resource_id |
211 << ", " << iter->second.ToString(); | 213 << ", " << iter->second.ToString(); |
212 } | 214 } |
213 } | 215 } |
214 } | 216 } |
215 | 217 |
216 void GDataCacheMetadataMap::RemoveFromCache(const std::string& resource_id) { | 218 void GDataCacheMetadataMap::RemoveFromCache(const std::string& resource_id) { |
217 AssertOnSequencedWorkerPool(); | 219 AssertOnSequencedWorkerPool(); |
218 | 220 |
(...skipping 30 matching lines...) Expand all Loading... |
249 << ", " << cache_entry->ToString(); | 251 << ", " << cache_entry->ToString(); |
250 | 252 |
251 return cache_entry.Pass(); | 253 return cache_entry.Pass(); |
252 } | 254 } |
253 | 255 |
254 void GDataCacheMetadataMap::RemoveTemporaryFiles() { | 256 void GDataCacheMetadataMap::RemoveTemporaryFiles() { |
255 AssertOnSequencedWorkerPool(); | 257 AssertOnSequencedWorkerPool(); |
256 | 258 |
257 CacheMap::iterator iter = cache_map_.begin(); | 259 CacheMap::iterator iter = cache_map_.begin(); |
258 while (iter != cache_map_.end()) { | 260 while (iter != cache_map_.end()) { |
259 if (!iter->second.IsPersistent()) { | 261 if (iter->second.sub_dir_type == GDataCache::CACHE_TYPE_TMP) { |
260 // Post-increment the iterator to avoid iterator invalidation. | 262 // Post-increment the iterator to avoid iterator invalidation. |
261 cache_map_.erase(iter++); | 263 cache_map_.erase(iter++); |
262 } else { | 264 } else { |
263 ++iter; | 265 ++iter; |
264 } | 266 } |
265 } | 267 } |
266 } | 268 } |
267 | 269 |
268 void GDataCacheMetadataMap::Iterate(const IterateCallback& callback) { | 270 void GDataCacheMetadataMap::Iterate(const IterateCallback& callback) { |
269 AssertOnSequencedWorkerPool(); | 271 AssertOnSequencedWorkerPool(); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 LOG(WARNING) << "Removing an symlink to a non-dirty file: " | 347 LOG(WARNING) << "Removing an symlink to a non-dirty file: " |
346 << current.value(); | 348 << current.value(); |
347 file_util::Delete(current, false); | 349 file_util::Delete(current, false); |
348 continue; | 350 continue; |
349 } | 351 } |
350 | 352 |
351 processed_file_map->insert(std::make_pair(resource_id, current)); | 353 processed_file_map->insert(std::make_pair(resource_id, current)); |
352 continue; | 354 continue; |
353 } else if (sub_dir_type == GDataCache::CACHE_TYPE_PERSISTENT || | 355 } else if (sub_dir_type == GDataCache::CACHE_TYPE_PERSISTENT || |
354 sub_dir_type == GDataCache::CACHE_TYPE_TMP) { | 356 sub_dir_type == GDataCache::CACHE_TYPE_TMP) { |
355 if (sub_dir_type == GDataCache::CACHE_TYPE_PERSISTENT) | |
356 cache_state = GDataCache::SetCachePersistent(cache_state); | |
357 | |
358 if (file_util::IsLink(current)) { | 357 if (file_util::IsLink(current)) { |
359 LOG(WARNING) << "Removing a symlink in persistent/tmp directory" | 358 LOG(WARNING) << "Removing a symlink in persistent/tmp directory" |
360 << current.value(); | 359 << current.value(); |
361 file_util::Delete(current, false); | 360 file_util::Delete(current, false); |
362 continue; | 361 continue; |
363 } | 362 } |
364 if (extra_extension == util::kMountedArchiveFileExtension) { | 363 if (extra_extension == util::kMountedArchiveFileExtension) { |
365 // Mounted archives in cache should be unmounted upon logout/shutdown. | 364 // Mounted archives in cache should be unmounted upon logout/shutdown. |
366 // But if we encounter a mounted file at start, delete it and create an | 365 // But if we encounter a mounted file at start, delete it and create an |
367 // entry with not PRESENT state. | 366 // entry with not PRESENT state. |
368 DCHECK(sub_dir_type == GDataCache::CACHE_TYPE_PERSISTENT); | 367 DCHECK(sub_dir_type == GDataCache::CACHE_TYPE_PERSISTENT); |
369 file_util::Delete(current, false); | 368 file_util::Delete(current, false); |
370 } else { | 369 } else { |
371 // The cache file is present. | 370 // The cache file is present. |
372 cache_state = GDataCache::SetCachePresent(cache_state); | 371 cache_state = GDataCache::SetCachePresent(cache_state); |
373 | 372 |
374 // Adds the dirty bit if |md5| indicates that the file is dirty, and | 373 // Adds the dirty bit if |md5| indicates that the file is dirty, and |
375 // the file is in the persistent directory. | 374 // the file is in the persistent directory. |
376 if (md5 == util::kLocallyModifiedFileExtension) { | 375 if (md5 == util::kLocallyModifiedFileExtension) { |
377 if (sub_dir_type == GDataCache::CACHE_TYPE_PERSISTENT) { | 376 if (sub_dir_type == GDataCache::CACHE_TYPE_PERSISTENT) { |
378 cache_state = GDataCache::SetCacheDirty(cache_state); | 377 cache_state |= GDataCache::SetCacheDirty(cache_state); |
379 } else { | 378 } else { |
380 LOG(WARNING) << "Removing a dirty file in tmp directory: " | 379 LOG(WARNING) << "Removing a dirty file in tmp directory: " |
381 << current.value(); | 380 << current.value(); |
382 file_util::Delete(current, false); | 381 file_util::Delete(current, false); |
383 continue; | 382 continue; |
384 } | 383 } |
385 } | 384 } |
386 } | 385 } |
387 } else { | 386 } else { |
388 NOTREACHED() << "Unexpected sub directory type: " << sub_dir_type; | 387 NOTREACHED() << "Unexpected sub directory type: " << sub_dir_type; |
389 } | 388 } |
390 | 389 |
391 // Create and insert new entry into cache map. | 390 // Create and insert new entry into cache map. |
392 cache_map->insert(std::make_pair( | 391 cache_map->insert(std::make_pair( |
393 resource_id, GDataCache::CacheEntry(md5, cache_state))); | 392 resource_id, GDataCache::CacheEntry( |
| 393 md5, real_sub_dir_type, cache_state))); |
394 processed_file_map->insert(std::make_pair(resource_id, current)); | 394 processed_file_map->insert(std::make_pair(resource_id, current)); |
395 } | 395 } |
396 } | 396 } |
397 | 397 |
398 // static | 398 // static |
399 bool GDataCacheMetadataMap::CheckIfMd5Matches( | 399 bool GDataCacheMetadataMap::CheckIfMd5Matches( |
400 const std::string& md5, | 400 const std::string& md5, |
401 const GDataCache::CacheEntry& cache_entry) { | 401 const GDataCache::CacheEntry& cache_entry) { |
402 if (cache_entry.IsDirty()) { | 402 if (cache_entry.IsDirty()) { |
403 // If the entry is dirty, its MD5 may have been replaced by "local" | 403 // If the entry is dirty, its MD5 may have been replaced by "local" |
404 // during cache initialization, so we don't compare MD5. | 404 // during cache initialization, so we don't compare MD5. |
405 return true; | 405 return true; |
406 } else if (cache_entry.IsPinned() && cache_entry.md5.empty()) { | 406 } else if (cache_entry.IsPinned() && cache_entry.md5.empty()) { |
407 // If the entry is pinned, it's ok for the entry to have an empty | 407 // If the entry is pinned, it's ok for the entry to have an empty |
408 // MD5. This can happen if the pinned file is not fetched. MD5 for pinned | 408 // MD5. This can happen if the pinned file is not fetched. MD5 for pinned |
409 // files are collected from files in "persistent" directory, but the | 409 // files are collected from files in "persistent" directory, but the |
410 // persistent files do not exisit if these are not fetched yet. | 410 // persistent files do not exisit if these are not fetched yet. |
411 return true; | 411 return true; |
412 } else if (md5.empty()) { | 412 } else if (md5.empty()) { |
413 // If the MD5 matching is not requested, don't check MD5. | 413 // If the MD5 matching is not requested, don't check MD5. |
414 return true; | 414 return true; |
415 } else if (md5 == cache_entry.md5) { | 415 } else if (md5 == cache_entry.md5) { |
416 // Otherwise, compare the MD5. | 416 // Otherwise, compare the MD5. |
417 return true; | 417 return true; |
418 } | 418 } |
419 return false; | 419 return false; |
420 } | 420 } |
421 | 421 |
422 } // namespace gdata | 422 } // namespace gdata |
OLD | NEW |