Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "content/browser/cache_storage/cache_storage.h" | 5 #include "content/browser/cache_storage/cache_storage.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <set> | 9 #include <set> |
| 10 #include <string> | 10 #include <string> |
| 11 #include <unordered_map> | |
| 11 #include <utility> | 12 #include <utility> |
| 12 | 13 |
| 13 #include "base/barrier_closure.h" | 14 #include "base/barrier_closure.h" |
| 14 #include "base/files/file_util.h" | 15 #include "base/files/file_util.h" |
| 15 #include "base/files/memory_mapped_file.h" | 16 #include "base/files/memory_mapped_file.h" |
| 16 #include "base/guid.h" | 17 #include "base/guid.h" |
| 17 #include "base/location.h" | 18 #include "base/location.h" |
| 18 #include "base/memory/ptr_util.h" | 19 #include "base/memory/ptr_util.h" |
| 19 #include "base/memory/ref_counted.h" | 20 #include "base/memory/ref_counted.h" |
| 20 #include "base/metrics/histogram_macros.h" | 21 #include "base/metrics/histogram_macros.h" |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 40 | 41 |
| 41 namespace { | 42 namespace { |
| 42 | 43 |
| 43 std::string HexedHash(const std::string& value) { | 44 std::string HexedHash(const std::string& value) { |
| 44 std::string value_hash = base::SHA1HashString(value); | 45 std::string value_hash = base::SHA1HashString(value); |
| 45 std::string valued_hexed_hash = base::ToLowerASCII( | 46 std::string valued_hexed_hash = base::ToLowerASCII( |
| 46 base::HexEncode(value_hash.c_str(), value_hash.length())); | 47 base::HexEncode(value_hash.c_str(), value_hash.length())); |
| 47 return valued_hexed_hash; | 48 return valued_hexed_hash; |
| 48 } | 49 } |
| 49 | 50 |
| 50 void SizeRetrievedFromCache( | |
| 51 std::unique_ptr<CacheStorageCacheHandle> cache_handle, | |
| 52 const base::Closure& closure, | |
| 53 int64_t* accumulator, | |
| 54 int64_t size) { | |
| 55 *accumulator += size; | |
| 56 closure.Run(); | |
| 57 } | |
| 58 | |
| 59 void SizeRetrievedFromAllCaches(std::unique_ptr<int64_t> accumulator, | 51 void SizeRetrievedFromAllCaches(std::unique_ptr<int64_t> accumulator, |
| 60 const CacheStorage::SizeCallback& callback) { | 52 const CacheStorage::SizeCallback& callback) { |
| 61 base::ThreadTaskRunnerHandle::Get()->PostTask( | 53 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 62 FROM_HERE, base::Bind(callback, *accumulator)); | 54 FROM_HERE, base::Bind(callback, *accumulator)); |
| 63 } | 55 } |
| 64 | 56 |
| 57 void DoNothingWithBool(bool success) {} | |
| 58 | |
| 65 } // namespace | 59 } // namespace |
| 66 | 60 |
| 67 const char CacheStorage::kIndexFileName[] = "index.txt"; | 61 const char CacheStorage::kIndexFileName[] = "index.txt"; |
| 62 const int64_t CacheStorage::kSizeUnknown; | |
| 68 | 63 |
| 69 struct CacheStorage::CacheMatchResponse { | 64 struct CacheStorage::CacheMatchResponse { |
| 70 CacheMatchResponse() = default; | 65 CacheMatchResponse() = default; |
| 71 ~CacheMatchResponse() = default; | 66 ~CacheMatchResponse() = default; |
| 72 | 67 |
| 73 CacheStorageError error; | 68 CacheStorageError error; |
| 74 std::unique_ptr<ServiceWorkerResponse> service_worker_response; | 69 std::unique_ptr<ServiceWorkerResponse> service_worker_response; |
| 75 std::unique_ptr<storage::BlobDataHandle> blob_data_handle; | 70 std::unique_ptr<storage::BlobDataHandle> blob_data_handle; |
| 76 }; | 71 }; |
| 77 | 72 |
| 73 class CacheStorage::CacheStorageIndex { | |
|
jkarlin
2016/10/21 19:24:39
Let's put this in its own file with its own unit t
cmumford
2016/11/10 17:28:16
Do you still want this to be an inner class of Cac
jkarlin
2016/11/11 18:24:56
The protobuf should be in package (read namespace)
| |
| 74 public: | |
| 75 CacheStorageIndex(const CacheStorageIndex& other) { | |
| 76 for (const auto& cache_info : other.ordered_cache_info_) | |
| 77 Insert(cache_info); | |
| 78 } | |
| 79 | |
| 80 CacheStorageIndex() = default; | |
| 81 | |
| 82 ~CacheStorageIndex() = default; | |
| 83 | |
| 84 CacheStorageIndex& operator=(CacheStorageIndex&& rhs) { | |
| 85 ordered_cache_info_ = std::move(rhs.ordered_cache_info_); | |
| 86 cache_info_map_ = std::move(rhs.cache_info_map_); | |
| 87 storage_size_ = rhs.storage_size_; | |
| 88 storage_size_dirty_ = rhs.storage_size_dirty_; | |
| 89 return *this; | |
| 90 } | |
| 91 | |
| 92 void Insert(const CacheInfo& cache_info) { | |
| 93 DCHECK(cache_info_map_.find(cache_info.name) == cache_info_map_.end()); | |
| 94 ordered_cache_info_.push_back(cache_info); | |
| 95 cache_info_map_[cache_info.name] = --ordered_cache_info_.end(); | |
| 96 storage_size_dirty_ = true; | |
| 97 } | |
| 98 | |
| 99 void Delete(const std::string& cache_name) { | |
| 100 auto it = cache_info_map_.find(cache_name); | |
| 101 DCHECK(it != cache_info_map_.end()); | |
| 102 ordered_cache_info_.erase(it->second); | |
| 103 cache_info_map_.erase(it); | |
| 104 storage_size_dirty_ = true; | |
| 105 } | |
| 106 | |
| 107 // Sets the cache size. Returns true if the new size is different than the | |
| 108 // current size else false. | |
| 109 bool SetCacheSize(const std::string& cache_name, int64_t size) { | |
| 110 auto it = cache_info_map_.find(cache_name); | |
| 111 if (it == cache_info_map_.end()) { | |
| 112 // Deleted (but still referenced) caches can still run. | |
| 113 return false; | |
| 114 } | |
| 115 if (it->second->size == size) | |
| 116 return false; | |
| 117 it->second->size = size; | |
| 118 storage_size_dirty_ = true; | |
| 119 return true; | |
| 120 } | |
| 121 | |
| 122 // The cache was modified, increasing/decreasing cache size by |size_delta|. | |
| 123 void SetCacheSizeModified(const std::string& cache_name, int64_t size_delta) { | |
| 124 DCHECK_NE(size_delta, 0); | |
| 125 | |
| 126 auto it = cache_info_map_.find(cache_name); | |
| 127 if (it == cache_info_map_.end()) { | |
| 128 // Deleted (but still referenced) caches can still run. | |
| 129 return; | |
| 130 } | |
| 131 DCHECK_NE(it->second->size, kSizeUnknown); | |
| 132 it->second->size += size_delta; | |
| 133 DCHECK_GE(it->second->size, 0U); | |
| 134 if (storage_size_dirty_ || storage_size_ == kSizeUnknown) | |
| 135 return; | |
| 136 DCHECK_NE(storage_size_, kSizeUnknown); | |
| 137 storage_size_ += size_delta; | |
| 138 DCHECK_GE(storage_size_, 0U); | |
| 139 } | |
| 140 | |
| 141 int64_t GetCacheSize(const std::string& cache_name) const { | |
| 142 const auto& it = cache_info_map_.find(cache_name); | |
| 143 if (it == cache_info_map_.end()) | |
| 144 return kSizeUnknown; | |
| 145 return it->second->size; | |
| 146 } | |
| 147 | |
| 148 const std::list<CacheInfo>& ordered_cache_info() const { | |
| 149 return ordered_cache_info_; | |
| 150 } | |
| 151 | |
| 152 size_t num_entries() const { return ordered_cache_info_.size(); } | |
| 153 | |
| 154 int64_t GetStorageSize() { | |
| 155 if (storage_size_dirty_) | |
| 156 UpdateStorageSize(); | |
| 157 return storage_size_; | |
| 158 } | |
| 159 | |
| 160 private: | |
| 161 void UpdateStorageSize() { | |
| 162 DCHECK(storage_size_dirty_); | |
| 163 storage_size_dirty_ = false; | |
| 164 int64_t storage_size = 0; | |
| 165 storage_size_ = kSizeUnknown; | |
| 166 for (const CacheInfo& info : ordered_cache_info_) { | |
| 167 if (info.size == kSizeUnknown) | |
| 168 return; | |
| 169 storage_size += info.size; | |
| 170 } | |
| 171 storage_size_ = storage_size; | |
| 172 } | |
| 173 // Use a list to keep saved iterators valid during insert/erase. | |
| 174 // Note: ordered by cache creation. | |
| 175 std::list<CacheInfo> ordered_cache_info_; | |
| 176 std::unordered_map<std::string, std::list<CacheInfo>::iterator> | |
| 177 cache_info_map_; | |
| 178 | |
| 179 // The total size of all caches in this store. | |
| 180 int64_t storage_size_ = CacheStorage::kSizeUnknown; | |
| 181 bool storage_size_dirty_ = true; | |
| 182 }; | |
| 183 | |
| 78 // Handles the loading and clean up of CacheStorageCache objects. | 184 // Handles the loading and clean up of CacheStorageCache objects. |
| 79 class CacheStorage::CacheLoader { | 185 class CacheStorage::CacheLoader { |
| 80 public: | 186 public: |
| 81 typedef base::Callback<void(std::unique_ptr<CacheStorageCache>)> | 187 typedef base::Callback<void(std::unique_ptr<CacheStorageCache>)> |
| 82 CacheCallback; | 188 CacheCallback; |
| 83 typedef base::Callback<void(bool)> BoolCallback; | 189 typedef base::Callback<void(bool)> BoolCallback; |
| 84 typedef base::Callback<void(std::unique_ptr<std::vector<std::string>>)> | 190 using CacheStorageIndexCallback = |
| 85 StringVectorCallback; | 191 base::Callback<void(std::unique_ptr<CacheStorageIndex>)>; |
| 86 | 192 |
| 87 CacheLoader( | 193 CacheLoader( |
| 88 base::SequencedTaskRunner* cache_task_runner, | 194 base::SequencedTaskRunner* cache_task_runner, |
| 89 scoped_refptr<net::URLRequestContextGetter> request_context_getter, | 195 scoped_refptr<net::URLRequestContextGetter> request_context_getter, |
| 90 storage::QuotaManagerProxy* quota_manager_proxy, | 196 storage::QuotaManagerProxy* quota_manager_proxy, |
| 91 base::WeakPtr<storage::BlobStorageContext> blob_context, | 197 base::WeakPtr<storage::BlobStorageContext> blob_context, |
| 92 CacheStorage* cache_storage, | 198 CacheStorage* cache_storage, |
| 93 const GURL& origin) | 199 const GURL& origin) |
| 94 : cache_task_runner_(cache_task_runner), | 200 : cache_task_runner_(cache_task_runner), |
| 95 request_context_getter_(request_context_getter), | 201 request_context_getter_(request_context_getter), |
| 96 quota_manager_proxy_(quota_manager_proxy), | 202 quota_manager_proxy_(quota_manager_proxy), |
| 97 blob_context_(blob_context), | 203 blob_context_(blob_context), |
| 98 cache_storage_(cache_storage), | 204 cache_storage_(cache_storage), |
| 99 origin_(origin) { | 205 origin_(origin) { |
| 100 DCHECK(!origin_.is_empty()); | 206 DCHECK(!origin_.is_empty()); |
| 101 } | 207 } |
| 102 | 208 |
| 103 virtual ~CacheLoader() {} | 209 virtual ~CacheLoader() {} |
| 104 | 210 |
| 105 // Creates a CacheStorageCache with the given name. It does not attempt to | 211 // Creates a CacheStorageCache with the given name. It does not attempt to |
| 106 // load the backend, that happens lazily when the cache is used. | 212 // load the backend, that happens lazily when the cache is used. |
| 107 virtual std::unique_ptr<CacheStorageCache> CreateCache( | 213 virtual std::unique_ptr<CacheStorageCache> CreateCache( |
| 108 const std::string& cache_name) = 0; | 214 const std::string& cache_name, |
| 215 int64_t cache_size) = 0; | |
| 109 | 216 |
| 110 // Deletes any pre-existing cache of the same name and then loads it. | 217 // Deletes any pre-existing cache of the same name and then loads it. |
| 111 virtual void PrepareNewCacheDestination(const std::string& cache_name, | 218 virtual void PrepareNewCacheDestination(const std::string& cache_name, |
| 112 const CacheCallback& callback) = 0; | 219 const CacheCallback& callback) = 0; |
| 113 | 220 |
| 114 // After the backend has been deleted, do any extra house keeping such as | 221 // After the backend has been deleted, do any extra house keeping such as |
| 115 // removing the cache's directory. | 222 // removing the cache's directory. |
| 116 virtual void CleanUpDeletedCache(CacheStorageCache* cache) = 0; | 223 virtual void CleanUpDeletedCache(CacheStorageCache* cache) = 0; |
| 117 | 224 |
| 118 // Writes the cache names (and sizes) to disk if applicable. | 225 // Writes the cache index to disk if applicable. |
| 119 virtual void WriteIndex(const StringVector& cache_names, | 226 virtual void WriteIndex(const CacheStorageIndex* index, |
|
jkarlin
2016/10/21 19:24:39
Prefer const CacheStorageIndex& index
cmumford
2016/11/10 17:28:16
Done.
| |
| 120 const BoolCallback& callback) = 0; | 227 const BoolCallback& callback) = 0; |
| 121 | 228 |
| 122 // Loads the cache names from disk if applicable. | 229 // Loads the cache index from disk if applicable. |
| 123 virtual void LoadIndex(std::unique_ptr<std::vector<std::string>> cache_names, | 230 virtual void LoadIndex(const CacheStorageIndexCallback& callback) = 0; |
| 124 const StringVectorCallback& callback) = 0; | |
| 125 | 231 |
| 126 // Called when CacheStorage has created a cache. Used to hold onto a handle to | 232 // Called when CacheStorage has created a cache. Used to hold onto a handle to |
| 127 // the cache if necessary. | 233 // the cache if necessary. |
| 128 virtual void NotifyCacheCreated( | 234 virtual void NotifyCacheCreated( |
| 129 const std::string& cache_name, | 235 const std::string& cache_name, |
| 130 std::unique_ptr<CacheStorageCacheHandle> cache_handle) {} | 236 std::unique_ptr<CacheStorageCacheHandle> cache_handle) {} |
| 131 | 237 |
| 132 // Notification that the cache for |cache_handle| has been doomed. If the | 238 // Notification that the cache for |cache_handle| has been doomed. If the |
| 133 // loader is holding a handle to the cache, it should drop it now. | 239 // loader is holding a handle to the cache, it should drop it now. |
| 134 virtual void NotifyCacheDoomed( | 240 virtual void NotifyCacheDoomed( |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 161 base::WeakPtr<storage::BlobStorageContext> blob_context, | 267 base::WeakPtr<storage::BlobStorageContext> blob_context, |
| 162 CacheStorage* cache_storage, | 268 CacheStorage* cache_storage, |
| 163 const GURL& origin) | 269 const GURL& origin) |
| 164 : CacheLoader(cache_task_runner, | 270 : CacheLoader(cache_task_runner, |
| 165 request_context, | 271 request_context, |
| 166 quota_manager_proxy, | 272 quota_manager_proxy, |
| 167 blob_context, | 273 blob_context, |
| 168 cache_storage, | 274 cache_storage, |
| 169 origin) {} | 275 origin) {} |
| 170 | 276 |
| 171 std::unique_ptr<CacheStorageCache> CreateCache( | 277 std::unique_ptr<CacheStorageCache> CreateCache(const std::string& cache_name, |
| 172 const std::string& cache_name) override { | 278 int64_t cache_size) override { |
| 173 return CacheStorageCache::CreateMemoryCache( | 279 return CacheStorageCache::CreateMemoryCache( |
| 174 origin_, cache_name, cache_storage_, request_context_getter_, | 280 origin_, cache_name, cache_storage_, request_context_getter_, |
| 175 quota_manager_proxy_, blob_context_); | 281 quota_manager_proxy_, blob_context_); |
| 176 } | 282 } |
| 177 | 283 |
| 178 void PrepareNewCacheDestination(const std::string& cache_name, | 284 void PrepareNewCacheDestination(const std::string& cache_name, |
| 179 const CacheCallback& callback) override { | 285 const CacheCallback& callback) override { |
| 180 std::unique_ptr<CacheStorageCache> cache = CreateCache(cache_name); | 286 std::unique_ptr<CacheStorageCache> cache = |
| 287 CreateCache(cache_name, 0 /*cache_size*/); | |
| 181 callback.Run(std::move(cache)); | 288 callback.Run(std::move(cache)); |
| 182 } | 289 } |
| 183 | 290 |
| 184 void CleanUpDeletedCache(CacheStorageCache* cache) override {} | 291 void CleanUpDeletedCache(CacheStorageCache* cache) override {} |
| 185 | 292 |
| 186 void WriteIndex(const StringVector& cache_names, | 293 void WriteIndex(const CacheStorageIndex* index, |
| 187 const BoolCallback& callback) override { | 294 const BoolCallback& callback) override { |
| 188 callback.Run(true); | 295 callback.Run(true); |
| 189 } | 296 } |
| 190 | 297 |
| 191 void LoadIndex(std::unique_ptr<std::vector<std::string>> cache_names, | 298 void LoadIndex(const CacheStorageIndexCallback& callback) override { |
| 192 const StringVectorCallback& callback) override { | 299 callback.Run(base::MakeUnique<CacheStorageIndex>()); |
| 193 callback.Run(std::move(cache_names)); | |
| 194 } | 300 } |
| 195 | 301 |
| 196 void NotifyCacheCreated( | 302 void NotifyCacheCreated( |
| 197 const std::string& cache_name, | 303 const std::string& cache_name, |
| 198 std::unique_ptr<CacheStorageCacheHandle> cache_handle) override { | 304 std::unique_ptr<CacheStorageCacheHandle> cache_handle) override { |
| 199 DCHECK(!base::ContainsKey(cache_handles_, cache_name)); | 305 DCHECK(!base::ContainsKey(cache_handles_, cache_name)); |
| 200 cache_handles_.insert(std::make_pair(cache_name, std::move(cache_handle))); | 306 cache_handles_.insert(std::make_pair(cache_name, std::move(cache_handle))); |
| 201 }; | 307 }; |
| 202 | 308 |
| 203 void NotifyCacheDoomed( | 309 void NotifyCacheDoomed( |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 229 const GURL& origin) | 335 const GURL& origin) |
| 230 : CacheLoader(cache_task_runner, | 336 : CacheLoader(cache_task_runner, |
| 231 request_context, | 337 request_context, |
| 232 quota_manager_proxy, | 338 quota_manager_proxy, |
| 233 blob_context, | 339 blob_context, |
| 234 cache_storage, | 340 cache_storage, |
| 235 origin), | 341 origin), |
| 236 origin_path_(origin_path), | 342 origin_path_(origin_path), |
| 237 weak_ptr_factory_(this) {} | 343 weak_ptr_factory_(this) {} |
| 238 | 344 |
| 239 std::unique_ptr<CacheStorageCache> CreateCache( | 345 std::unique_ptr<CacheStorageCache> CreateCache(const std::string& cache_name, |
| 240 const std::string& cache_name) override { | 346 int64_t cache_size) override { |
| 241 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 347 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 242 DCHECK(base::ContainsKey(cache_name_to_cache_dir_, cache_name)); | 348 DCHECK(base::ContainsKey(cache_name_to_cache_dir_, cache_name)); |
| 243 | 349 |
| 244 std::string cache_dir = cache_name_to_cache_dir_[cache_name]; | 350 std::string cache_dir = cache_name_to_cache_dir_[cache_name]; |
| 245 base::FilePath cache_path = origin_path_.AppendASCII(cache_dir); | 351 base::FilePath cache_path = origin_path_.AppendASCII(cache_dir); |
| 246 return CacheStorageCache::CreatePersistentCache( | 352 return CacheStorageCache::CreatePersistentCache( |
| 247 origin_, cache_name, cache_storage_, cache_path, | 353 origin_, cache_name, cache_storage_, cache_path, |
| 248 request_context_getter_, quota_manager_proxy_, blob_context_); | 354 request_context_getter_, quota_manager_proxy_, blob_context_, |
| 355 cache_size); | |
| 249 } | 356 } |
| 250 | 357 |
| 251 void PrepareNewCacheDestination(const std::string& cache_name, | 358 void PrepareNewCacheDestination(const std::string& cache_name, |
| 252 const CacheCallback& callback) override { | 359 const CacheCallback& callback) override { |
| 253 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 360 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 254 | 361 |
| 255 PostTaskAndReplyWithResult( | 362 PostTaskAndReplyWithResult( |
| 256 cache_task_runner_.get(), FROM_HERE, | 363 cache_task_runner_.get(), FROM_HERE, |
| 257 base::Bind(&SimpleCacheLoader::PrepareNewCacheDirectoryInPool, | 364 base::Bind(&SimpleCacheLoader::PrepareNewCacheDirectoryInPool, |
| 258 origin_path_), | 365 origin_path_), |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 275 | 382 |
| 276 void PrepareNewCacheCreateCache(const std::string& cache_name, | 383 void PrepareNewCacheCreateCache(const std::string& cache_name, |
| 277 const CacheCallback& callback, | 384 const CacheCallback& callback, |
| 278 const std::string& cache_dir) { | 385 const std::string& cache_dir) { |
| 279 if (cache_dir.empty()) { | 386 if (cache_dir.empty()) { |
| 280 callback.Run(std::unique_ptr<CacheStorageCache>()); | 387 callback.Run(std::unique_ptr<CacheStorageCache>()); |
| 281 return; | 388 return; |
| 282 } | 389 } |
| 283 | 390 |
| 284 cache_name_to_cache_dir_[cache_name] = cache_dir; | 391 cache_name_to_cache_dir_[cache_name] = cache_dir; |
| 285 callback.Run(CreateCache(cache_name)); | 392 callback.Run(CreateCache(cache_name, CacheStorage::kSizeUnknown)); |
| 286 } | 393 } |
| 287 | 394 |
| 288 void CleanUpDeletedCache(CacheStorageCache* cache) override { | 395 void CleanUpDeletedCache(CacheStorageCache* cache) override { |
| 289 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 396 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 290 DCHECK(base::ContainsKey(doomed_cache_to_path_, cache)); | 397 DCHECK(base::ContainsKey(doomed_cache_to_path_, cache)); |
| 291 | 398 |
| 292 base::FilePath cache_path = | 399 base::FilePath cache_path = |
| 293 origin_path_.AppendASCII(doomed_cache_to_path_[cache]); | 400 origin_path_.AppendASCII(doomed_cache_to_path_[cache]); |
| 294 doomed_cache_to_path_.erase(cache); | 401 doomed_cache_to_path_.erase(cache); |
| 295 | 402 |
| 296 cache_task_runner_->PostTask( | 403 cache_task_runner_->PostTask( |
| 297 FROM_HERE, base::Bind(&SimpleCacheLoader::CleanUpDeleteCacheDirInPool, | 404 FROM_HERE, base::Bind(&SimpleCacheLoader::CleanUpDeleteCacheDirInPool, |
| 298 cache_path)); | 405 cache_path)); |
| 299 } | 406 } |
| 300 | 407 |
| 301 static void CleanUpDeleteCacheDirInPool(const base::FilePath& cache_path) { | 408 static void CleanUpDeleteCacheDirInPool(const base::FilePath& cache_path) { |
| 302 base::DeleteFile(cache_path, true /* recursive */); | 409 base::DeleteFile(cache_path, true /* recursive */); |
| 303 } | 410 } |
| 304 | 411 |
| 305 void WriteIndex(const StringVector& cache_names, | 412 void WriteIndex(const CacheStorageIndex* index, |
| 306 const BoolCallback& callback) override { | 413 const BoolCallback& callback) override { |
| 307 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 414 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 308 | 415 |
| 309 // 1. Create the index file as a string. (WriteIndex) | 416 // 1. Create the index file as a string. (WriteIndex) |
| 310 // 2. Write the file to disk. (WriteIndexWriteToFileInPool) | 417 // 2. Write the file to disk. (WriteIndexWriteToFileInPool) |
| 311 | 418 |
| 312 CacheStorageIndex index; | 419 content::CacheStorageIndex pb_index; |
| 313 index.set_origin(origin_.spec()); | 420 pb_index.set_origin(origin_.spec()); |
| 314 | 421 |
| 315 for (size_t i = 0u, max = cache_names.size(); i < max; ++i) { | 422 for (const auto& cache_info : index->ordered_cache_info()) { |
| 316 DCHECK(base::ContainsKey(cache_name_to_cache_dir_, cache_names[i])); | 423 DCHECK(base::ContainsKey(cache_name_to_cache_dir_, cache_info.name)); |
| 317 | 424 |
| 318 CacheStorageIndex::Cache* index_cache = index.add_cache(); | 425 content::CacheStorageIndex::Cache* index_cache = pb_index.add_cache(); |
| 319 index_cache->set_name(cache_names[i]); | 426 index_cache->set_name(cache_info.name); |
| 320 index_cache->set_cache_dir(cache_name_to_cache_dir_[cache_names[i]]); | 427 index_cache->set_cache_dir(cache_name_to_cache_dir_[cache_info.name]); |
| 428 if (cache_info.size == CacheStorage::kSizeUnknown) | |
| 429 index_cache->clear_size(); | |
| 430 else | |
| 431 index_cache->set_size(cache_info.size); | |
| 321 } | 432 } |
| 322 | 433 |
| 323 std::string serialized; | 434 std::string serialized; |
| 324 bool success = index.SerializeToString(&serialized); | 435 bool success = pb_index.SerializeToString(&serialized); |
| 325 DCHECK(success); | 436 DCHECK(success); |
| 326 | 437 |
| 327 base::FilePath tmp_path = origin_path_.AppendASCII("index.txt.tmp"); | 438 base::FilePath tmp_path = origin_path_.AppendASCII("index.txt.tmp"); |
| 328 base::FilePath index_path = | 439 base::FilePath index_path = |
| 329 origin_path_.AppendASCII(CacheStorage::kIndexFileName); | 440 origin_path_.AppendASCII(CacheStorage::kIndexFileName); |
| 330 | 441 |
| 331 PostTaskAndReplyWithResult( | 442 PostTaskAndReplyWithResult( |
| 332 cache_task_runner_.get(), FROM_HERE, | 443 cache_task_runner_.get(), FROM_HERE, |
| 333 base::Bind(&SimpleCacheLoader::WriteIndexWriteToFileInPool, tmp_path, | 444 base::Bind(&SimpleCacheLoader::WriteIndexWriteToFileInPool, tmp_path, |
| 334 index_path, serialized), | 445 index_path, serialized), |
| 335 callback); | 446 callback); |
| 336 } | 447 } |
| 337 | 448 |
| 338 static bool WriteIndexWriteToFileInPool(const base::FilePath& tmp_path, | 449 static bool WriteIndexWriteToFileInPool(const base::FilePath& tmp_path, |
| 339 const base::FilePath& index_path, | 450 const base::FilePath& index_path, |
| 340 const std::string& data) { | 451 const std::string& data) { |
| 341 int bytes_written = base::WriteFile(tmp_path, data.c_str(), data.size()); | 452 int bytes_written = base::WriteFile(tmp_path, data.c_str(), data.size()); |
| 342 if (bytes_written != base::checked_cast<int>(data.size())) { | 453 if (bytes_written != base::checked_cast<int>(data.size())) { |
| 343 base::DeleteFile(tmp_path, /* recursive */ false); | 454 base::DeleteFile(tmp_path, /* recursive */ false); |
| 344 return false; | 455 return false; |
| 345 } | 456 } |
| 346 | 457 |
| 347 // Atomically rename the temporary index file to become the real one. | 458 // Atomically rename the temporary index file to become the real one. |
| 348 return base::ReplaceFile(tmp_path, index_path, NULL); | 459 return base::ReplaceFile(tmp_path, index_path, NULL); |
| 349 } | 460 } |
| 350 | 461 |
| 351 void LoadIndex(std::unique_ptr<std::vector<std::string>> names, | 462 void LoadIndex(const CacheStorageIndexCallback& callback) override { |
| 352 const StringVectorCallback& callback) override { | |
| 353 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 463 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 354 | 464 |
| 355 // 1. Read the file from disk. (LoadIndexReadFileInPool) | |
| 356 // 2. Parse file and return the names of the caches (LoadIndexDidReadFile) | |
| 357 | |
| 358 base::FilePath index_path = | |
| 359 origin_path_.AppendASCII(CacheStorage::kIndexFileName); | |
| 360 | |
| 361 PostTaskAndReplyWithResult( | 465 PostTaskAndReplyWithResult( |
| 362 cache_task_runner_.get(), FROM_HERE, | 466 cache_task_runner_.get(), FROM_HERE, |
| 363 base::Bind(&SimpleCacheLoader::ReadAndMigrateIndexInPool, index_path), | 467 base::Bind(&SimpleCacheLoader::ReadAndMigrateIndexInPool, origin_path_), |
| 364 base::Bind(&SimpleCacheLoader::LoadIndexDidReadFile, | 468 base::Bind(&SimpleCacheLoader::LoadIndexDidReadIndex, |
| 365 weak_ptr_factory_.GetWeakPtr(), base::Passed(&names), | 469 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 366 callback)); | |
| 367 } | 470 } |
| 368 | 471 |
| 369 void LoadIndexDidReadFile(std::unique_ptr<std::vector<std::string>> names, | 472 void LoadIndexDidReadIndex(const CacheStorageIndexCallback& callback, |
| 370 const StringVectorCallback& callback, | 473 content::CacheStorageIndex pb_index) { |
| 371 const std::string& serialized) { | |
| 372 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 474 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 373 | 475 |
| 374 std::unique_ptr<std::set<std::string>> cache_dirs( | 476 std::unique_ptr<std::set<std::string>> cache_dirs( |
| 375 new std::set<std::string>); | 477 new std::set<std::string>); |
| 376 | 478 |
| 377 CacheStorageIndex index; | 479 auto index = base::MakeUnique<CacheStorageIndex>(); |
| 378 if (index.ParseFromString(serialized)) { | 480 for (int i = 0, max = pb_index.cache_size(); i < max; ++i) { |
| 379 for (int i = 0, max = index.cache_size(); i < max; ++i) { | 481 const content::CacheStorageIndex::Cache& cache = pb_index.cache(i); |
| 380 const CacheStorageIndex::Cache& cache = index.cache(i); | 482 DCHECK(cache.has_cache_dir()); |
| 381 DCHECK(cache.has_cache_dir()); | 483 int64_t cache_size = |
| 382 names->push_back(cache.name()); | 484 cache.has_size() ? cache.size() : CacheStorage::kSizeUnknown; |
| 383 cache_name_to_cache_dir_[cache.name()] = cache.cache_dir(); | 485 index->Insert(CacheInfo(cache.name(), cache_size)); |
| 384 cache_dirs->insert(cache.cache_dir()); | 486 cache_name_to_cache_dir_[cache.name()] = cache.cache_dir(); |
| 385 } | 487 cache_dirs->insert(cache.cache_dir()); |
| 386 } | 488 } |
| 387 | 489 |
| 388 cache_task_runner_->PostTask( | 490 cache_task_runner_->PostTask( |
| 389 FROM_HERE, base::Bind(&DeleteUnreferencedCachesInPool, origin_path_, | 491 FROM_HERE, base::Bind(&DeleteUnreferencedCachesInPool, origin_path_, |
| 390 base::Passed(&cache_dirs))); | 492 base::Passed(&cache_dirs))); |
| 391 callback.Run(std::move(names)); | 493 callback.Run(std::move(index)); |
| 392 } | 494 } |
| 393 | 495 |
| 394 void NotifyCacheDoomed( | 496 void NotifyCacheDoomed( |
| 395 std::unique_ptr<CacheStorageCacheHandle> cache_handle) override { | 497 std::unique_ptr<CacheStorageCacheHandle> cache_handle) override { |
| 396 DCHECK(base::ContainsKey(cache_name_to_cache_dir_, | 498 DCHECK(base::ContainsKey(cache_name_to_cache_dir_, |
| 397 cache_handle->value()->cache_name())); | 499 cache_handle->value()->cache_name())); |
| 398 auto iter = | 500 auto iter = |
| 399 cache_name_to_cache_dir_.find(cache_handle->value()->cache_name()); | 501 cache_name_to_cache_dir_.find(cache_handle->value()->cache_name()); |
| 400 doomed_cache_to_path_[cache_handle->value()] = iter->second; | 502 doomed_cache_to_path_[cache_handle->value()] = iter->second; |
| 401 cache_name_to_cache_dir_.erase(iter); | 503 cache_name_to_cache_dir_.erase(iter); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 417 while (!(cache_path = file_enum.Next()).empty()) { | 519 while (!(cache_path = file_enum.Next()).empty()) { |
| 418 if (!base::ContainsKey(*cache_dirs, cache_path.BaseName().AsUTF8Unsafe())) | 520 if (!base::ContainsKey(*cache_dirs, cache_path.BaseName().AsUTF8Unsafe())) |
| 419 dirs_to_delete.push_back(cache_path); | 521 dirs_to_delete.push_back(cache_path); |
| 420 } | 522 } |
| 421 | 523 |
| 422 for (const base::FilePath& cache_path : dirs_to_delete) | 524 for (const base::FilePath& cache_path : dirs_to_delete) |
| 423 base::DeleteFile(cache_path, true /* recursive */); | 525 base::DeleteFile(cache_path, true /* recursive */); |
| 424 } | 526 } |
| 425 | 527 |
| 426 // Runs on cache_task_runner_ | 528 // Runs on cache_task_runner_ |
| 427 static std::string MigrateCachesIfNecessaryInPool( | 529 static content::CacheStorageIndex ReadAndMigrateIndexInPool( |
| 428 const std::string& body, | 530 const base::FilePath& origin_path) { |
| 429 const base::FilePath& index_path) { | 531 const base::FilePath index_path = |
| 430 CacheStorageIndex index; | 532 origin_path.AppendASCII(CacheStorage::kIndexFileName); |
| 431 if (!index.ParseFromString(body)) | |
| 432 return body; | |
| 433 | 533 |
| 434 base::FilePath origin_path = index_path.DirName(); | 534 content::CacheStorageIndex index; |
| 435 bool index_is_dirty = false; | 535 std::string body; |
| 436 const std::string kBadIndexState(""); | 536 if (!base::ReadFileToString(index_path, &body) || |
| 537 !index.ParseFromString(body)) | |
| 538 return content::CacheStorageIndex(); | |
| 539 body.clear(); | |
| 540 | |
| 541 base::File::Info file_info; | |
| 542 base::Time index_last_modified; | |
| 543 if (GetFileInfo(index_path, &file_info)) | |
| 544 index_last_modified = file_info.last_modified; | |
| 545 bool index_modified = false; | |
| 437 | 546 |
| 438 // Look for caches that have no cache_dir. Give any such caches a directory | 547 // Look for caches that have no cache_dir. Give any such caches a directory |
| 439 // with a random name and move them there. Then, rewrite the index file. | 548 // with a random name and move them there. Then, rewrite the index file. |
| 440 for (int i = 0, max = index.cache_size(); i < max; ++i) { | 549 for (int i = 0, max = index.cache_size(); i < max; ++i) { |
| 441 const CacheStorageIndex::Cache& cache = index.cache(i); | 550 const content::CacheStorageIndex::Cache& cache = index.cache(i); |
| 442 if (!cache.has_cache_dir()) { | 551 if (cache.has_cache_dir()) { |
| 552 if (cache.has_size()) { | |
| 553 base::FilePath cache_dir = origin_path.AppendASCII(cache.cache_dir()); | |
| 554 if (!GetFileInfo(cache_dir, &file_info) || | |
| 555 index_last_modified <= file_info.last_modified) { | |
| 556 // Index is older than this cache, so invalidate index entries that | |
| 557 // may change as a result of cache operations. | |
| 558 index.mutable_cache(i)->clear_size(); | |
| 559 index_modified = true; | |
| 560 } | |
| 561 } | |
| 562 } else { | |
| 443 // Find a new home for the cache. | 563 // Find a new home for the cache. |
| 444 base::FilePath legacy_cache_path = | 564 base::FilePath legacy_cache_path = |
| 445 origin_path.AppendASCII(HexedHash(cache.name())); | 565 origin_path.AppendASCII(HexedHash(cache.name())); |
| 446 std::string cache_dir; | 566 std::string cache_dir; |
| 447 base::FilePath cache_path; | 567 base::FilePath cache_path; |
| 448 do { | 568 do { |
| 449 cache_dir = base::GenerateGUID(); | 569 cache_dir = base::GenerateGUID(); |
| 450 cache_path = origin_path.AppendASCII(cache_dir); | 570 cache_path = origin_path.AppendASCII(cache_dir); |
| 451 } while (base::PathExists(cache_path)); | 571 } while (base::PathExists(cache_path)); |
| 452 | 572 |
| 453 if (!base::Move(legacy_cache_path, cache_path)) { | 573 if (!base::Move(legacy_cache_path, cache_path)) { |
| 454 // If the move fails then the cache is in a bad state. Return an empty | 574 // If the move fails then the cache is in a bad state. Return an empty |
| 455 // index so that the CacheStorage can start fresh. The unreferenced | 575 // index so that the CacheStorage can start fresh. The unreferenced |
| 456 // caches will be discarded later in initialization. | 576 // caches will be discarded later in initialization. |
| 457 return kBadIndexState; | 577 return content::CacheStorageIndex(); |
| 458 } | 578 } |
| 459 | 579 |
| 460 index.mutable_cache(i)->set_cache_dir(cache_dir); | 580 index.mutable_cache(i)->set_cache_dir(cache_dir); |
| 461 index_is_dirty = true; | 581 index.mutable_cache(i)->clear_size(); |
| 582 index_modified = true; | |
| 462 } | 583 } |
| 463 } | 584 } |
| 464 | 585 |
| 465 if (index_is_dirty) { | 586 if (index_modified) { |
| 466 std::string new_body; | 587 if (!index.SerializeToString(&body)) |
| 467 if (!index.SerializeToString(&new_body)) | 588 return content::CacheStorageIndex(); |
| 468 return kBadIndexState; | 589 if (base::WriteFile(index_path, body.c_str(), body.size()) != |
| 469 if (base::WriteFile(index_path, new_body.c_str(), new_body.size()) != | 590 base::checked_cast<int>(body.size())) |
| 470 base::checked_cast<int>(new_body.size())) | 591 return content::CacheStorageIndex(); |
| 471 return kBadIndexState; | |
| 472 return new_body; | |
| 473 } | 592 } |
| 474 | 593 |
| 475 return body; | 594 return index; |
| 476 } | |
| 477 | |
| 478 // Runs on cache_task_runner_ | |
| 479 static std::string ReadAndMigrateIndexInPool( | |
| 480 const base::FilePath& index_path) { | |
| 481 std::string body; | |
| 482 base::ReadFileToString(index_path, &body); | |
| 483 | |
| 484 return MigrateCachesIfNecessaryInPool(body, index_path); | |
| 485 } | 595 } |
| 486 | 596 |
| 487 const base::FilePath origin_path_; | 597 const base::FilePath origin_path_; |
| 488 std::map<std::string, std::string> cache_name_to_cache_dir_; | 598 std::map<std::string, std::string> cache_name_to_cache_dir_; |
| 489 std::map<CacheStorageCache*, std::string> doomed_cache_to_path_; | 599 std::map<CacheStorageCache*, std::string> doomed_cache_to_path_; |
| 490 | 600 |
| 491 base::WeakPtrFactory<SimpleCacheLoader> weak_ptr_factory_; | 601 base::WeakPtrFactory<SimpleCacheLoader> weak_ptr_factory_; |
| 492 }; | 602 }; |
| 493 | 603 |
| 494 CacheStorage::CacheStorage( | 604 CacheStorage::CacheStorage( |
| 495 const base::FilePath& path, | 605 const base::FilePath& path, |
| 496 bool memory_only, | 606 bool memory_only, |
| 497 base::SequencedTaskRunner* cache_task_runner, | 607 base::SequencedTaskRunner* cache_task_runner, |
| 498 scoped_refptr<net::URLRequestContextGetter> request_context, | 608 scoped_refptr<net::URLRequestContextGetter> request_context, |
| 499 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, | 609 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, |
| 500 base::WeakPtr<storage::BlobStorageContext> blob_context, | 610 base::WeakPtr<storage::BlobStorageContext> blob_context, |
| 501 const GURL& origin) | 611 const GURL& origin) |
| 502 : initialized_(false), | 612 : initialized_(false), |
| 503 initializing_(false), | 613 initializing_(false), |
| 504 memory_only_(memory_only), | 614 memory_only_(memory_only), |
| 505 scheduler_(new CacheStorageScheduler( | 615 scheduler_(new CacheStorageScheduler( |
| 506 CacheStorageSchedulerClient::CLIENT_STORAGE)), | 616 CacheStorageSchedulerClient::CLIENT_STORAGE)), |
| 617 index_(base::MakeUnique<CacheStorageIndex>()), | |
| 507 origin_path_(path), | 618 origin_path_(path), |
| 508 cache_task_runner_(cache_task_runner), | 619 cache_task_runner_(cache_task_runner), |
| 509 quota_manager_proxy_(quota_manager_proxy), | 620 quota_manager_proxy_(quota_manager_proxy), |
| 510 origin_(origin), | 621 origin_(origin), |
| 511 weak_factory_(this) { | 622 weak_factory_(this) { |
| 512 if (memory_only) | 623 if (memory_only) |
| 513 cache_loader_.reset(new MemoryLoader( | 624 cache_loader_.reset(new MemoryLoader( |
| 514 cache_task_runner_.get(), std::move(request_context), | 625 cache_task_runner_.get(), std::move(request_context), |
| 515 quota_manager_proxy.get(), blob_context, this, origin)); | 626 quota_manager_proxy.get(), blob_context, this, origin)); |
| 516 else | 627 else |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 563 | 674 |
| 564 quota_manager_proxy_->NotifyStorageAccessed( | 675 quota_manager_proxy_->NotifyStorageAccessed( |
| 565 storage::QuotaClient::kServiceWorkerCache, origin_, | 676 storage::QuotaClient::kServiceWorkerCache, origin_, |
| 566 storage::kStorageTypeTemporary); | 677 storage::kStorageTypeTemporary); |
| 567 | 678 |
| 568 scheduler_->ScheduleOperation( | 679 scheduler_->ScheduleOperation( |
| 569 base::Bind(&CacheStorage::DeleteCacheImpl, weak_factory_.GetWeakPtr(), | 680 base::Bind(&CacheStorage::DeleteCacheImpl, weak_factory_.GetWeakPtr(), |
| 570 cache_name, scheduler_->WrapCallbackToRunNext(callback))); | 681 cache_name, scheduler_->WrapCallbackToRunNext(callback))); |
| 571 } | 682 } |
| 572 | 683 |
| 573 void CacheStorage::EnumerateCaches(const StringsCallback& callback) { | 684 void CacheStorage::EnumerateCaches(const CacheInfoCallback& callback) { |
| 574 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 685 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 575 | 686 |
| 576 if (!initialized_) | 687 if (!initialized_) |
| 577 LazyInit(); | 688 LazyInit(); |
| 578 | 689 |
| 579 quota_manager_proxy_->NotifyStorageAccessed( | 690 quota_manager_proxy_->NotifyStorageAccessed( |
| 580 storage::QuotaClient::kServiceWorkerCache, origin_, | 691 storage::QuotaClient::kServiceWorkerCache, origin_, |
| 581 storage::kStorageTypeTemporary); | 692 storage::kStorageTypeTemporary); |
| 582 | 693 |
| 583 scheduler_->ScheduleOperation( | 694 scheduler_->ScheduleOperation( |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 639 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 750 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 640 | 751 |
| 641 if (!initialized_) | 752 if (!initialized_) |
| 642 LazyInit(); | 753 LazyInit(); |
| 643 | 754 |
| 644 scheduler_->ScheduleOperation( | 755 scheduler_->ScheduleOperation( |
| 645 base::Bind(&CacheStorage::SizeImpl, weak_factory_.GetWeakPtr(), | 756 base::Bind(&CacheStorage::SizeImpl, weak_factory_.GetWeakPtr(), |
| 646 scheduler_->WrapCallbackToRunNext(callback))); | 757 scheduler_->WrapCallbackToRunNext(callback))); |
| 647 } | 758 } |
| 648 | 759 |
| 760 void CacheStorage::ScheduleWriteIndex() { | |
| 761 // TODO(cmumford): Write in a lazy fashion to minimize writes. | |
| 762 cache_loader_->WriteIndex(index_.get(), base::Bind(&DoNothingWithBool)); | |
| 763 } | |
| 764 | |
| 765 void CacheStorage::CacheModified(const CacheStorageCache* cache, | |
| 766 int64_t size_delta) { | |
| 767 if (!size_delta) | |
| 768 return; | |
| 769 index_->SetCacheSizeModified(cache->cache_name(), size_delta); | |
| 770 ScheduleWriteIndex(); | |
| 771 } | |
| 772 | |
| 773 void CacheStorage::SetCacheSize(const CacheStorageCache* cache, | |
| 774 int64_t cache_size) { | |
| 775 index_->SetCacheSize(cache->cache_name(), cache_size); | |
| 776 ScheduleWriteIndex(); | |
| 777 } | |
| 778 | |
| 649 void CacheStorage::StartAsyncOperationForTesting() { | 779 void CacheStorage::StartAsyncOperationForTesting() { |
| 650 scheduler_->ScheduleOperation(base::Bind(&base::DoNothing)); | 780 scheduler_->ScheduleOperation(base::Bind(&base::DoNothing)); |
| 651 } | 781 } |
| 652 | 782 |
| 653 void CacheStorage::CompleteAsyncOperationForTesting() { | 783 void CacheStorage::CompleteAsyncOperationForTesting() { |
| 654 scheduler_->CompleteOperationAndRunNext(); | 784 scheduler_->CompleteOperationAndRunNext(); |
| 655 } | 785 } |
| 656 | 786 |
| 657 // Init is run lazily so that it is called on the proper MessageLoop. | 787 // Init is run lazily so that it is called on the proper MessageLoop. |
| 658 void CacheStorage::LazyInit() { | 788 void CacheStorage::LazyInit() { |
| 659 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 789 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 660 DCHECK(!initialized_); | 790 DCHECK(!initialized_); |
| 661 | 791 |
| 662 if (initializing_) | 792 if (initializing_) |
| 663 return; | 793 return; |
| 664 | 794 |
| 665 DCHECK(!scheduler_->ScheduledOperations()); | 795 DCHECK(!scheduler_->ScheduledOperations()); |
| 666 | 796 |
| 667 initializing_ = true; | 797 initializing_ = true; |
| 668 scheduler_->ScheduleOperation( | 798 scheduler_->ScheduleOperation( |
| 669 base::Bind(&CacheStorage::LazyInitImpl, weak_factory_.GetWeakPtr())); | 799 base::Bind(&CacheStorage::LazyInitImpl, weak_factory_.GetWeakPtr())); |
| 670 } | 800 } |
| 671 | 801 |
| 672 void CacheStorage::LazyInitImpl() { | 802 void CacheStorage::LazyInitImpl() { |
| 673 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 803 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 674 DCHECK(!initialized_); | 804 DCHECK(!initialized_); |
| 675 DCHECK(initializing_); | 805 DCHECK(initializing_); |
| 676 | 806 |
| 677 // 1. Get the list of cache names (async call) | 807 // 1. Get the cache index (async call) |
| 678 // 2. For each cache name, load the cache (async call) | 808 // 2. For each cache name, load the cache (async call) |
| 679 // 3. Once each load is complete, update the map variables. | 809 // 3. Once each load is complete, update the map variables. |
| 680 // 4. Call the list of waiting callbacks. | 810 // 4. Call the list of waiting callbacks. |
| 681 | 811 |
| 682 std::unique_ptr<std::vector<std::string>> indexed_cache_names( | 812 cache_loader_->LoadIndex(base::Bind(&CacheStorage::LazyInitDidLoadIndex, |
| 683 new std::vector<std::string>()); | |
| 684 | |
| 685 cache_loader_->LoadIndex(std::move(indexed_cache_names), | |
| 686 base::Bind(&CacheStorage::LazyInitDidLoadIndex, | |
| 687 weak_factory_.GetWeakPtr())); | 813 weak_factory_.GetWeakPtr())); |
| 688 } | 814 } |
| 689 | 815 |
| 690 void CacheStorage::LazyInitDidLoadIndex( | 816 void CacheStorage::LazyInitDidLoadIndex( |
| 691 std::unique_ptr<std::vector<std::string>> indexed_cache_names) { | 817 std::unique_ptr<CacheStorageIndex> index) { |
| 692 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 818 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 693 | 819 |
| 694 for (size_t i = 0u, max = indexed_cache_names->size(); i < max; ++i) { | 820 DCHECK(cache_map_.empty()); |
| 695 cache_map_.insert(std::make_pair(indexed_cache_names->at(i), | 821 for (const auto& cache_info : index->ordered_cache_info()) { |
| 696 std::unique_ptr<CacheStorageCache>())); | 822 cache_map_.insert( |
| 697 ordered_cache_names_.push_back(indexed_cache_names->at(i)); | 823 std::make_pair(cache_info.name, std::unique_ptr<CacheStorageCache>())); |
| 698 } | 824 } |
| 699 | 825 |
| 826 index_.swap(index); | |
| 827 | |
| 700 initializing_ = false; | 828 initializing_ = false; |
| 701 initialized_ = true; | 829 initialized_ = true; |
| 702 | 830 |
| 703 scheduler_->CompleteOperationAndRunNext(); | 831 scheduler_->CompleteOperationAndRunNext(); |
| 704 } | 832 } |
| 705 | 833 |
| 706 void CacheStorage::OpenCacheImpl(const std::string& cache_name, | 834 void CacheStorage::OpenCacheImpl(const std::string& cache_name, |
| 707 const CacheAndErrorCallback& callback) { | 835 const CacheAndErrorCallback& callback) { |
| 708 std::unique_ptr<CacheStorageCacheHandle> cache_handle = | 836 std::unique_ptr<CacheStorageCacheHandle> cache_handle = |
| 709 GetLoadedCache(cache_name); | 837 GetLoadedCache(cache_name); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 728 | 856 |
| 729 if (!cache) { | 857 if (!cache) { |
| 730 callback.Run(std::unique_ptr<CacheStorageCacheHandle>(), | 858 callback.Run(std::unique_ptr<CacheStorageCacheHandle>(), |
| 731 CACHE_STORAGE_ERROR_STORAGE); | 859 CACHE_STORAGE_ERROR_STORAGE); |
| 732 return; | 860 return; |
| 733 } | 861 } |
| 734 | 862 |
| 735 CacheStorageCache* cache_ptr = cache.get(); | 863 CacheStorageCache* cache_ptr = cache.get(); |
| 736 | 864 |
| 737 cache_map_.insert(std::make_pair(cache_name, std::move(cache))); | 865 cache_map_.insert(std::make_pair(cache_name, std::move(cache))); |
| 738 ordered_cache_names_.push_back(cache_name); | 866 index_->Insert(CacheInfo(cache_name, cache_ptr->cache_size())); |
| 739 | 867 |
| 740 cache_loader_->WriteIndex( | 868 cache_loader_->WriteIndex( |
| 741 ordered_cache_names_, | 869 index_.get(), base::Bind(&CacheStorage::CreateCacheDidWriteIndex, |
| 742 base::Bind(&CacheStorage::CreateCacheDidWriteIndex, | 870 weak_factory_.GetWeakPtr(), callback, |
| 743 weak_factory_.GetWeakPtr(), callback, | 871 base::Passed(CreateCacheHandle(cache_ptr)))); |
| 744 base::Passed(CreateCacheHandle(cache_ptr)))); | |
| 745 | 872 |
| 746 cache_loader_->NotifyCacheCreated(cache_name, CreateCacheHandle(cache_ptr)); | 873 cache_loader_->NotifyCacheCreated(cache_name, CreateCacheHandle(cache_ptr)); |
| 747 } | 874 } |
| 748 | 875 |
| 749 void CacheStorage::CreateCacheDidWriteIndex( | 876 void CacheStorage::CreateCacheDidWriteIndex( |
| 750 const CacheAndErrorCallback& callback, | 877 const CacheAndErrorCallback& callback, |
| 751 std::unique_ptr<CacheStorageCacheHandle> cache_handle, | 878 std::unique_ptr<CacheStorageCacheHandle> cache_handle, |
| 752 bool success) { | 879 bool success) { |
| 753 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 880 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 754 DCHECK(cache_handle); | 881 DCHECK(cache_handle); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 765 } | 892 } |
| 766 | 893 |
| 767 void CacheStorage::DeleteCacheImpl(const std::string& cache_name, | 894 void CacheStorage::DeleteCacheImpl(const std::string& cache_name, |
| 768 const BoolAndErrorCallback& callback) { | 895 const BoolAndErrorCallback& callback) { |
| 769 if (!GetLoadedCache(cache_name)) { | 896 if (!GetLoadedCache(cache_name)) { |
| 770 base::ThreadTaskRunnerHandle::Get()->PostTask( | 897 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 771 FROM_HERE, base::Bind(callback, false, CACHE_STORAGE_ERROR_NOT_FOUND)); | 898 FROM_HERE, base::Bind(callback, false, CACHE_STORAGE_ERROR_NOT_FOUND)); |
| 772 return; | 899 return; |
| 773 } | 900 } |
| 774 | 901 |
| 775 // Delete the name from ordered_cache_names_. | 902 // Save the current index so that it can be restored if the write fails. |
| 776 StringVector original_ordered_cache_names = ordered_cache_names_; | 903 // TODO(cmumford): Avoid creating a copy, and make CacheStorageCacheIndex |
| 777 StringVector::iterator iter = std::find( | 904 // DISALLOW_COPY_AND_ASSIGN. |
| 778 ordered_cache_names_.begin(), ordered_cache_names_.end(), cache_name); | 905 auto prior_index = base::MakeUnique<CacheStorageIndex>(*index_); |
| 779 DCHECK(iter != ordered_cache_names_.end()); | 906 index_->Delete(cache_name); |
| 780 ordered_cache_names_.erase(iter); | |
| 781 | 907 |
| 782 cache_loader_->WriteIndex(ordered_cache_names_, | 908 cache_loader_->WriteIndex( |
| 783 base::Bind(&CacheStorage::DeleteCacheDidWriteIndex, | 909 index_.get(), base::Bind(&CacheStorage::DeleteCacheDidWriteIndex, |
| 784 weak_factory_.GetWeakPtr(), cache_name, | 910 weak_factory_.GetWeakPtr(), cache_name, |
| 785 original_ordered_cache_names, callback)); | 911 base::Passed(std::move(prior_index)), callback)); |
| 786 } | 912 } |
| 787 | 913 |
| 788 void CacheStorage::DeleteCacheDidWriteIndex( | 914 void CacheStorage::DeleteCacheDidWriteIndex( |
| 789 const std::string& cache_name, | 915 const std::string& cache_name, |
| 790 const StringVector& original_ordered_cache_names, | 916 std::unique_ptr<CacheStorageIndex> index_before_delete, |
| 791 const BoolAndErrorCallback& callback, | 917 const BoolAndErrorCallback& callback, |
| 792 bool success) { | 918 bool success) { |
| 793 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 919 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 794 | 920 |
| 795 if (!success) { | 921 if (!success) { |
| 796 // Undo any changes if the change couldn't be written to disk. | 922 // Undo any changes if the change couldn't be written to disk. |
| 797 ordered_cache_names_ = original_ordered_cache_names; | 923 index_.swap(index_before_delete); |
| 798 callback.Run(false, CACHE_STORAGE_ERROR_STORAGE); | 924 callback.Run(false, CACHE_STORAGE_ERROR_STORAGE); |
| 799 return; | 925 return; |
| 800 } | 926 } |
| 801 | 927 |
| 802 // Make sure that a cache handle exists for the doomed cache to ensure that | 928 // Make sure that a cache handle exists for the doomed cache to ensure that |
| 803 // DeleteCacheFinalize is called. | 929 // DeleteCacheFinalize is called. |
| 804 std::unique_ptr<CacheStorageCacheHandle> cache_handle = | 930 std::unique_ptr<CacheStorageCacheHandle> cache_handle = |
| 805 GetLoadedCache(cache_name); | 931 GetLoadedCache(cache_name); |
| 806 | 932 |
| 807 CacheMap::iterator map_iter = cache_map_.find(cache_name); | 933 CacheMap::iterator map_iter = cache_map_.find(cache_name); |
| 808 doomed_caches_.insert( | 934 doomed_caches_.insert( |
| 809 std::make_pair(map_iter->second.get(), std::move(map_iter->second))); | 935 std::make_pair(map_iter->second.get(), std::move(map_iter->second))); |
| 810 cache_map_.erase(map_iter); | 936 cache_map_.erase(map_iter); |
| 811 | 937 |
| 812 cache_loader_->NotifyCacheDoomed(std::move(cache_handle)); | 938 cache_loader_->NotifyCacheDoomed(std::move(cache_handle)); |
| 813 | 939 |
| 814 callback.Run(true, CACHE_STORAGE_OK); | 940 callback.Run(true, CACHE_STORAGE_OK); |
| 815 } | 941 } |
| 816 | 942 |
| 817 // Call this once the last handle to a doomed cache is gone. It's okay if this | 943 // Call this once the last handle to a doomed cache is gone. It's okay if this |
| 818 // doesn't get to complete before shutdown, the cache will be removed from disk | 944 // doesn't get to complete before shutdown, the cache will be removed from disk |
| 819 // on next startup in that case. | 945 // on next startup in that case. |
| 820 void CacheStorage::DeleteCacheFinalize( | 946 void CacheStorage::DeleteCacheFinalize( |
| 821 std::unique_ptr<CacheStorageCache> doomed_cache) { | 947 std::unique_ptr<CacheStorageCache> doomed_cache) { |
| 822 CacheStorageCache* cache = doomed_cache.get(); | 948 CacheStorageCache* cache = doomed_cache.get(); |
| 949 cache->SetObserver(nullptr); | |
|
jkarlin
2016/10/21 18:04:19
Let's keep the cache in doomed_caches_ instead of
cmumford
2016/11/10 17:28:16
Done.
| |
| 823 cache->Size(base::Bind(&CacheStorage::DeleteCacheDidGetSize, | 950 cache->Size(base::Bind(&CacheStorage::DeleteCacheDidGetSize, |
| 824 weak_factory_.GetWeakPtr(), | 951 weak_factory_.GetWeakPtr(), |
| 825 base::Passed(std::move(doomed_cache)))); | 952 base::Passed(std::move(doomed_cache)))); |
| 826 } | 953 } |
| 827 | 954 |
| 828 void CacheStorage::DeleteCacheDidGetSize( | 955 void CacheStorage::DeleteCacheDidGetSize( |
| 829 std::unique_ptr<CacheStorageCache> cache, | 956 std::unique_ptr<CacheStorageCache> cache, |
| 830 int64_t cache_size) { | 957 int64_t cache_size) { |
| 831 quota_manager_proxy_->NotifyStorageModified( | 958 quota_manager_proxy_->NotifyStorageModified( |
| 832 storage::QuotaClient::kServiceWorkerCache, origin_, | 959 storage::QuotaClient::kServiceWorkerCache, origin_, |
| 833 storage::kStorageTypeTemporary, -1 * cache_size); | 960 storage::kStorageTypeTemporary, -1 * cache_size); |
| 834 | 961 |
| 835 cache_loader_->CleanUpDeletedCache(cache.get()); | 962 cache_loader_->CleanUpDeletedCache(cache.get()); |
| 836 } | 963 } |
| 837 | 964 |
| 838 void CacheStorage::EnumerateCachesImpl(const StringsCallback& callback) { | 965 void CacheStorage::EnumerateCachesImpl(const CacheInfoCallback& callback) { |
| 839 callback.Run(ordered_cache_names_); | 966 callback.Run(index_->ordered_cache_info()); |
| 840 } | 967 } |
| 841 | 968 |
| 842 void CacheStorage::MatchCacheImpl( | 969 void CacheStorage::MatchCacheImpl( |
| 843 const std::string& cache_name, | 970 const std::string& cache_name, |
| 844 std::unique_ptr<ServiceWorkerFetchRequest> request, | 971 std::unique_ptr<ServiceWorkerFetchRequest> request, |
| 845 const CacheStorageCacheQueryParams& match_params, | 972 const CacheStorageCacheQueryParams& match_params, |
| 846 const CacheStorageCache::ResponseCallback& callback) { | 973 const CacheStorageCache::ResponseCallback& callback) { |
| 847 std::unique_ptr<CacheStorageCacheHandle> cache_handle = | 974 std::unique_ptr<CacheStorageCacheHandle> cache_handle = |
| 848 GetLoadedCache(cache_name); | 975 GetLoadedCache(cache_name); |
| 849 | 976 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 870 std::unique_ptr<ServiceWorkerResponse> response, | 997 std::unique_ptr<ServiceWorkerResponse> response, |
| 871 std::unique_ptr<storage::BlobDataHandle> handle) { | 998 std::unique_ptr<storage::BlobDataHandle> handle) { |
| 872 callback.Run(error, std::move(response), std::move(handle)); | 999 callback.Run(error, std::move(response), std::move(handle)); |
| 873 } | 1000 } |
| 874 | 1001 |
| 875 void CacheStorage::MatchAllCachesImpl( | 1002 void CacheStorage::MatchAllCachesImpl( |
| 876 std::unique_ptr<ServiceWorkerFetchRequest> request, | 1003 std::unique_ptr<ServiceWorkerFetchRequest> request, |
| 877 const CacheStorageCacheQueryParams& match_params, | 1004 const CacheStorageCacheQueryParams& match_params, |
| 878 const CacheStorageCache::ResponseCallback& callback) { | 1005 const CacheStorageCache::ResponseCallback& callback) { |
| 879 std::vector<CacheMatchResponse>* match_responses = | 1006 std::vector<CacheMatchResponse>* match_responses = |
| 880 new std::vector<CacheMatchResponse>(ordered_cache_names_.size()); | 1007 new std::vector<CacheMatchResponse>(index_->num_entries()); |
| 881 | 1008 |
| 882 base::Closure barrier_closure = base::BarrierClosure( | 1009 base::Closure barrier_closure = base::BarrierClosure( |
| 883 ordered_cache_names_.size(), | 1010 index_->num_entries(), |
| 884 base::Bind(&CacheStorage::MatchAllCachesDidMatchAll, | 1011 base::Bind(&CacheStorage::MatchAllCachesDidMatchAll, |
| 885 weak_factory_.GetWeakPtr(), | 1012 weak_factory_.GetWeakPtr(), |
| 886 base::Passed(base::WrapUnique(match_responses)), callback)); | 1013 base::Passed(base::WrapUnique(match_responses)), callback)); |
| 887 | 1014 |
| 888 for (size_t i = 0, max = ordered_cache_names_.size(); i < max; ++i) { | 1015 size_t idx = 0, max = index_->num_entries(); |
| 1016 for (const auto& cache_info : index_->ordered_cache_info()) { | |
| 889 std::unique_ptr<CacheStorageCacheHandle> cache_handle = | 1017 std::unique_ptr<CacheStorageCacheHandle> cache_handle = |
| 890 GetLoadedCache(ordered_cache_names_[i]); | 1018 GetLoadedCache(cache_info.name); |
| 891 DCHECK(cache_handle); | 1019 DCHECK(cache_handle); |
| 892 | 1020 |
| 893 CacheStorageCache* cache_ptr = cache_handle->value(); | 1021 CacheStorageCache* cache_ptr = cache_handle->value(); |
| 894 cache_ptr->Match(base::MakeUnique<ServiceWorkerFetchRequest>(*request), | 1022 cache_ptr->Match(base::MakeUnique<ServiceWorkerFetchRequest>(*request), |
| 895 match_params, | 1023 match_params, |
| 896 base::Bind(&CacheStorage::MatchAllCachesDidMatch, | 1024 base::Bind(&CacheStorage::MatchAllCachesDidMatch, |
| 897 weak_factory_.GetWeakPtr(), | 1025 weak_factory_.GetWeakPtr(), |
| 898 base::Passed(std::move(cache_handle)), | 1026 base::Passed(std::move(cache_handle)), |
| 899 &match_responses->at(i), barrier_closure)); | 1027 &match_responses->at(idx), barrier_closure)); |
| 1028 if (++idx > max) | |
| 1029 break; | |
| 900 } | 1030 } |
| 901 } | 1031 } |
| 902 | 1032 |
| 903 void CacheStorage::MatchAllCachesDidMatch( | 1033 void CacheStorage::MatchAllCachesDidMatch( |
| 904 std::unique_ptr<CacheStorageCacheHandle> cache_handle, | 1034 std::unique_ptr<CacheStorageCacheHandle> cache_handle, |
| 905 CacheMatchResponse* out_match_response, | 1035 CacheMatchResponse* out_match_response, |
| 906 const base::Closure& barrier_closure, | 1036 const base::Closure& barrier_closure, |
| 907 CacheStorageError error, | 1037 CacheStorageError error, |
| 908 std::unique_ptr<ServiceWorkerResponse> service_worker_response, | 1038 std::unique_ptr<ServiceWorkerResponse> service_worker_response, |
| 909 std::unique_ptr<storage::BlobDataHandle> handle) { | 1039 std::unique_ptr<storage::BlobDataHandle> handle) { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 977 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1107 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 978 DCHECK(initialized_); | 1108 DCHECK(initialized_); |
| 979 | 1109 |
| 980 CacheMap::iterator map_iter = cache_map_.find(cache_name); | 1110 CacheMap::iterator map_iter = cache_map_.find(cache_name); |
| 981 if (map_iter == cache_map_.end()) | 1111 if (map_iter == cache_map_.end()) |
| 982 return std::unique_ptr<CacheStorageCacheHandle>(); | 1112 return std::unique_ptr<CacheStorageCacheHandle>(); |
| 983 | 1113 |
| 984 CacheStorageCache* cache = map_iter->second.get(); | 1114 CacheStorageCache* cache = map_iter->second.get(); |
| 985 | 1115 |
| 986 if (!cache) { | 1116 if (!cache) { |
| 987 std::unique_ptr<CacheStorageCache> new_cache = | 1117 DCHECK(initialized_); |
| 988 cache_loader_->CreateCache(cache_name); | 1118 std::unique_ptr<CacheStorageCache> new_cache = cache_loader_->CreateCache( |
| 1119 cache_name, index_->GetCacheSize(cache_name)); | |
| 989 CacheStorageCache* cache_ptr = new_cache.get(); | 1120 CacheStorageCache* cache_ptr = new_cache.get(); |
| 990 map_iter->second = std::move(new_cache); | 1121 map_iter->second = std::move(new_cache); |
| 991 | 1122 |
| 992 return CreateCacheHandle(cache_ptr); | 1123 return CreateCacheHandle(cache_ptr); |
| 993 } | 1124 } |
| 994 | 1125 |
| 995 return CreateCacheHandle(cache); | 1126 return CreateCacheHandle(cache); |
| 996 } | 1127 } |
| 997 | 1128 |
| 1129 void CacheStorage::SizeRetrievedFromCache( | |
| 1130 std::unique_ptr<CacheStorageCacheHandle> cache_handle, | |
| 1131 const base::Closure& closure, | |
| 1132 int64_t* accumulator, | |
| 1133 int64_t size) { | |
| 1134 index_->SetCacheSize(cache_handle->value()->cache_name(), size); | |
| 1135 *accumulator += size; | |
| 1136 closure.Run(); | |
| 1137 } | |
| 1138 | |
| 1139 void CacheStorage::CloseAllCaches() { | |
| 1140 for (const CacheInfo& cache_info : index_->ordered_cache_info()) { | |
| 1141 auto map_iter = cache_map_.find(cache_info.name); | |
| 1142 if (map_iter != cache_map_.end()) { | |
| 1143 CacheStorageCache* cache = map_iter->second.get(); | |
| 1144 if (cache) | |
| 1145 cache->Close(base::Bind(&base::DoNothing)); | |
| 1146 } | |
| 1147 } | |
| 1148 } | |
| 1149 | |
| 998 void CacheStorage::GetSizeThenCloseAllCachesImpl(const SizeCallback& callback) { | 1150 void CacheStorage::GetSizeThenCloseAllCachesImpl(const SizeCallback& callback) { |
|
jkarlin
2016/10/21 19:24:39
I don't think this function should change. It shou
cmumford
2016/11/10 17:28:16
Done. Not sure why I modified it that way, but all
| |
| 999 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1151 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 1000 DCHECK(initialized_); | 1152 DCHECK(initialized_); |
| 1001 | 1153 |
| 1154 if (index_->GetStorageSize() != kSizeUnknown) { | |
| 1155 CloseAllCaches(); | |
| 1156 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 1157 FROM_HERE, base::Bind(callback, index_->GetStorageSize())); | |
| 1158 return; | |
| 1159 } | |
| 1160 | |
| 1002 std::unique_ptr<int64_t> accumulator(new int64_t(0)); | 1161 std::unique_ptr<int64_t> accumulator(new int64_t(0)); |
| 1003 int64_t* accumulator_ptr = accumulator.get(); | 1162 int64_t* accumulator_ptr = accumulator.get(); |
| 1004 | 1163 |
| 1005 base::Closure barrier_closure = base::BarrierClosure( | 1164 base::Closure barrier_closure = base::BarrierClosure( |
| 1006 ordered_cache_names_.size(), | 1165 index_->num_entries(), |
| 1007 base::Bind(&SizeRetrievedFromAllCaches, | 1166 base::Bind(&SizeRetrievedFromAllCaches, |
| 1008 base::Passed(std::move(accumulator)), callback)); | 1167 base::Passed(std::move(accumulator)), callback)); |
| 1009 | 1168 |
| 1010 for (const std::string& cache_name : ordered_cache_names_) { | 1169 for (const CacheInfo& cache_info : index_->ordered_cache_info()) { |
| 1170 if (cache_info.size != CacheStorage::kSizeUnknown) { | |
| 1171 // If the cache is open then close it. | |
| 1172 auto map_iter = cache_map_.find(cache_info.name); | |
| 1173 if (map_iter != cache_map_.end()) { | |
| 1174 // Doomed caches have names, but null values in the map. | |
| 1175 CacheStorageCache* cache = map_iter->second.get(); | |
| 1176 if (cache) | |
| 1177 cache->Close(base::Bind(&base::DoNothing)); | |
| 1178 } | |
| 1179 | |
| 1180 *accumulator_ptr += cache_info.size; | |
| 1181 barrier_closure.Run(); | |
| 1182 continue; | |
| 1183 } | |
| 1011 std::unique_ptr<CacheStorageCacheHandle> cache_handle = | 1184 std::unique_ptr<CacheStorageCacheHandle> cache_handle = |
| 1012 GetLoadedCache(cache_name); | 1185 GetLoadedCache(cache_info.name); |
| 1013 CacheStorageCache* cache = cache_handle->value(); | 1186 CacheStorageCache* cache = cache_handle->value(); |
| 1014 cache->GetSizeThenClose(base::Bind(&SizeRetrievedFromCache, | 1187 cache->GetSizeThenClose(base::Bind(&CacheStorage::SizeRetrievedFromCache, |
| 1188 weak_factory_.GetWeakPtr(), | |
| 1015 base::Passed(std::move(cache_handle)), | 1189 base::Passed(std::move(cache_handle)), |
| 1016 barrier_closure, accumulator_ptr)); | 1190 barrier_closure, accumulator_ptr)); |
| 1017 } | 1191 } |
| 1018 } | 1192 } |
| 1019 | 1193 |
| 1020 void CacheStorage::SizeImpl(const SizeCallback& callback) { | 1194 void CacheStorage::SizeImpl(const SizeCallback& callback) { |
| 1021 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1195 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 1022 DCHECK(initialized_); | 1196 DCHECK(initialized_); |
| 1023 | 1197 |
| 1198 if (index_->GetStorageSize() != kSizeUnknown) { | |
| 1199 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 1200 FROM_HERE, base::Bind(callback, index_->GetStorageSize())); | |
| 1201 return; | |
| 1202 } | |
| 1203 | |
| 1024 std::unique_ptr<int64_t> accumulator(new int64_t(0)); | 1204 std::unique_ptr<int64_t> accumulator(new int64_t(0)); |
| 1025 int64_t* accumulator_ptr = accumulator.get(); | 1205 int64_t* accumulator_ptr = accumulator.get(); |
| 1026 | 1206 |
| 1027 base::Closure barrier_closure = base::BarrierClosure( | 1207 base::Closure barrier_closure = base::BarrierClosure( |
| 1028 ordered_cache_names_.size(), | 1208 index_->num_entries(), |
| 1029 base::Bind(&SizeRetrievedFromAllCaches, | 1209 base::Bind(&SizeRetrievedFromAllCaches, |
| 1030 base::Passed(std::move(accumulator)), callback)); | 1210 base::Passed(std::move(accumulator)), callback)); |
| 1031 | 1211 |
| 1032 for (const std::string& cache_name : ordered_cache_names_) { | 1212 for (const CacheInfo& cache_info : index_->ordered_cache_info()) { |
| 1213 if (cache_info.size != CacheStorage::kSizeUnknown) { | |
| 1214 *accumulator_ptr += cache_info.size; | |
| 1215 barrier_closure.Run(); | |
| 1216 continue; | |
| 1217 } | |
| 1033 std::unique_ptr<CacheStorageCacheHandle> cache_handle = | 1218 std::unique_ptr<CacheStorageCacheHandle> cache_handle = |
| 1034 GetLoadedCache(cache_name); | 1219 GetLoadedCache(cache_info.name); |
| 1035 CacheStorageCache* cache = cache_handle->value(); | 1220 CacheStorageCache* cache = cache_handle->value(); |
| 1036 cache->Size(base::Bind(&SizeRetrievedFromCache, | 1221 cache->Size(base::Bind(&CacheStorage::SizeRetrievedFromCache, |
| 1222 weak_factory_.GetWeakPtr(), | |
| 1037 base::Passed(std::move(cache_handle)), | 1223 base::Passed(std::move(cache_handle)), |
| 1038 barrier_closure, accumulator_ptr)); | 1224 barrier_closure, accumulator_ptr)); |
| 1039 } | 1225 } |
| 1040 } | 1226 } |
| 1041 | 1227 |
| 1042 } // namespace content | 1228 } // namespace content |
| OLD | NEW |