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

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

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

Powered by Google App Engine
This is Rietveld 408576698