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

Side by Side Diff: content/browser/cache_storage/cache_storage.cc

Issue 2416713002: Write out CacheStorageCache size to index file. (Closed)
Patch Set: BrowserThread::PostDelayedTask(IO, ...) --> base::ThreadTaskRunnerHandle::Get()->Post* Created 3 years, 12 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
OLDNEW
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>
(...skipping 10 matching lines...) Expand all
21 #include "base/numerics/safe_conversions.h" 21 #include "base/numerics/safe_conversions.h"
22 #include "base/sha1.h" 22 #include "base/sha1.h"
23 #include "base/single_thread_task_runner.h" 23 #include "base/single_thread_task_runner.h"
24 #include "base/stl_util.h" 24 #include "base/stl_util.h"
25 #include "base/strings/string_number_conversions.h" 25 #include "base/strings/string_number_conversions.h"
26 #include "base/strings/string_util.h" 26 #include "base/strings/string_util.h"
27 #include "base/threading/thread_task_runner_handle.h" 27 #include "base/threading/thread_task_runner_handle.h"
28 #include "content/browser/cache_storage/cache_storage.pb.h" 28 #include "content/browser/cache_storage/cache_storage.pb.h"
29 #include "content/browser/cache_storage/cache_storage_cache.h" 29 #include "content/browser/cache_storage/cache_storage_cache.h"
30 #include "content/browser/cache_storage/cache_storage_cache_handle.h" 30 #include "content/browser/cache_storage/cache_storage_cache_handle.h"
31 #include "content/browser/cache_storage/cache_storage_index.h"
31 #include "content/browser/cache_storage/cache_storage_scheduler.h" 32 #include "content/browser/cache_storage/cache_storage_scheduler.h"
32 #include "content/public/browser/browser_thread.h" 33 #include "content/public/browser/browser_thread.h"
33 #include "net/base/directory_lister.h" 34 #include "net/base/directory_lister.h"
34 #include "net/base/net_errors.h" 35 #include "net/base/net_errors.h"
35 #include "net/url_request/url_request_context_getter.h" 36 #include "net/url_request/url_request_context_getter.h"
36 #include "storage/browser/blob/blob_storage_context.h" 37 #include "storage/browser/blob/blob_storage_context.h"
37 #include "storage/browser/quota/quota_manager_proxy.h" 38 #include "storage/browser/quota/quota_manager_proxy.h"
38 39
39 namespace content { 40 namespace content {
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
78 // Handles the loading and clean up of CacheStorageCache objects. 73 // Handles the loading and clean up of CacheStorageCache objects.
79 class CacheStorage::CacheLoader { 74 class CacheStorage::CacheLoader {
80 public: 75 public:
81 typedef base::Callback<void(std::unique_ptr<CacheStorageCache>)> 76 typedef base::Callback<void(std::unique_ptr<CacheStorageCache>)>
82 CacheCallback; 77 CacheCallback;
83 typedef base::Callback<void(bool)> BoolCallback; 78 typedef base::Callback<void(bool)> BoolCallback;
84 typedef base::Callback<void(std::unique_ptr<std::vector<std::string>>)> 79 using CacheStorageIndexLoadCallback =
85 StringVectorCallback; 80 base::Callback<void(std::unique_ptr<CacheStorageIndex>)>;
86 81
87 CacheLoader( 82 CacheLoader(
88 base::SequencedTaskRunner* cache_task_runner, 83 base::SequencedTaskRunner* cache_task_runner,
89 scoped_refptr<net::URLRequestContextGetter> request_context_getter, 84 scoped_refptr<net::URLRequestContextGetter> request_context_getter,
90 storage::QuotaManagerProxy* quota_manager_proxy, 85 storage::QuotaManagerProxy* quota_manager_proxy,
91 base::WeakPtr<storage::BlobStorageContext> blob_context, 86 base::WeakPtr<storage::BlobStorageContext> blob_context,
92 CacheStorage* cache_storage, 87 CacheStorage* cache_storage,
93 const GURL& origin) 88 const GURL& origin)
94 : cache_task_runner_(cache_task_runner), 89 : cache_task_runner_(cache_task_runner),
95 request_context_getter_(request_context_getter), 90 request_context_getter_(request_context_getter),
96 quota_manager_proxy_(quota_manager_proxy), 91 quota_manager_proxy_(quota_manager_proxy),
97 blob_context_(blob_context), 92 blob_context_(blob_context),
98 cache_storage_(cache_storage), 93 cache_storage_(cache_storage),
99 origin_(origin) { 94 origin_(origin) {
100 DCHECK(!origin_.is_empty()); 95 DCHECK(!origin_.is_empty());
101 } 96 }
102 97
103 virtual ~CacheLoader() {} 98 virtual ~CacheLoader() {}
104 99
105 // Creates a CacheStorageCache with the given name. It does not attempt to 100 // Creates a CacheStorageCache with the given name. It does not attempt to
106 // load the backend, that happens lazily when the cache is used. 101 // load the backend, that happens lazily when the cache is used.
107 virtual std::unique_ptr<CacheStorageCache> CreateCache( 102 virtual std::unique_ptr<CacheStorageCache> CreateCache(
108 const std::string& cache_name) = 0; 103 const std::string& cache_name,
104 int64_t cache_size) = 0;
109 105
110 // Deletes any pre-existing cache of the same name and then loads it. 106 // Deletes any pre-existing cache of the same name and then loads it.
111 virtual void PrepareNewCacheDestination(const std::string& cache_name, 107 virtual void PrepareNewCacheDestination(const std::string& cache_name,
112 const CacheCallback& callback) = 0; 108 const CacheCallback& callback) = 0;
113 109
114 // After the backend has been deleted, do any extra house keeping such as 110 // After the backend has been deleted, do any extra house keeping such as
115 // removing the cache's directory. 111 // removing the cache's directory.
116 virtual void CleanUpDeletedCache(CacheStorageCache* cache) = 0; 112 virtual void CleanUpDeletedCache(CacheStorageCache* cache) = 0;
117 113
118 // Writes the cache names (and sizes) to disk if applicable. 114 // Writes the cache index to disk if applicable.
119 virtual void WriteIndex(const StringVector& cache_names, 115 virtual void WriteIndex(const CacheStorageIndex& index,
120 const BoolCallback& callback) = 0; 116 const BoolCallback& callback) = 0;
121 117
122 // Loads the cache names from disk if applicable. 118 // Loads the cache index from disk if applicable.
123 virtual void LoadIndex(std::unique_ptr<std::vector<std::string>> cache_names, 119 virtual void LoadIndex(const CacheStorageIndexLoadCallback& callback) = 0;
124 const StringVectorCallback& callback) = 0;
125 120
126 // Called when CacheStorage has created a cache. Used to hold onto a handle to 121 // Called when CacheStorage has created a cache. Used to hold onto a handle to
127 // the cache if necessary. 122 // the cache if necessary.
128 virtual void NotifyCacheCreated( 123 virtual void NotifyCacheCreated(
129 const std::string& cache_name, 124 const std::string& cache_name,
130 std::unique_ptr<CacheStorageCacheHandle> cache_handle) {} 125 std::unique_ptr<CacheStorageCacheHandle> cache_handle) {}
131 126
132 // Notification that the cache for |cache_handle| has been doomed. If the 127 // 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. 128 // loader is holding a handle to the cache, it should drop it now.
134 virtual void NotifyCacheDoomed( 129 virtual void NotifyCacheDoomed(
(...skipping 26 matching lines...) Expand all
161 base::WeakPtr<storage::BlobStorageContext> blob_context, 156 base::WeakPtr<storage::BlobStorageContext> blob_context,
162 CacheStorage* cache_storage, 157 CacheStorage* cache_storage,
163 const GURL& origin) 158 const GURL& origin)
164 : CacheLoader(cache_task_runner, 159 : CacheLoader(cache_task_runner,
165 request_context, 160 request_context,
166 quota_manager_proxy, 161 quota_manager_proxy,
167 blob_context, 162 blob_context,
168 cache_storage, 163 cache_storage,
169 origin) {} 164 origin) {}
170 165
171 std::unique_ptr<CacheStorageCache> CreateCache( 166 std::unique_ptr<CacheStorageCache> CreateCache(const std::string& cache_name,
172 const std::string& cache_name) override { 167 int64_t cache_size) override {
173 return CacheStorageCache::CreateMemoryCache( 168 return CacheStorageCache::CreateMemoryCache(
174 origin_, cache_name, cache_storage_, request_context_getter_, 169 origin_, cache_name, cache_storage_, request_context_getter_,
175 quota_manager_proxy_, blob_context_); 170 quota_manager_proxy_, blob_context_);
176 } 171 }
177 172
178 void PrepareNewCacheDestination(const std::string& cache_name, 173 void PrepareNewCacheDestination(const std::string& cache_name,
179 const CacheCallback& callback) override { 174 const CacheCallback& callback) override {
180 std::unique_ptr<CacheStorageCache> cache = CreateCache(cache_name); 175 std::unique_ptr<CacheStorageCache> cache =
176 CreateCache(cache_name, 0 /*cache_size*/);
181 callback.Run(std::move(cache)); 177 callback.Run(std::move(cache));
182 } 178 }
183 179
184 void CleanUpDeletedCache(CacheStorageCache* cache) override {} 180 void CleanUpDeletedCache(CacheStorageCache* cache) override {}
185 181
186 void WriteIndex(const StringVector& cache_names, 182 void WriteIndex(const CacheStorageIndex& index,
187 const BoolCallback& callback) override { 183 const BoolCallback& callback) override {
188 callback.Run(true); 184 callback.Run(true);
189 } 185 }
190 186
191 void LoadIndex(std::unique_ptr<std::vector<std::string>> cache_names, 187 void LoadIndex(const CacheStorageIndexLoadCallback& callback) override {
192 const StringVectorCallback& callback) override { 188 callback.Run(base::MakeUnique<CacheStorageIndex>());
193 callback.Run(std::move(cache_names));
194 } 189 }
195 190
196 void NotifyCacheCreated( 191 void NotifyCacheCreated(
197 const std::string& cache_name, 192 const std::string& cache_name,
198 std::unique_ptr<CacheStorageCacheHandle> cache_handle) override { 193 std::unique_ptr<CacheStorageCacheHandle> cache_handle) override {
199 DCHECK(!base::ContainsKey(cache_handles_, cache_name)); 194 DCHECK(!base::ContainsKey(cache_handles_, cache_name));
200 cache_handles_.insert(std::make_pair(cache_name, std::move(cache_handle))); 195 cache_handles_.insert(std::make_pair(cache_name, std::move(cache_handle)));
201 }; 196 };
202 197
203 void NotifyCacheDoomed( 198 void NotifyCacheDoomed(
(...skipping 25 matching lines...) Expand all
229 const GURL& origin) 224 const GURL& origin)
230 : CacheLoader(cache_task_runner, 225 : CacheLoader(cache_task_runner,
231 request_context, 226 request_context,
232 quota_manager_proxy, 227 quota_manager_proxy,
233 blob_context, 228 blob_context,
234 cache_storage, 229 cache_storage,
235 origin), 230 origin),
236 origin_path_(origin_path), 231 origin_path_(origin_path),
237 weak_ptr_factory_(this) {} 232 weak_ptr_factory_(this) {}
238 233
239 std::unique_ptr<CacheStorageCache> CreateCache( 234 std::unique_ptr<CacheStorageCache> CreateCache(const std::string& cache_name,
240 const std::string& cache_name) override { 235 int64_t cache_size) override {
241 DCHECK_CURRENTLY_ON(BrowserThread::IO); 236 DCHECK_CURRENTLY_ON(BrowserThread::IO);
242 DCHECK(base::ContainsKey(cache_name_to_cache_dir_, cache_name)); 237 DCHECK(base::ContainsKey(cache_name_to_cache_dir_, cache_name));
243 238
244 std::string cache_dir = cache_name_to_cache_dir_[cache_name]; 239 std::string cache_dir = cache_name_to_cache_dir_[cache_name];
245 base::FilePath cache_path = origin_path_.AppendASCII(cache_dir); 240 base::FilePath cache_path = origin_path_.AppendASCII(cache_dir);
246 return CacheStorageCache::CreatePersistentCache( 241 return CacheStorageCache::CreatePersistentCache(
247 origin_, cache_name, cache_storage_, cache_path, 242 origin_, cache_name, cache_storage_, cache_path,
248 request_context_getter_, quota_manager_proxy_, blob_context_); 243 request_context_getter_, quota_manager_proxy_, blob_context_,
244 cache_size);
249 } 245 }
250 246
251 void PrepareNewCacheDestination(const std::string& cache_name, 247 void PrepareNewCacheDestination(const std::string& cache_name,
252 const CacheCallback& callback) override { 248 const CacheCallback& callback) override {
253 DCHECK_CURRENTLY_ON(BrowserThread::IO); 249 DCHECK_CURRENTLY_ON(BrowserThread::IO);
254 250
255 PostTaskAndReplyWithResult( 251 PostTaskAndReplyWithResult(
256 cache_task_runner_.get(), FROM_HERE, 252 cache_task_runner_.get(), FROM_HERE,
257 base::Bind(&SimpleCacheLoader::PrepareNewCacheDirectoryInPool, 253 base::Bind(&SimpleCacheLoader::PrepareNewCacheDirectoryInPool,
258 origin_path_), 254 origin_path_),
(...skipping 16 matching lines...) Expand all
275 271
276 void PrepareNewCacheCreateCache(const std::string& cache_name, 272 void PrepareNewCacheCreateCache(const std::string& cache_name,
277 const CacheCallback& callback, 273 const CacheCallback& callback,
278 const std::string& cache_dir) { 274 const std::string& cache_dir) {
279 if (cache_dir.empty()) { 275 if (cache_dir.empty()) {
280 callback.Run(std::unique_ptr<CacheStorageCache>()); 276 callback.Run(std::unique_ptr<CacheStorageCache>());
281 return; 277 return;
282 } 278 }
283 279
284 cache_name_to_cache_dir_[cache_name] = cache_dir; 280 cache_name_to_cache_dir_[cache_name] = cache_dir;
285 callback.Run(CreateCache(cache_name)); 281 callback.Run(CreateCache(cache_name, CacheStorage::kSizeUnknown));
286 } 282 }
287 283
288 void CleanUpDeletedCache(CacheStorageCache* cache) override { 284 void CleanUpDeletedCache(CacheStorageCache* cache) override {
289 DCHECK_CURRENTLY_ON(BrowserThread::IO); 285 DCHECK_CURRENTLY_ON(BrowserThread::IO);
290 DCHECK(base::ContainsKey(doomed_cache_to_path_, cache)); 286 DCHECK(base::ContainsKey(doomed_cache_to_path_, cache));
291 287
292 base::FilePath cache_path = 288 base::FilePath cache_path =
293 origin_path_.AppendASCII(doomed_cache_to_path_[cache]); 289 origin_path_.AppendASCII(doomed_cache_to_path_[cache]);
294 doomed_cache_to_path_.erase(cache); 290 doomed_cache_to_path_.erase(cache);
295 291
296 cache_task_runner_->PostTask( 292 cache_task_runner_->PostTask(
297 FROM_HERE, base::Bind(&SimpleCacheLoader::CleanUpDeleteCacheDirInPool, 293 FROM_HERE, base::Bind(&SimpleCacheLoader::CleanUpDeleteCacheDirInPool,
298 cache_path)); 294 cache_path));
299 } 295 }
300 296
301 static void CleanUpDeleteCacheDirInPool(const base::FilePath& cache_path) { 297 static void CleanUpDeleteCacheDirInPool(const base::FilePath& cache_path) {
302 base::DeleteFile(cache_path, true /* recursive */); 298 base::DeleteFile(cache_path, true /* recursive */);
303 } 299 }
304 300
305 void WriteIndex(const StringVector& cache_names, 301 void WriteIndex(const CacheStorageIndex& index,
306 const BoolCallback& callback) override { 302 const BoolCallback& callback) override {
307 DCHECK_CURRENTLY_ON(BrowserThread::IO); 303 DCHECK_CURRENTLY_ON(BrowserThread::IO);
308 304
309 // 1. Create the index file as a string. (WriteIndex) 305 // 1. Create the index file as a string. (WriteIndex)
310 // 2. Write the file to disk. (WriteIndexWriteToFileInPool) 306 // 2. Write the file to disk. (WriteIndexWriteToFileInPool)
311 307
312 proto::CacheStorageIndex index; 308 proto::CacheStorageIndex protobuf_index;
313 index.set_origin(origin_.spec()); 309 protobuf_index.set_origin(origin_.spec());
314 310
315 for (size_t i = 0u, max = cache_names.size(); i < max; ++i) { 311 for (const auto& cache_metadata : index.ordered_cache_metadata()) {
316 DCHECK(base::ContainsKey(cache_name_to_cache_dir_, cache_names[i])); 312 DCHECK(base::ContainsKey(cache_name_to_cache_dir_, cache_metadata.name));
317 313
318 proto::CacheStorageIndex::Cache* index_cache = index.add_cache(); 314 proto::CacheStorageIndex::Cache* index_cache = protobuf_index.add_cache();
319 index_cache->set_name(cache_names[i]); 315 index_cache->set_name(cache_metadata.name);
320 index_cache->set_cache_dir(cache_name_to_cache_dir_[cache_names[i]]); 316 index_cache->set_cache_dir(cache_name_to_cache_dir_[cache_metadata.name]);
317 if (cache_metadata.size == CacheStorage::kSizeUnknown)
318 index_cache->clear_size();
319 else
320 index_cache->set_size(cache_metadata.size);
321 } 321 }
322 322
323 std::string serialized; 323 std::string serialized;
324 bool success = index.SerializeToString(&serialized); 324 bool success = protobuf_index.SerializeToString(&serialized);
325 DCHECK(success); 325 DCHECK(success);
326 326
327 base::FilePath tmp_path = origin_path_.AppendASCII("index.txt.tmp"); 327 base::FilePath tmp_path = origin_path_.AppendASCII("index.txt.tmp");
328 base::FilePath index_path = 328 base::FilePath index_path =
329 origin_path_.AppendASCII(CacheStorage::kIndexFileName); 329 origin_path_.AppendASCII(CacheStorage::kIndexFileName);
330 330
331 PostTaskAndReplyWithResult( 331 PostTaskAndReplyWithResult(
332 cache_task_runner_.get(), FROM_HERE, 332 cache_task_runner_.get(), FROM_HERE,
333 base::Bind(&SimpleCacheLoader::WriteIndexWriteToFileInPool, tmp_path, 333 base::Bind(&SimpleCacheLoader::WriteIndexWriteToFileInPool, tmp_path,
334 index_path, serialized), 334 index_path, serialized),
335 callback); 335 callback);
336 } 336 }
337 337
338 static bool WriteIndexWriteToFileInPool(const base::FilePath& tmp_path, 338 static bool WriteIndexWriteToFileInPool(const base::FilePath& tmp_path,
339 const base::FilePath& index_path, 339 const base::FilePath& index_path,
340 const std::string& data) { 340 const std::string& data) {
341 int bytes_written = base::WriteFile(tmp_path, data.c_str(), data.size()); 341 int bytes_written = base::WriteFile(tmp_path, data.c_str(), data.size());
342 if (bytes_written != base::checked_cast<int>(data.size())) { 342 if (bytes_written != base::checked_cast<int>(data.size())) {
343 base::DeleteFile(tmp_path, /* recursive */ false); 343 base::DeleteFile(tmp_path, /* recursive */ false);
344 return false; 344 return false;
345 } 345 }
346 346
347 // Atomically rename the temporary index file to become the real one. 347 // Atomically rename the temporary index file to become the real one.
348 return base::ReplaceFile(tmp_path, index_path, NULL); 348 return base::ReplaceFile(tmp_path, index_path, NULL);
349 } 349 }
350 350
351 void LoadIndex(std::unique_ptr<std::vector<std::string>> names, 351 void LoadIndex(const CacheStorageIndexLoadCallback& callback) override {
352 const StringVectorCallback& callback) override {
353 DCHECK_CURRENTLY_ON(BrowserThread::IO); 352 DCHECK_CURRENTLY_ON(BrowserThread::IO);
354 353
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( 354 PostTaskAndReplyWithResult(
362 cache_task_runner_.get(), FROM_HERE, 355 cache_task_runner_.get(), FROM_HERE,
363 base::Bind(&SimpleCacheLoader::ReadAndMigrateIndexInPool, index_path), 356 base::Bind(&SimpleCacheLoader::ReadAndMigrateIndexInPool, origin_path_),
364 base::Bind(&SimpleCacheLoader::LoadIndexDidReadFile, 357 base::Bind(&SimpleCacheLoader::LoadIndexDidReadIndex,
365 weak_ptr_factory_.GetWeakPtr(), base::Passed(&names), 358 weak_ptr_factory_.GetWeakPtr(), callback));
366 callback));
367 } 359 }
368 360
369 void LoadIndexDidReadFile(std::unique_ptr<std::vector<std::string>> names, 361 void LoadIndexDidReadIndex(const CacheStorageIndexLoadCallback& callback,
370 const StringVectorCallback& callback, 362 proto::CacheStorageIndex protobuf_index) {
371 const std::string& serialized) {
372 DCHECK_CURRENTLY_ON(BrowserThread::IO); 363 DCHECK_CURRENTLY_ON(BrowserThread::IO);
373 364
374 std::unique_ptr<std::set<std::string>> cache_dirs( 365 std::unique_ptr<std::set<std::string>> cache_dirs(
375 new std::set<std::string>); 366 new std::set<std::string>);
376 367
377 proto::CacheStorageIndex index; 368 auto index = base::MakeUnique<CacheStorageIndex>();
378 if (index.ParseFromString(serialized)) { 369 for (int i = 0, max = protobuf_index.cache_size(); i < max; ++i) {
379 for (int i = 0, max = index.cache_size(); i < max; ++i) { 370 const proto::CacheStorageIndex::Cache& cache = protobuf_index.cache(i);
380 const proto::CacheStorageIndex::Cache& cache = index.cache(i); 371 DCHECK(cache.has_cache_dir());
381 DCHECK(cache.has_cache_dir()); 372 int64_t cache_size =
382 names->push_back(cache.name()); 373 cache.has_size() ? cache.size() : CacheStorage::kSizeUnknown;
383 cache_name_to_cache_dir_[cache.name()] = cache.cache_dir(); 374 index->Insert(CacheStorageIndex::CacheMetadata(cache.name(), cache_size));
384 cache_dirs->insert(cache.cache_dir()); 375 cache_name_to_cache_dir_[cache.name()] = cache.cache_dir();
385 } 376 cache_dirs->insert(cache.cache_dir());
386 } 377 }
387 378
388 cache_task_runner_->PostTask( 379 cache_task_runner_->PostTask(
389 FROM_HERE, base::Bind(&DeleteUnreferencedCachesInPool, origin_path_, 380 FROM_HERE, base::Bind(&DeleteUnreferencedCachesInPool, origin_path_,
390 base::Passed(&cache_dirs))); 381 base::Passed(&cache_dirs)));
391 callback.Run(std::move(names)); 382 callback.Run(std::move(index));
392 } 383 }
393 384
394 void NotifyCacheDoomed( 385 void NotifyCacheDoomed(
395 std::unique_ptr<CacheStorageCacheHandle> cache_handle) override { 386 std::unique_ptr<CacheStorageCacheHandle> cache_handle) override {
396 DCHECK(base::ContainsKey(cache_name_to_cache_dir_, 387 DCHECK(base::ContainsKey(cache_name_to_cache_dir_,
397 cache_handle->value()->cache_name())); 388 cache_handle->value()->cache_name()));
398 auto iter = 389 auto iter =
399 cache_name_to_cache_dir_.find(cache_handle->value()->cache_name()); 390 cache_name_to_cache_dir_.find(cache_handle->value()->cache_name());
400 doomed_cache_to_path_[cache_handle->value()] = iter->second; 391 doomed_cache_to_path_[cache_handle->value()] = iter->second;
401 cache_name_to_cache_dir_.erase(iter); 392 cache_name_to_cache_dir_.erase(iter);
(...skipping 15 matching lines...) Expand all
417 while (!(cache_path = file_enum.Next()).empty()) { 408 while (!(cache_path = file_enum.Next()).empty()) {
418 if (!base::ContainsKey(*cache_dirs, cache_path.BaseName().AsUTF8Unsafe())) 409 if (!base::ContainsKey(*cache_dirs, cache_path.BaseName().AsUTF8Unsafe()))
419 dirs_to_delete.push_back(cache_path); 410 dirs_to_delete.push_back(cache_path);
420 } 411 }
421 412
422 for (const base::FilePath& cache_path : dirs_to_delete) 413 for (const base::FilePath& cache_path : dirs_to_delete)
423 base::DeleteFile(cache_path, true /* recursive */); 414 base::DeleteFile(cache_path, true /* recursive */);
424 } 415 }
425 416
426 // Runs on cache_task_runner_ 417 // Runs on cache_task_runner_
427 static std::string MigrateCachesIfNecessaryInPool( 418 static proto::CacheStorageIndex ReadAndMigrateIndexInPool(
428 const std::string& body, 419 const base::FilePath& origin_path) {
429 const base::FilePath& index_path) { 420 const base::FilePath index_path =
421 origin_path.AppendASCII(CacheStorage::kIndexFileName);
422
430 proto::CacheStorageIndex index; 423 proto::CacheStorageIndex index;
431 if (!index.ParseFromString(body)) 424 std::string body;
432 return body; 425 if (!base::ReadFileToString(index_path, &body) ||
426 !index.ParseFromString(body))
427 return proto::CacheStorageIndex();
428 body.clear();
433 429
434 base::FilePath origin_path = index_path.DirName(); 430 base::File::Info file_info;
435 bool index_is_dirty = false; 431 base::Time index_last_modified;
436 const std::string kBadIndexState(""); 432 if (GetFileInfo(index_path, &file_info))
433 index_last_modified = file_info.last_modified;
434 bool index_modified = false;
437 435
438 // Look for caches that have no cache_dir. Give any such caches a directory 436 // 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. 437 // with a random name and move them there. Then, rewrite the index file.
438 // Additionally invalidate the size of any index entries where the cache was
439 // modified after the index (making it out-of-date).
440 for (int i = 0, max = index.cache_size(); i < max; ++i) { 440 for (int i = 0, max = index.cache_size(); i < max; ++i) {
441 const proto::CacheStorageIndex::Cache& cache = index.cache(i); 441 const proto::CacheStorageIndex::Cache& cache = index.cache(i);
442 if (!cache.has_cache_dir()) { 442 if (cache.has_cache_dir()) {
443 if (cache.has_size()) {
444 base::FilePath cache_dir = origin_path.AppendASCII(cache.cache_dir());
445 if (!GetFileInfo(cache_dir, &file_info) ||
446 index_last_modified <= file_info.last_modified) {
447 // Index is older than this cache, so invalidate index entries that
448 // may change as a result of cache operations.
449 index.mutable_cache(i)->clear_size();
450 }
451 }
452 } else {
443 // Find a new home for the cache. 453 // Find a new home for the cache.
444 base::FilePath legacy_cache_path = 454 base::FilePath legacy_cache_path =
445 origin_path.AppendASCII(HexedHash(cache.name())); 455 origin_path.AppendASCII(HexedHash(cache.name()));
446 std::string cache_dir; 456 std::string cache_dir;
447 base::FilePath cache_path; 457 base::FilePath cache_path;
448 do { 458 do {
449 cache_dir = base::GenerateGUID(); 459 cache_dir = base::GenerateGUID();
450 cache_path = origin_path.AppendASCII(cache_dir); 460 cache_path = origin_path.AppendASCII(cache_dir);
451 } while (base::PathExists(cache_path)); 461 } while (base::PathExists(cache_path));
452 462
453 if (!base::Move(legacy_cache_path, cache_path)) { 463 if (!base::Move(legacy_cache_path, cache_path)) {
454 // If the move fails then the cache is in a bad state. Return an empty 464 // 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 465 // index so that the CacheStorage can start fresh. The unreferenced
456 // caches will be discarded later in initialization. 466 // caches will be discarded later in initialization.
457 return kBadIndexState; 467 return proto::CacheStorageIndex();
458 } 468 }
459 469
460 index.mutable_cache(i)->set_cache_dir(cache_dir); 470 index.mutable_cache(i)->set_cache_dir(cache_dir);
461 index_is_dirty = true; 471 index.mutable_cache(i)->clear_size();
472 index_modified = true;
462 } 473 }
463 } 474 }
464 475
465 if (index_is_dirty) { 476 if (index_modified) {
466 std::string new_body; 477 if (!index.SerializeToString(&body))
467 if (!index.SerializeToString(&new_body)) 478 return proto::CacheStorageIndex();
468 return kBadIndexState; 479 if (base::WriteFile(index_path, body.c_str(), body.size()) !=
469 if (base::WriteFile(index_path, new_body.c_str(), new_body.size()) != 480 base::checked_cast<int>(body.size()))
470 base::checked_cast<int>(new_body.size())) 481 return proto::CacheStorageIndex();
471 return kBadIndexState;
472 return new_body;
473 } 482 }
474 483
475 return body; 484 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 } 485 }
486 486
487 const base::FilePath origin_path_; 487 const base::FilePath origin_path_;
488 std::map<std::string, std::string> cache_name_to_cache_dir_; 488 std::map<std::string, std::string> cache_name_to_cache_dir_;
489 std::map<CacheStorageCache*, std::string> doomed_cache_to_path_; 489 std::map<CacheStorageCache*, std::string> doomed_cache_to_path_;
490 490
491 base::WeakPtrFactory<SimpleCacheLoader> weak_ptr_factory_; 491 base::WeakPtrFactory<SimpleCacheLoader> weak_ptr_factory_;
492 }; 492 };
493 493
494 CacheStorage::CacheStorage( 494 CacheStorage::CacheStorage(
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 563
564 quota_manager_proxy_->NotifyStorageAccessed( 564 quota_manager_proxy_->NotifyStorageAccessed(
565 storage::QuotaClient::kServiceWorkerCache, origin_, 565 storage::QuotaClient::kServiceWorkerCache, origin_,
566 storage::kStorageTypeTemporary); 566 storage::kStorageTypeTemporary);
567 567
568 scheduler_->ScheduleOperation( 568 scheduler_->ScheduleOperation(
569 base::Bind(&CacheStorage::DeleteCacheImpl, weak_factory_.GetWeakPtr(), 569 base::Bind(&CacheStorage::DeleteCacheImpl, weak_factory_.GetWeakPtr(),
570 cache_name, scheduler_->WrapCallbackToRunNext(callback))); 570 cache_name, scheduler_->WrapCallbackToRunNext(callback)));
571 } 571 }
572 572
573 void CacheStorage::EnumerateCaches(const StringsCallback& callback) { 573 void CacheStorage::EnumerateCaches(const IndexCallback& callback) {
574 DCHECK_CURRENTLY_ON(BrowserThread::IO); 574 DCHECK_CURRENTLY_ON(BrowserThread::IO);
575 575
576 if (!initialized_) 576 if (!initialized_)
577 LazyInit(); 577 LazyInit();
578 578
579 quota_manager_proxy_->NotifyStorageAccessed( 579 quota_manager_proxy_->NotifyStorageAccessed(
580 storage::QuotaClient::kServiceWorkerCache, origin_, 580 storage::QuotaClient::kServiceWorkerCache, origin_,
581 storage::kStorageTypeTemporary); 581 storage::kStorageTypeTemporary);
582 582
583 scheduler_->ScheduleOperation( 583 scheduler_->ScheduleOperation(
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 DCHECK_CURRENTLY_ON(BrowserThread::IO); 639 DCHECK_CURRENTLY_ON(BrowserThread::IO);
640 640
641 if (!initialized_) 641 if (!initialized_)
642 LazyInit(); 642 LazyInit();
643 643
644 scheduler_->ScheduleOperation( 644 scheduler_->ScheduleOperation(
645 base::Bind(&CacheStorage::SizeImpl, weak_factory_.GetWeakPtr(), 645 base::Bind(&CacheStorage::SizeImpl, weak_factory_.GetWeakPtr(),
646 scheduler_->WrapCallbackToRunNext(callback))); 646 scheduler_->WrapCallbackToRunNext(callback)));
647 } 647 }
648 648
649 void CacheStorage::ScheduleWriteIndex() {
650 static const int64_t kWriteIndexDelaySecs = 5;
651 DCHECK_CURRENTLY_ON(BrowserThread::IO);
652 index_write_task_.Reset(base::Bind(&CacheStorage::WriteIndex,
653 weak_factory_.GetWeakPtr(),
654 base::Bind(&DoNothingWithBool)));
655 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
656 FROM_HERE, index_write_task_.callback(),
657 base::TimeDelta::FromSeconds(kWriteIndexDelaySecs));
658 }
659
660 void CacheStorage::WriteIndex(const base::Callback<void(bool)>& callback) {
661 DCHECK_CURRENTLY_ON(BrowserThread::IO);
662 scheduler_->ScheduleOperation(
663 base::Bind(&CacheStorage::WriteIndexImpl, weak_factory_.GetWeakPtr(),
664 scheduler_->WrapCallbackToRunNext(callback)));
665 }
666
667 void CacheStorage::WriteIndexImpl(const base::Callback<void(bool)>& callback) {
668 DCHECK_CURRENTLY_ON(BrowserThread::IO);
669 cache_loader_->WriteIndex(*cache_index_, callback);
670 }
671
672 bool CacheStorage::InitiateScheduledIndexWriteForTest(
673 const base::Callback<void(bool)>& callback) {
674 DCHECK_CURRENTLY_ON(BrowserThread::IO);
675 if (index_write_pending()) {
676 index_write_task_.Cancel();
677 WriteIndex(callback);
678 return true;
679 }
680 callback.Run(true /* success */);
681 return false;
682 }
683
684 void CacheStorage::CacheSizeUpdated(const CacheStorageCache* cache,
685 int64_t size) {
686 // Should not be called for doomed caches.
687 DCHECK(!base::ContainsKey(doomed_caches_,
688 const_cast<CacheStorageCache*>(cache)));
689 cache_index_->SetCacheSize(cache->cache_name(), size);
690 ScheduleWriteIndex();
691 }
692
649 void CacheStorage::StartAsyncOperationForTesting() { 693 void CacheStorage::StartAsyncOperationForTesting() {
650 scheduler_->ScheduleOperation(base::Bind(&base::DoNothing)); 694 scheduler_->ScheduleOperation(base::Bind(&base::DoNothing));
651 } 695 }
652 696
653 void CacheStorage::CompleteAsyncOperationForTesting() { 697 void CacheStorage::CompleteAsyncOperationForTesting() {
654 scheduler_->CompleteOperationAndRunNext(); 698 scheduler_->CompleteOperationAndRunNext();
655 } 699 }
656 700
657 // Init is run lazily so that it is called on the proper MessageLoop. 701 // Init is run lazily so that it is called on the proper MessageLoop.
658 void CacheStorage::LazyInit() { 702 void CacheStorage::LazyInit() {
659 DCHECK_CURRENTLY_ON(BrowserThread::IO); 703 DCHECK_CURRENTLY_ON(BrowserThread::IO);
660 DCHECK(!initialized_); 704 DCHECK(!initialized_);
661 705
662 if (initializing_) 706 if (initializing_)
663 return; 707 return;
664 708
665 DCHECK(!scheduler_->ScheduledOperations()); 709 DCHECK(!scheduler_->ScheduledOperations());
666 710
667 initializing_ = true; 711 initializing_ = true;
668 scheduler_->ScheduleOperation( 712 scheduler_->ScheduleOperation(
669 base::Bind(&CacheStorage::LazyInitImpl, weak_factory_.GetWeakPtr())); 713 base::Bind(&CacheStorage::LazyInitImpl, weak_factory_.GetWeakPtr()));
670 } 714 }
671 715
672 void CacheStorage::LazyInitImpl() { 716 void CacheStorage::LazyInitImpl() {
673 DCHECK_CURRENTLY_ON(BrowserThread::IO); 717 DCHECK_CURRENTLY_ON(BrowserThread::IO);
674 DCHECK(!initialized_); 718 DCHECK(!initialized_);
675 DCHECK(initializing_); 719 DCHECK(initializing_);
676 720
677 // 1. Get the list of cache names (async call) 721 // 1. Get the cache index (async call)
678 // 2. For each cache name, load the cache (async call) 722 // 2. For each cache name, load the cache (async call)
679 // 3. Once each load is complete, update the map variables. 723 // 3. Once each load is complete, update the map variables.
680 // 4. Call the list of waiting callbacks. 724 // 4. Call the list of waiting callbacks.
681 725
682 std::unique_ptr<std::vector<std::string>> indexed_cache_names( 726 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())); 727 weak_factory_.GetWeakPtr()));
688 } 728 }
689 729
690 void CacheStorage::LazyInitDidLoadIndex( 730 void CacheStorage::LazyInitDidLoadIndex(
691 std::unique_ptr<std::vector<std::string>> indexed_cache_names) { 731 std::unique_ptr<CacheStorageIndex> index) {
692 DCHECK_CURRENTLY_ON(BrowserThread::IO); 732 DCHECK_CURRENTLY_ON(BrowserThread::IO);
733 DCHECK(cache_map_.empty());
693 734
694 for (size_t i = 0u, max = indexed_cache_names->size(); i < max; ++i) { 735 for (const auto& cache_metadata : index->ordered_cache_metadata()) {
695 cache_map_.insert(std::make_pair(indexed_cache_names->at(i), 736 cache_map_.insert(std::make_pair(cache_metadata.name,
696 std::unique_ptr<CacheStorageCache>())); 737 std::unique_ptr<CacheStorageCache>()));
697 ordered_cache_names_.push_back(indexed_cache_names->at(i));
698 } 738 }
699 739
740 DCHECK(!cache_index_);
741 cache_index_ = std::move(index);
742
700 initializing_ = false; 743 initializing_ = false;
701 initialized_ = true; 744 initialized_ = true;
702 745
703 scheduler_->CompleteOperationAndRunNext(); 746 scheduler_->CompleteOperationAndRunNext();
704 } 747 }
705 748
706 void CacheStorage::OpenCacheImpl(const std::string& cache_name, 749 void CacheStorage::OpenCacheImpl(const std::string& cache_name,
707 const CacheAndErrorCallback& callback) { 750 const CacheAndErrorCallback& callback) {
708 std::unique_ptr<CacheStorageCacheHandle> cache_handle = 751 std::unique_ptr<CacheStorageCacheHandle> cache_handle =
709 GetLoadedCache(cache_name); 752 GetLoadedCache(cache_name);
(...skipping 18 matching lines...) Expand all
728 771
729 if (!cache) { 772 if (!cache) {
730 callback.Run(std::unique_ptr<CacheStorageCacheHandle>(), 773 callback.Run(std::unique_ptr<CacheStorageCacheHandle>(),
731 CACHE_STORAGE_ERROR_STORAGE); 774 CACHE_STORAGE_ERROR_STORAGE);
732 return; 775 return;
733 } 776 }
734 777
735 CacheStorageCache* cache_ptr = cache.get(); 778 CacheStorageCache* cache_ptr = cache.get();
736 779
737 cache_map_.insert(std::make_pair(cache_name, std::move(cache))); 780 cache_map_.insert(std::make_pair(cache_name, std::move(cache)));
738 ordered_cache_names_.push_back(cache_name); 781 cache_index_->Insert(
782 CacheStorageIndex::CacheMetadata(cache_name, cache_ptr->cache_size()));
739 783
740 cache_loader_->WriteIndex( 784 cache_loader_->WriteIndex(
741 ordered_cache_names_, 785 *cache_index_, base::Bind(&CacheStorage::CreateCacheDidWriteIndex,
742 base::Bind(&CacheStorage::CreateCacheDidWriteIndex, 786 weak_factory_.GetWeakPtr(), callback,
743 weak_factory_.GetWeakPtr(), callback, 787 base::Passed(CreateCacheHandle(cache_ptr))));
744 base::Passed(CreateCacheHandle(cache_ptr))));
745 788
746 cache_loader_->NotifyCacheCreated(cache_name, CreateCacheHandle(cache_ptr)); 789 cache_loader_->NotifyCacheCreated(cache_name, CreateCacheHandle(cache_ptr));
747 } 790 }
748 791
749 void CacheStorage::CreateCacheDidWriteIndex( 792 void CacheStorage::CreateCacheDidWriteIndex(
750 const CacheAndErrorCallback& callback, 793 const CacheAndErrorCallback& callback,
751 std::unique_ptr<CacheStorageCacheHandle> cache_handle, 794 std::unique_ptr<CacheStorageCacheHandle> cache_handle,
752 bool success) { 795 bool success) {
753 DCHECK_CURRENTLY_ON(BrowserThread::IO); 796 DCHECK_CURRENTLY_ON(BrowserThread::IO);
754 DCHECK(cache_handle); 797 DCHECK(cache_handle);
755 798
756 // TODO(jkarlin): Handle !success. 799 // TODO(jkarlin): Handle !success.
757 800
758 callback.Run(std::move(cache_handle), CACHE_STORAGE_OK); 801 callback.Run(std::move(cache_handle), CACHE_STORAGE_OK);
759 } 802 }
760 803
761 void CacheStorage::HasCacheImpl(const std::string& cache_name, 804 void CacheStorage::HasCacheImpl(const std::string& cache_name,
762 const BoolAndErrorCallback& callback) { 805 const BoolAndErrorCallback& callback) {
763 bool has_cache = base::ContainsKey(cache_map_, cache_name); 806 bool has_cache = base::ContainsKey(cache_map_, cache_name);
764 callback.Run(has_cache, CACHE_STORAGE_OK); 807 callback.Run(has_cache, CACHE_STORAGE_OK);
765 } 808 }
766 809
767 void CacheStorage::DeleteCacheImpl(const std::string& cache_name, 810 void CacheStorage::DeleteCacheImpl(const std::string& cache_name,
768 const BoolAndErrorCallback& callback) { 811 const BoolAndErrorCallback& callback) {
769 if (!GetLoadedCache(cache_name)) { 812 std::unique_ptr<CacheStorageCacheHandle> cache_handle =
813 GetLoadedCache(cache_name);
814 if (!cache_handle) {
770 base::ThreadTaskRunnerHandle::Get()->PostTask( 815 base::ThreadTaskRunnerHandle::Get()->PostTask(
771 FROM_HERE, base::Bind(callback, false, CACHE_STORAGE_ERROR_NOT_FOUND)); 816 FROM_HERE, base::Bind(callback, false, CACHE_STORAGE_ERROR_NOT_FOUND));
772 return; 817 return;
773 } 818 }
774 819
775 // Delete the name from ordered_cache_names_. 820 cache_handle->value()->SetObserver(nullptr);
776 StringVector original_ordered_cache_names = ordered_cache_names_; 821 cache_index_->DoomCache(cache_name);
777 StringVector::iterator iter = std::find( 822 cache_loader_->WriteIndex(
778 ordered_cache_names_.begin(), ordered_cache_names_.end(), cache_name); 823 *cache_index_,
779 DCHECK(iter != ordered_cache_names_.end()); 824 base::Bind(&CacheStorage::DeleteCacheDidWriteIndex,
780 ordered_cache_names_.erase(iter); 825 weak_factory_.GetWeakPtr(),
781 826 base::Passed(std::move(cache_handle)), callback));
782 cache_loader_->WriteIndex(ordered_cache_names_,
783 base::Bind(&CacheStorage::DeleteCacheDidWriteIndex,
784 weak_factory_.GetWeakPtr(), cache_name,
785 original_ordered_cache_names, callback));
786 } 827 }
787 828
788 void CacheStorage::DeleteCacheDidWriteIndex( 829 void CacheStorage::DeleteCacheDidWriteIndex(
789 const std::string& cache_name, 830 std::unique_ptr<CacheStorageCacheHandle> cache_handle,
790 const StringVector& original_ordered_cache_names,
791 const BoolAndErrorCallback& callback, 831 const BoolAndErrorCallback& callback,
792 bool success) { 832 bool success) {
793 DCHECK_CURRENTLY_ON(BrowserThread::IO); 833 DCHECK_CURRENTLY_ON(BrowserThread::IO);
794 834
795 if (!success) { 835 if (!success) {
796 // Undo any changes if the change couldn't be written to disk. 836 // Undo any changes if the index couldn't be written to disk.
797 ordered_cache_names_ = original_ordered_cache_names; 837 cache_index_->RestoreDoomedCache();
838 cache_handle->value()->SetObserver(this);
798 callback.Run(false, CACHE_STORAGE_ERROR_STORAGE); 839 callback.Run(false, CACHE_STORAGE_ERROR_STORAGE);
799 return; 840 return;
800 } 841 }
801 842
802 // Make sure that a cache handle exists for the doomed cache to ensure that 843 cache_index_->FinalizeDoomedCache();
803 // DeleteCacheFinalize is called.
804 std::unique_ptr<CacheStorageCacheHandle> cache_handle =
805 GetLoadedCache(cache_name);
806 844
807 CacheMap::iterator map_iter = cache_map_.find(cache_name); 845 CacheMap::iterator map_iter =
846 cache_map_.find(cache_handle->value()->cache_name());
847 DCHECK(map_iter != cache_map_.end());
848
808 doomed_caches_.insert( 849 doomed_caches_.insert(
809 std::make_pair(map_iter->second.get(), std::move(map_iter->second))); 850 std::make_pair(map_iter->second.get(), std::move(map_iter->second)));
810 cache_map_.erase(map_iter); 851 cache_map_.erase(map_iter);
811 852
812 cache_loader_->NotifyCacheDoomed(std::move(cache_handle)); 853 cache_loader_->NotifyCacheDoomed(std::move(cache_handle));
813 854
814 callback.Run(true, CACHE_STORAGE_OK); 855 callback.Run(true, CACHE_STORAGE_OK);
815 } 856 }
816 857
817 // Call this once the last handle to a doomed cache is gone. It's okay if this 858 // 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 859 // doesn't get to complete before shutdown, the cache will be removed from disk
819 // on next startup in that case. 860 // on next startup in that case.
820 void CacheStorage::DeleteCacheFinalize(CacheStorageCache* doomed_cache) { 861 void CacheStorage::DeleteCacheFinalize(CacheStorageCache* doomed_cache) {
821 doomed_cache->Size(base::Bind(&CacheStorage::DeleteCacheDidGetSize, 862 doomed_cache->Size(base::Bind(&CacheStorage::DeleteCacheDidGetSize,
822 weak_factory_.GetWeakPtr(), doomed_cache)); 863 weak_factory_.GetWeakPtr(), doomed_cache));
823 } 864 }
824 865
825 void CacheStorage::DeleteCacheDidGetSize(CacheStorageCache* doomed_cache, 866 void CacheStorage::DeleteCacheDidGetSize(CacheStorageCache* doomed_cache,
826 int64_t cache_size) { 867 int64_t cache_size) {
827 quota_manager_proxy_->NotifyStorageModified( 868 quota_manager_proxy_->NotifyStorageModified(
828 storage::QuotaClient::kServiceWorkerCache, origin_, 869 storage::QuotaClient::kServiceWorkerCache, origin_,
829 storage::kStorageTypeTemporary, -1 * cache_size); 870 storage::kStorageTypeTemporary, -1 * cache_size);
830 871
831 cache_loader_->CleanUpDeletedCache(doomed_cache); 872 cache_loader_->CleanUpDeletedCache(doomed_cache);
832 auto doomed_caches_iter = doomed_caches_.find(doomed_cache); 873 auto doomed_caches_iter = doomed_caches_.find(doomed_cache);
833 DCHECK(doomed_caches_iter != doomed_caches_.end()); 874 DCHECK(doomed_caches_iter != doomed_caches_.end());
834 doomed_caches_.erase(doomed_caches_iter); 875 doomed_caches_.erase(doomed_caches_iter);
835 } 876 }
836 877
837 void CacheStorage::EnumerateCachesImpl(const StringsCallback& callback) { 878 void CacheStorage::EnumerateCachesImpl(const IndexCallback& callback) {
838 callback.Run(ordered_cache_names_); 879 callback.Run(*cache_index_);
839 } 880 }
840 881
841 void CacheStorage::MatchCacheImpl( 882 void CacheStorage::MatchCacheImpl(
842 const std::string& cache_name, 883 const std::string& cache_name,
843 std::unique_ptr<ServiceWorkerFetchRequest> request, 884 std::unique_ptr<ServiceWorkerFetchRequest> request,
844 const CacheStorageCacheQueryParams& match_params, 885 const CacheStorageCacheQueryParams& match_params,
845 const CacheStorageCache::ResponseCallback& callback) { 886 const CacheStorageCache::ResponseCallback& callback) {
846 std::unique_ptr<CacheStorageCacheHandle> cache_handle = 887 std::unique_ptr<CacheStorageCacheHandle> cache_handle =
847 GetLoadedCache(cache_name); 888 GetLoadedCache(cache_name);
848 889
(...skipping 20 matching lines...) Expand all
869 std::unique_ptr<ServiceWorkerResponse> response, 910 std::unique_ptr<ServiceWorkerResponse> response,
870 std::unique_ptr<storage::BlobDataHandle> handle) { 911 std::unique_ptr<storage::BlobDataHandle> handle) {
871 callback.Run(error, std::move(response), std::move(handle)); 912 callback.Run(error, std::move(response), std::move(handle));
872 } 913 }
873 914
874 void CacheStorage::MatchAllCachesImpl( 915 void CacheStorage::MatchAllCachesImpl(
875 std::unique_ptr<ServiceWorkerFetchRequest> request, 916 std::unique_ptr<ServiceWorkerFetchRequest> request,
876 const CacheStorageCacheQueryParams& match_params, 917 const CacheStorageCacheQueryParams& match_params,
877 const CacheStorageCache::ResponseCallback& callback) { 918 const CacheStorageCache::ResponseCallback& callback) {
878 std::vector<CacheMatchResponse>* match_responses = 919 std::vector<CacheMatchResponse>* match_responses =
879 new std::vector<CacheMatchResponse>(ordered_cache_names_.size()); 920 new std::vector<CacheMatchResponse>(cache_index_->num_entries());
880 921
881 base::Closure barrier_closure = base::BarrierClosure( 922 base::Closure barrier_closure = base::BarrierClosure(
882 ordered_cache_names_.size(), 923 cache_index_->num_entries(),
883 base::Bind(&CacheStorage::MatchAllCachesDidMatchAll, 924 base::Bind(&CacheStorage::MatchAllCachesDidMatchAll,
884 weak_factory_.GetWeakPtr(), 925 weak_factory_.GetWeakPtr(),
885 base::Passed(base::WrapUnique(match_responses)), callback)); 926 base::Passed(base::WrapUnique(match_responses)), callback));
886 927
887 for (size_t i = 0, max = ordered_cache_names_.size(); i < max; ++i) { 928 size_t idx = 0;
929 for (const auto& cache_metadata : cache_index_->ordered_cache_metadata()) {
888 std::unique_ptr<CacheStorageCacheHandle> cache_handle = 930 std::unique_ptr<CacheStorageCacheHandle> cache_handle =
889 GetLoadedCache(ordered_cache_names_[i]); 931 GetLoadedCache(cache_metadata.name);
890 DCHECK(cache_handle); 932 DCHECK(cache_handle);
891 933
892 CacheStorageCache* cache_ptr = cache_handle->value(); 934 CacheStorageCache* cache_ptr = cache_handle->value();
893 cache_ptr->Match(base::MakeUnique<ServiceWorkerFetchRequest>(*request), 935 cache_ptr->Match(base::MakeUnique<ServiceWorkerFetchRequest>(*request),
894 match_params, 936 match_params,
895 base::Bind(&CacheStorage::MatchAllCachesDidMatch, 937 base::Bind(&CacheStorage::MatchAllCachesDidMatch,
896 weak_factory_.GetWeakPtr(), 938 weak_factory_.GetWeakPtr(),
897 base::Passed(std::move(cache_handle)), 939 base::Passed(std::move(cache_handle)),
898 &match_responses->at(i), barrier_closure)); 940 &match_responses->at(idx), barrier_closure));
941 idx++;
899 } 942 }
900 } 943 }
901 944
902 void CacheStorage::MatchAllCachesDidMatch( 945 void CacheStorage::MatchAllCachesDidMatch(
903 std::unique_ptr<CacheStorageCacheHandle> cache_handle, 946 std::unique_ptr<CacheStorageCacheHandle> cache_handle,
904 CacheMatchResponse* out_match_response, 947 CacheMatchResponse* out_match_response,
905 const base::Closure& barrier_closure, 948 const base::Closure& barrier_closure,
906 CacheStorageError error, 949 CacheStorageError error,
907 std::unique_ptr<ServiceWorkerResponse> service_worker_response, 950 std::unique_ptr<ServiceWorkerResponse> service_worker_response,
908 std::unique_ptr<storage::BlobDataHandle> handle) { 951 std::unique_ptr<storage::BlobDataHandle> handle) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
975 DCHECK_CURRENTLY_ON(BrowserThread::IO); 1018 DCHECK_CURRENTLY_ON(BrowserThread::IO);
976 DCHECK(initialized_); 1019 DCHECK(initialized_);
977 1020
978 CacheMap::iterator map_iter = cache_map_.find(cache_name); 1021 CacheMap::iterator map_iter = cache_map_.find(cache_name);
979 if (map_iter == cache_map_.end()) 1022 if (map_iter == cache_map_.end())
980 return std::unique_ptr<CacheStorageCacheHandle>(); 1023 return std::unique_ptr<CacheStorageCacheHandle>();
981 1024
982 CacheStorageCache* cache = map_iter->second.get(); 1025 CacheStorageCache* cache = map_iter->second.get();
983 1026
984 if (!cache) { 1027 if (!cache) {
985 std::unique_ptr<CacheStorageCache> new_cache = 1028 std::unique_ptr<CacheStorageCache> new_cache = cache_loader_->CreateCache(
986 cache_loader_->CreateCache(cache_name); 1029 cache_name, cache_index_->GetCacheSize(cache_name));
987 CacheStorageCache* cache_ptr = new_cache.get(); 1030 CacheStorageCache* cache_ptr = new_cache.get();
988 map_iter->second = std::move(new_cache); 1031 map_iter->second = std::move(new_cache);
989 1032
990 return CreateCacheHandle(cache_ptr); 1033 return CreateCacheHandle(cache_ptr);
991 } 1034 }
992 1035
993 return CreateCacheHandle(cache); 1036 return CreateCacheHandle(cache);
994 } 1037 }
995 1038
1039 void CacheStorage::SizeRetrievedFromCache(
1040 std::unique_ptr<CacheStorageCacheHandle> cache_handle,
1041 const base::Closure& closure,
1042 int64_t* accumulator,
1043 int64_t size) {
1044 cache_index_->SetCacheSize(cache_handle->value()->cache_name(), size);
1045 *accumulator += size;
1046 closure.Run();
1047 }
1048
996 void CacheStorage::GetSizeThenCloseAllCachesImpl(const SizeCallback& callback) { 1049 void CacheStorage::GetSizeThenCloseAllCachesImpl(const SizeCallback& callback) {
997 DCHECK_CURRENTLY_ON(BrowserThread::IO); 1050 DCHECK_CURRENTLY_ON(BrowserThread::IO);
998 DCHECK(initialized_); 1051 DCHECK(initialized_);
999 1052
1000 std::unique_ptr<int64_t> accumulator(new int64_t(0)); 1053 std::unique_ptr<int64_t> accumulator(new int64_t(0));
1001 int64_t* accumulator_ptr = accumulator.get(); 1054 int64_t* accumulator_ptr = accumulator.get();
1002 1055
1003 base::Closure barrier_closure = base::BarrierClosure( 1056 base::Closure barrier_closure = base::BarrierClosure(
1004 ordered_cache_names_.size(), 1057 cache_index_->num_entries(),
1005 base::Bind(&SizeRetrievedFromAllCaches, 1058 base::Bind(&SizeRetrievedFromAllCaches,
1006 base::Passed(std::move(accumulator)), callback)); 1059 base::Passed(std::move(accumulator)), callback));
1007 1060
1008 for (const std::string& cache_name : ordered_cache_names_) { 1061 for (const auto& cache_metadata : cache_index_->ordered_cache_metadata()) {
1009 std::unique_ptr<CacheStorageCacheHandle> cache_handle = 1062 auto cache_handle = GetLoadedCache(cache_metadata.name);
1010 GetLoadedCache(cache_name);
1011 CacheStorageCache* cache = cache_handle->value(); 1063 CacheStorageCache* cache = cache_handle->value();
1012 cache->GetSizeThenClose(base::Bind(&SizeRetrievedFromCache, 1064 cache->GetSizeThenClose(base::Bind(&CacheStorage::SizeRetrievedFromCache,
1065 weak_factory_.GetWeakPtr(),
1013 base::Passed(std::move(cache_handle)), 1066 base::Passed(std::move(cache_handle)),
1014 barrier_closure, accumulator_ptr)); 1067 barrier_closure, accumulator_ptr));
1015 } 1068 }
1016 } 1069 }
1017 1070
1018 void CacheStorage::SizeImpl(const SizeCallback& callback) { 1071 void CacheStorage::SizeImpl(const SizeCallback& callback) {
1019 DCHECK_CURRENTLY_ON(BrowserThread::IO); 1072 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1020 DCHECK(initialized_); 1073 DCHECK(initialized_);
1021 1074
1075 if (cache_index_->GetStorageSize() != kSizeUnknown) {
1076 base::ThreadTaskRunnerHandle::Get()->PostTask(
1077 FROM_HERE, base::Bind(callback, cache_index_->GetStorageSize()));
1078 return;
1079 }
1080
1022 std::unique_ptr<int64_t> accumulator(new int64_t(0)); 1081 std::unique_ptr<int64_t> accumulator(new int64_t(0));
1023 int64_t* accumulator_ptr = accumulator.get(); 1082 int64_t* accumulator_ptr = accumulator.get();
1024 1083
1025 base::Closure barrier_closure = base::BarrierClosure( 1084 base::Closure barrier_closure = base::BarrierClosure(
1026 ordered_cache_names_.size(), 1085 cache_index_->num_entries(),
1027 base::Bind(&SizeRetrievedFromAllCaches, 1086 base::Bind(&SizeRetrievedFromAllCaches,
1028 base::Passed(std::move(accumulator)), callback)); 1087 base::Passed(std::move(accumulator)), callback));
1029 1088
1030 for (const std::string& cache_name : ordered_cache_names_) { 1089 for (const auto& cache_metadata : cache_index_->ordered_cache_metadata()) {
1090 if (cache_metadata.size != CacheStorage::kSizeUnknown) {
1091 *accumulator_ptr += cache_metadata.size;
1092 barrier_closure.Run();
1093 continue;
1094 }
1031 std::unique_ptr<CacheStorageCacheHandle> cache_handle = 1095 std::unique_ptr<CacheStorageCacheHandle> cache_handle =
1032 GetLoadedCache(cache_name); 1096 GetLoadedCache(cache_metadata.name);
1033 CacheStorageCache* cache = cache_handle->value(); 1097 CacheStorageCache* cache = cache_handle->value();
1034 cache->Size(base::Bind(&SizeRetrievedFromCache, 1098 cache->Size(base::Bind(&CacheStorage::SizeRetrievedFromCache,
1099 weak_factory_.GetWeakPtr(),
1035 base::Passed(std::move(cache_handle)), 1100 base::Passed(std::move(cache_handle)),
1036 barrier_closure, accumulator_ptr)); 1101 barrier_closure, accumulator_ptr));
1037 } 1102 }
1038 } 1103 }
1039 1104
1040 } // namespace content 1105 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698