| 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 GDataCache::CacheSubDirectoryType subdir, | 188 int cache_state) { |
| 189 int cache_state) { | |
| 190 AssertOnSequencedWorkerPool(); | 189 AssertOnSequencedWorkerPool(); |
| 191 | 190 |
| 192 CacheMap::iterator iter = cache_map_.find(resource_id); | 191 CacheMap::iterator iter = cache_map_.find(resource_id); |
| 193 if (iter == cache_map_.end()) { // New resource, create new entry. | 192 if (iter == cache_map_.end()) { // New resource, create new entry. |
| 194 // Makes no sense to create new entry if cache state is NONE. | 193 // Makes no sense to create new entry if cache state is NONE. |
| 195 DCHECK(cache_state != GDataCache::CACHE_STATE_NONE); | 194 DCHECK(cache_state != GDataCache::CACHE_STATE_NONE); |
| 196 if (cache_state != GDataCache::CACHE_STATE_NONE) { | 195 if (cache_state != GDataCache::CACHE_STATE_NONE) { |
| 197 GDataCache::CacheEntry cache_entry(md5, subdir, cache_state); | 196 GDataCache::CacheEntry cache_entry(md5, cache_state); |
| 198 cache_map_.insert(std::make_pair(resource_id, cache_entry)); | 197 cache_map_.insert(std::make_pair(resource_id, cache_entry)); |
| 199 DVLOG(1) << "Added res_id=" << resource_id | 198 DVLOG(1) << "Added res_id=" << resource_id |
| 200 << ", " << cache_entry.ToString(); | 199 << ", " << cache_entry.ToString(); |
| 201 } | 200 } |
| 202 } else { // Resource exists. | 201 } else { // Resource exists. |
| 203 // If cache state is NONE, delete entry from cache map. | 202 // If cache state is NONE, delete entry from cache map. |
| 204 if (cache_state == GDataCache::CACHE_STATE_NONE) { | 203 if (cache_state == GDataCache::CACHE_STATE_NONE) { |
| 205 DVLOG(1) << "Deleting res_id=" << resource_id | 204 DVLOG(1) << "Deleting res_id=" << resource_id |
| 206 << ", " << iter->second.ToString(); | 205 << ", " << iter->second.ToString(); |
| 207 cache_map_.erase(iter); | 206 cache_map_.erase(iter); |
| 208 } else { // Otherwise, update entry in cache map. | 207 } else { // Otherwise, update entry in cache map. |
| 209 iter->second.md5 = md5; | 208 iter->second.md5 = md5; |
| 210 iter->second.sub_dir_type = subdir; | |
| 211 iter->second.cache_state = cache_state; | 209 iter->second.cache_state = cache_state; |
| 212 DVLOG(1) << "Updated res_id=" << resource_id | 210 DVLOG(1) << "Updated res_id=" << resource_id |
| 213 << ", " << iter->second.ToString(); | 211 << ", " << iter->second.ToString(); |
| 214 } | 212 } |
| 215 } | 213 } |
| 216 } | 214 } |
| 217 | 215 |
| 218 void GDataCacheMetadataMap::RemoveFromCache(const std::string& resource_id) { | 216 void GDataCacheMetadataMap::RemoveFromCache(const std::string& resource_id) { |
| 219 AssertOnSequencedWorkerPool(); | 217 AssertOnSequencedWorkerPool(); |
| 220 | 218 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 251 << ", " << cache_entry->ToString(); | 249 << ", " << cache_entry->ToString(); |
| 252 | 250 |
| 253 return cache_entry.Pass(); | 251 return cache_entry.Pass(); |
| 254 } | 252 } |
| 255 | 253 |
| 256 void GDataCacheMetadataMap::RemoveTemporaryFiles() { | 254 void GDataCacheMetadataMap::RemoveTemporaryFiles() { |
| 257 AssertOnSequencedWorkerPool(); | 255 AssertOnSequencedWorkerPool(); |
| 258 | 256 |
| 259 CacheMap::iterator iter = cache_map_.begin(); | 257 CacheMap::iterator iter = cache_map_.begin(); |
| 260 while (iter != cache_map_.end()) { | 258 while (iter != cache_map_.end()) { |
| 261 if (iter->second.sub_dir_type == GDataCache::CACHE_TYPE_TMP) { | 259 if (!iter->second.IsPersistent()) { |
| 262 // Post-increment the iterator to avoid iterator invalidation. | 260 // Post-increment the iterator to avoid iterator invalidation. |
| 263 cache_map_.erase(iter++); | 261 cache_map_.erase(iter++); |
| 264 } else { | 262 } else { |
| 265 ++iter; | 263 ++iter; |
| 266 } | 264 } |
| 267 } | 265 } |
| 268 } | 266 } |
| 269 | 267 |
| 270 void GDataCacheMetadataMap::Iterate(const IterateCallback& callback) { | 268 void GDataCacheMetadataMap::Iterate(const IterateCallback& callback) { |
| 271 AssertOnSequencedWorkerPool(); | 269 AssertOnSequencedWorkerPool(); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 LOG(WARNING) << "Removing an symlink to a non-dirty file: " | 345 LOG(WARNING) << "Removing an symlink to a non-dirty file: " |
| 348 << current.value(); | 346 << current.value(); |
| 349 file_util::Delete(current, false); | 347 file_util::Delete(current, false); |
| 350 continue; | 348 continue; |
| 351 } | 349 } |
| 352 | 350 |
| 353 processed_file_map->insert(std::make_pair(resource_id, current)); | 351 processed_file_map->insert(std::make_pair(resource_id, current)); |
| 354 continue; | 352 continue; |
| 355 } else if (sub_dir_type == GDataCache::CACHE_TYPE_PERSISTENT || | 353 } else if (sub_dir_type == GDataCache::CACHE_TYPE_PERSISTENT || |
| 356 sub_dir_type == GDataCache::CACHE_TYPE_TMP) { | 354 sub_dir_type == GDataCache::CACHE_TYPE_TMP) { |
| 355 if (sub_dir_type == GDataCache::CACHE_TYPE_PERSISTENT) |
| 356 cache_state = GDataCache::SetCachePersistent(cache_state); |
| 357 |
| 357 if (file_util::IsLink(current)) { | 358 if (file_util::IsLink(current)) { |
| 358 LOG(WARNING) << "Removing a symlink in persistent/tmp directory" | 359 LOG(WARNING) << "Removing a symlink in persistent/tmp directory" |
| 359 << current.value(); | 360 << current.value(); |
| 360 file_util::Delete(current, false); | 361 file_util::Delete(current, false); |
| 361 continue; | 362 continue; |
| 362 } | 363 } |
| 363 if (extra_extension == util::kMountedArchiveFileExtension) { | 364 if (extra_extension == util::kMountedArchiveFileExtension) { |
| 364 // Mounted archives in cache should be unmounted upon logout/shutdown. | 365 // Mounted archives in cache should be unmounted upon logout/shutdown. |
| 365 // But if we encounter a mounted file at start, delete it and create an | 366 // But if we encounter a mounted file at start, delete it and create an |
| 366 // entry with not PRESENT state. | 367 // entry with not PRESENT state. |
| 367 DCHECK(sub_dir_type == GDataCache::CACHE_TYPE_PERSISTENT); | 368 DCHECK(sub_dir_type == GDataCache::CACHE_TYPE_PERSISTENT); |
| 368 file_util::Delete(current, false); | 369 file_util::Delete(current, false); |
| 369 } else { | 370 } else { |
| 370 // The cache file is present. | 371 // The cache file is present. |
| 371 cache_state = GDataCache::SetCachePresent(cache_state); | 372 cache_state = GDataCache::SetCachePresent(cache_state); |
| 372 | 373 |
| 373 // Adds the dirty bit if |md5| indicates that the file is dirty, and | 374 // Adds the dirty bit if |md5| indicates that the file is dirty, and |
| 374 // the file is in the persistent directory. | 375 // the file is in the persistent directory. |
| 375 if (md5 == util::kLocallyModifiedFileExtension) { | 376 if (md5 == util::kLocallyModifiedFileExtension) { |
| 376 if (sub_dir_type == GDataCache::CACHE_TYPE_PERSISTENT) { | 377 if (sub_dir_type == GDataCache::CACHE_TYPE_PERSISTENT) { |
| 377 cache_state |= GDataCache::SetCacheDirty(cache_state); | 378 cache_state = GDataCache::SetCacheDirty(cache_state); |
| 378 } else { | 379 } else { |
| 379 LOG(WARNING) << "Removing a dirty file in tmp directory: " | 380 LOG(WARNING) << "Removing a dirty file in tmp directory: " |
| 380 << current.value(); | 381 << current.value(); |
| 381 file_util::Delete(current, false); | 382 file_util::Delete(current, false); |
| 382 continue; | 383 continue; |
| 383 } | 384 } |
| 384 } | 385 } |
| 385 } | 386 } |
| 386 } else { | 387 } else { |
| 387 NOTREACHED() << "Unexpected sub directory type: " << sub_dir_type; | 388 NOTREACHED() << "Unexpected sub directory type: " << sub_dir_type; |
| 388 } | 389 } |
| 389 | 390 |
| 390 // Create and insert new entry into cache map. | 391 // Create and insert new entry into cache map. |
| 391 cache_map->insert(std::make_pair( | 392 cache_map->insert(std::make_pair( |
| 392 resource_id, GDataCache::CacheEntry( | 393 resource_id, GDataCache::CacheEntry(md5, cache_state))); |
| 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 |