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: net/disk_cache/simple/simple_backend_impl.cc

Issue 23486006: Track entries pending Doom in SimpleCache backend. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add TODO Created 7 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « net/disk_cache/simple/simple_backend_impl.h ('k') | net/disk_cache/simple/simple_entry_impl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "net/disk_cache/simple/simple_backend_impl.h" 5 #include "net/disk_cache/simple/simple_backend_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cstdlib> 8 #include <cstdlib>
9 9
10 #if defined(OS_POSIX) 10 #if defined(OS_POSIX)
(...skipping 16 matching lines...) Expand all
27 #include "net/base/net_errors.h" 27 #include "net/base/net_errors.h"
28 #include "net/disk_cache/backend_impl.h" 28 #include "net/disk_cache/backend_impl.h"
29 #include "net/disk_cache/simple/simple_entry_format.h" 29 #include "net/disk_cache/simple/simple_entry_format.h"
30 #include "net/disk_cache/simple/simple_entry_impl.h" 30 #include "net/disk_cache/simple/simple_entry_impl.h"
31 #include "net/disk_cache/simple/simple_histogram_macros.h" 31 #include "net/disk_cache/simple/simple_histogram_macros.h"
32 #include "net/disk_cache/simple/simple_index.h" 32 #include "net/disk_cache/simple/simple_index.h"
33 #include "net/disk_cache/simple/simple_index_file.h" 33 #include "net/disk_cache/simple/simple_index_file.h"
34 #include "net/disk_cache/simple/simple_synchronous_entry.h" 34 #include "net/disk_cache/simple/simple_synchronous_entry.h"
35 #include "net/disk_cache/simple/simple_util.h" 35 #include "net/disk_cache/simple/simple_util.h"
36 36
37 using base::Callback;
37 using base::Closure; 38 using base::Closure;
38 using base::FilePath; 39 using base::FilePath;
39 using base::MessageLoopProxy; 40 using base::MessageLoopProxy;
40 using base::SequencedWorkerPool; 41 using base::SequencedWorkerPool;
41 using base::SingleThreadTaskRunner; 42 using base::SingleThreadTaskRunner;
42 using base::Time; 43 using base::Time;
43 using base::DirectoryExists; 44 using base::DirectoryExists;
44 using file_util::CreateDirectory; 45 using file_util::CreateDirectory;
45 46
46 namespace { 47 namespace {
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 } 194 }
194 195
195 // A short bindable thunk that can call a completion callback. Intended to be 196 // A short bindable thunk that can call a completion callback. Intended to be
196 // used to post a task to run a callback after an operation completes. 197 // used to post a task to run a callback after an operation completes.
197 void CallCompletionCallback(const net::CompletionCallback& callback, 198 void CallCompletionCallback(const net::CompletionCallback& callback,
198 int error_code) { 199 int error_code) {
199 DCHECK(!callback.is_null()); 200 DCHECK(!callback.is_null());
200 callback.Run(error_code); 201 callback.Run(error_code);
201 } 202 }
202 203
204 // A short bindable thunk that ensures a completion callback is always called
205 // after running an operation asynchronously.
206 void RunOperationAndCallback(
207 const Callback<int(const net::CompletionCallback&)>& operation,
208 const net::CompletionCallback& operation_callback) {
209 const int operation_result = operation.Run(operation_callback);
210 if (operation_result != net::ERR_IO_PENDING)
211 operation_callback.Run(operation_result);
212 }
213
203 void RecordIndexLoad(net::CacheType cache_type, 214 void RecordIndexLoad(net::CacheType cache_type,
204 base::TimeTicks constructed_since, 215 base::TimeTicks constructed_since,
205 int result) { 216 int result) {
206 const base::TimeDelta creation_to_index = base::TimeTicks::Now() - 217 const base::TimeDelta creation_to_index = base::TimeTicks::Now() -
207 constructed_since; 218 constructed_since;
208 if (result == net::OK) { 219 if (result == net::OK) {
209 SIMPLE_CACHE_UMA(TIMES, "CreationToIndex", cache_type, creation_to_index); 220 SIMPLE_CACHE_UMA(TIMES, "CreationToIndex", cache_type, creation_to_index);
210 } else { 221 } else {
211 SIMPLE_CACHE_UMA(TIMES, 222 SIMPLE_CACHE_UMA(TIMES,
212 "CreationToIndexFail", cache_type, creation_to_index); 223 "CreationToIndexFail", cache_type, creation_to_index);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 } 278 }
268 279
269 int SimpleBackendImpl::GetMaxFileSize() const { 280 int SimpleBackendImpl::GetMaxFileSize() const {
270 return index_->max_size() / kMaxFileRatio; 281 return index_->max_size() / kMaxFileRatio;
271 } 282 }
272 283
273 void SimpleBackendImpl::OnDeactivated(const SimpleEntryImpl* entry) { 284 void SimpleBackendImpl::OnDeactivated(const SimpleEntryImpl* entry) {
274 active_entries_.erase(entry->entry_hash()); 285 active_entries_.erase(entry->entry_hash());
275 } 286 }
276 287
288 void SimpleBackendImpl::OnDoomStart(uint64 entry_hash) {
289 DCHECK_EQ(0u, entries_pending_doom_.count(entry_hash));
290 entries_pending_doom_.insert(
291 std::make_pair(entry_hash, std::vector<Closure>()));
292 }
293
294 void SimpleBackendImpl::OnDoomComplete(uint64 entry_hash) {
295 DCHECK_EQ(1u, entries_pending_doom_.count(entry_hash));
296 base::hash_map<uint64, std::vector<Closure> >::iterator it =
297 entries_pending_doom_.find(entry_hash);
298 std::vector<Closure> to_run_closures;
299 to_run_closures.swap(it->second);
300 entries_pending_doom_.erase(it);
301
302 std::for_each(to_run_closures.begin(), to_run_closures.end(),
303 std::mem_fun_ref(&Closure::Run));
304 }
305
277 net::CacheType SimpleBackendImpl::GetCacheType() const { 306 net::CacheType SimpleBackendImpl::GetCacheType() const {
278 return net::DISK_CACHE; 307 return net::DISK_CACHE;
279 } 308 }
280 309
281 int32 SimpleBackendImpl::GetEntryCount() const { 310 int32 SimpleBackendImpl::GetEntryCount() const {
282 // TODO(pasko): Use directory file count when index is not ready. 311 // TODO(pasko): Use directory file count when index is not ready.
283 return index_->GetEntryCount(); 312 return index_->GetEntryCount();
284 } 313 }
285 314
286 int SimpleBackendImpl::OpenEntry(const std::string& key, 315 int SimpleBackendImpl::OpenEntry(const std::string& key,
287 Entry** entry, 316 Entry** entry,
288 const CompletionCallback& callback) { 317 const CompletionCallback& callback) {
289 scoped_refptr<SimpleEntryImpl> simple_entry = CreateOrFindActiveEntry(key); 318 const uint64 entry_hash = simple_util::GetEntryHashKey(key);
319
320 // TODO(gavinp): Factor out this (not quite completely) repetitive code
321 // block from OpenEntry/CreateEntry/DoomEntry.
322 base::hash_map<uint64, std::vector<Closure> >::iterator it =
323 entries_pending_doom_.find(entry_hash);
324 if (it != entries_pending_doom_.end()) {
325 Callback<int(const net::CompletionCallback&)> operation =
326 base::Bind(&SimpleBackendImpl::OpenEntry,
327 base::Unretained(this), key, entry);
328 it->second.push_back(base::Bind(&RunOperationAndCallback,
329 operation, callback));
330 return net::ERR_IO_PENDING;
331 }
332 scoped_refptr<SimpleEntryImpl> simple_entry =
333 CreateOrFindActiveEntry(entry_hash, key);
290 CompletionCallback backend_callback = 334 CompletionCallback backend_callback =
291 base::Bind(&SimpleBackendImpl::OnEntryOpenedFromKey, 335 base::Bind(&SimpleBackendImpl::OnEntryOpenedFromKey,
292 AsWeakPtr(), 336 AsWeakPtr(),
293 key, 337 key,
294 entry, 338 entry,
295 simple_entry, 339 simple_entry,
296 callback); 340 callback);
297 return simple_entry->OpenEntry(entry, backend_callback); 341 return simple_entry->OpenEntry(entry, backend_callback);
298 } 342 }
299 343
300 int SimpleBackendImpl::CreateEntry(const std::string& key, 344 int SimpleBackendImpl::CreateEntry(const std::string& key,
301 Entry** entry, 345 Entry** entry,
302 const CompletionCallback& callback) { 346 const CompletionCallback& callback) {
303 DCHECK_LT(0u, key.size()); 347 DCHECK_LT(0u, key.size());
304 scoped_refptr<SimpleEntryImpl> simple_entry = CreateOrFindActiveEntry(key); 348 const uint64 entry_hash = simple_util::GetEntryHashKey(key);
349
350 base::hash_map<uint64, std::vector<Closure> >::iterator it =
351 entries_pending_doom_.find(entry_hash);
352 if (it != entries_pending_doom_.end()) {
353 Callback<int(const net::CompletionCallback&)> operation =
354 base::Bind(&SimpleBackendImpl::CreateEntry,
355 base::Unretained(this), key, entry);
356 it->second.push_back(base::Bind(&RunOperationAndCallback,
357 operation, callback));
358 return net::ERR_IO_PENDING;
359 }
360 scoped_refptr<SimpleEntryImpl> simple_entry =
361 CreateOrFindActiveEntry(entry_hash, key);
305 return simple_entry->CreateEntry(entry, callback); 362 return simple_entry->CreateEntry(entry, callback);
306 } 363 }
307 364
308 int SimpleBackendImpl::DoomEntry(const std::string& key, 365 int SimpleBackendImpl::DoomEntry(const std::string& key,
309 const net::CompletionCallback& callback) { 366 const net::CompletionCallback& callback) {
310 scoped_refptr<SimpleEntryImpl> simple_entry = CreateOrFindActiveEntry(key); 367 const uint64 entry_hash = simple_util::GetEntryHashKey(key);
311 return simple_entry->DoomEntry(callback); 368
369 base::hash_map<uint64, std::vector<Closure> >::iterator it =
370 entries_pending_doom_.find(entry_hash);
371 if (it != entries_pending_doom_.end()) {
372 Callback<int(const net::CompletionCallback&)> operation =
373 base::Bind(&SimpleBackendImpl::DoomEntry, base::Unretained(this), key);
374 it->second.push_back(base::Bind(&RunOperationAndCallback,
375 operation, callback));
376 return net::ERR_IO_PENDING;
377 }
378 scoped_refptr<SimpleEntryImpl> simple_entry =
379 CreateOrFindActiveEntry(entry_hash, key);
380 return simple_entry->DoomEntry(callback);
312 } 381 }
313 382
314 int SimpleBackendImpl::DoomAllEntries(const CompletionCallback& callback) { 383 int SimpleBackendImpl::DoomAllEntries(const CompletionCallback& callback) {
315 return DoomEntriesBetween(Time(), Time(), callback); 384 return DoomEntriesBetween(Time(), Time(), callback);
316 } 385 }
317 386
318 void SimpleBackendImpl::IndexReadyForDoom(Time initial_time, 387 void SimpleBackendImpl::IndexReadyForDoom(Time initial_time,
319 Time end_time, 388 Time end_time,
320 const CompletionCallback& callback, 389 const CompletionCallback& callback,
321 int result) { 390 int result) {
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 // TODO(pasko): Move PreferedCacheSize() to cache_util.h. Also fix the 491 // TODO(pasko): Move PreferedCacheSize() to cache_util.h. Also fix the
423 // spelling. 492 // spelling.
424 result.max_size = disk_cache::PreferedCacheSize(available); 493 result.max_size = disk_cache::PreferedCacheSize(available);
425 } 494 }
426 DCHECK(result.max_size); 495 DCHECK(result.max_size);
427 } 496 }
428 return result; 497 return result;
429 } 498 }
430 499
431 scoped_refptr<SimpleEntryImpl> SimpleBackendImpl::CreateOrFindActiveEntry( 500 scoped_refptr<SimpleEntryImpl> SimpleBackendImpl::CreateOrFindActiveEntry(
501 const uint64 entry_hash,
432 const std::string& key) { 502 const std::string& key) {
433 const uint64 entry_hash = simple_util::GetEntryHashKey(key); 503 DCHECK_EQ(entry_hash, simple_util::GetEntryHashKey(key));
434
435 std::pair<EntryMap::iterator, bool> insert_result = 504 std::pair<EntryMap::iterator, bool> insert_result =
436 active_entries_.insert(std::make_pair(entry_hash, 505 active_entries_.insert(std::make_pair(entry_hash,
437 base::WeakPtr<SimpleEntryImpl>())); 506 base::WeakPtr<SimpleEntryImpl>()));
438 EntryMap::iterator& it = insert_result.first; 507 EntryMap::iterator& it = insert_result.first;
439 if (insert_result.second) 508 if (insert_result.second)
440 DCHECK(!it->second.get()); 509 DCHECK(!it->second.get());
441 if (!it->second.get()) { 510 if (!it->second.get()) {
442 SimpleEntryImpl* entry = new SimpleEntryImpl( 511 SimpleEntryImpl* entry = new SimpleEntryImpl(
443 cache_type_, path_, entry_hash, entry_operations_mode_, this, net_log_); 512 cache_type_, path_, entry_hash, entry_operations_mode_, this, net_log_);
444 entry->SetKey(key); 513 entry->SetKey(key);
445 it->second = entry->AsWeakPtr(); 514 it->second = entry->AsWeakPtr();
446 } 515 }
447 DCHECK(it->second.get()); 516 DCHECK(it->second.get());
448 // It's possible, but unlikely, that we have an entry hash collision with a 517 // It's possible, but unlikely, that we have an entry hash collision with a
449 // currently active entry. 518 // currently active entry.
450 if (key != it->second->key()) { 519 if (key != it->second->key()) {
451 it->second->Doom(); 520 it->second->Doom();
452 DCHECK_EQ(0U, active_entries_.count(entry_hash)); 521 DCHECK_EQ(0U, active_entries_.count(entry_hash));
453 return CreateOrFindActiveEntry(key); 522 return CreateOrFindActiveEntry(entry_hash, key);
454 } 523 }
455 return make_scoped_refptr(it->second.get()); 524 return make_scoped_refptr(it->second.get());
456 } 525 }
457 526
458 int SimpleBackendImpl::OpenEntryFromHash(uint64 hash, 527 int SimpleBackendImpl::OpenEntryFromHash(uint64 hash,
459 Entry** entry, 528 Entry** entry,
460 const CompletionCallback& callback) { 529 const CompletionCallback& callback) {
461 EntryMap::iterator has_active = active_entries_.find(hash); 530 EntryMap::iterator has_active = active_entries_.find(hash);
462 if (has_active != active_entries_.end()) 531 if (has_active != active_entries_.end())
463 return OpenEntry(has_active->second->key(), entry, callback); 532 return OpenEntry(has_active->second->key(), entry, callback);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 } 643 }
575 callback.Run(error_code); 644 callback.Run(error_code);
576 } 645 }
577 646
578 void SimpleBackendImpl::FlushWorkerPoolForTesting() { 647 void SimpleBackendImpl::FlushWorkerPoolForTesting() {
579 if (g_sequenced_worker_pool) 648 if (g_sequenced_worker_pool)
580 g_sequenced_worker_pool->FlushForTesting(); 649 g_sequenced_worker_pool->FlushForTesting();
581 } 650 }
582 651
583 } // namespace disk_cache 652 } // namespace disk_cache
OLDNEW
« no previous file with comments | « net/disk_cache/simple/simple_backend_impl.h ('k') | net/disk_cache/simple/simple_entry_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698