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

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: remediation and test update 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 15 matching lines...) Expand all
26 #include "base/time/time.h" 26 #include "base/time/time.h"
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_index.h" 31 #include "net/disk_cache/simple/simple_index.h"
32 #include "net/disk_cache/simple/simple_index_file.h" 32 #include "net/disk_cache/simple/simple_index_file.h"
33 #include "net/disk_cache/simple/simple_synchronous_entry.h" 33 #include "net/disk_cache/simple/simple_synchronous_entry.h"
34 #include "net/disk_cache/simple/simple_util.h" 34 #include "net/disk_cache/simple/simple_util.h"
35 35
36 using base::Callback;
36 using base::Closure; 37 using base::Closure;
37 using base::FilePath; 38 using base::FilePath;
38 using base::MessageLoopProxy; 39 using base::MessageLoopProxy;
39 using base::SequencedWorkerPool; 40 using base::SequencedWorkerPool;
40 using base::SingleThreadTaskRunner; 41 using base::SingleThreadTaskRunner;
41 using base::Time; 42 using base::Time;
42 using base::DirectoryExists; 43 using base::DirectoryExists;
43 using file_util::CreateDirectory; 44 using file_util::CreateDirectory;
44 45
45 namespace { 46 namespace {
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 return true; 190 return true;
190 } 191 }
191 } 192 }
192 193
193 void CallCompletionCallback(const net::CompletionCallback& callback, 194 void CallCompletionCallback(const net::CompletionCallback& callback,
194 int error_code) { 195 int error_code) {
195 DCHECK(!callback.is_null()); 196 DCHECK(!callback.is_null());
196 callback.Run(error_code); 197 callback.Run(error_code);
197 } 198 }
198 199
200 // See ChainOperationIntoClosure, below.
201 void ChainOperationIntoClosureImpl(
202 const Callback<int(const net::CompletionCallback&)>& to_chain_operation,
203 const net::CompletionCallback& operation_callback,
204 const Closure& closure) {
205 const int operation_result = to_chain_operation.Run(operation_callback);
206 if (operation_result != net::ERR_IO_PENDING)
207 operation_callback.Run(operation_result);
208 if (!closure.is_null())
209 closure.Run();
210 }
211
212 // Returns a Closure that will first run |to_chain_operation|, returning its
213 // result to |operation_callback|, and finally run |closure| if it is not null.
214 Closure ChainOperationIntoClosure(
215 const Callback<int(const net::CompletionCallback&)>& to_chain_operation,
216 const net::CompletionCallback& operation_callback,
217 const Closure& closure) {
218 return base::Bind(&ChainOperationIntoClosureImpl, to_chain_operation,
219 operation_callback, closure);
220 }
221
199 void RecordIndexLoad(base::TimeTicks constructed_since, int result) { 222 void RecordIndexLoad(base::TimeTicks constructed_since, int result) {
200 const base::TimeDelta creation_to_index = base::TimeTicks::Now() - 223 const base::TimeDelta creation_to_index = base::TimeTicks::Now() -
201 constructed_since; 224 constructed_since;
202 if (result == net::OK) 225 if (result == net::OK)
203 UMA_HISTOGRAM_TIMES("SimpleCache.CreationToIndex", creation_to_index); 226 UMA_HISTOGRAM_TIMES("SimpleCache.CreationToIndex", creation_to_index);
204 else 227 else
205 UMA_HISTOGRAM_TIMES("SimpleCache.CreationToIndexFail", creation_to_index); 228 UMA_HISTOGRAM_TIMES("SimpleCache.CreationToIndexFail", creation_to_index);
206 } 229 }
207 230
208 } // namespace 231 } // namespace
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 } 282 }
260 283
261 int SimpleBackendImpl::GetMaxFileSize() const { 284 int SimpleBackendImpl::GetMaxFileSize() const {
262 return index_->max_size() / kMaxFileRatio; 285 return index_->max_size() / kMaxFileRatio;
263 } 286 }
264 287
265 void SimpleBackendImpl::OnDeactivated(const SimpleEntryImpl* entry) { 288 void SimpleBackendImpl::OnDeactivated(const SimpleEntryImpl* entry) {
266 active_entries_.erase(entry->entry_hash()); 289 active_entries_.erase(entry->entry_hash());
267 } 290 }
268 291
292 void SimpleBackendImpl::OnDoomStart(uint64 entry_hash) {
293 DCHECK_EQ(0u, entries_pending_doom_.count(entry_hash));
294 entries_pending_doom_.insert(std::make_pair(entry_hash, Closure()));
295 }
296
297 void SimpleBackendImpl::OnDoomComplete(uint64 entry_hash) {
298 DCHECK_EQ(1u, entries_pending_doom_.count(entry_hash));
299 base::hash_map<uint64, base::Closure>::iterator it =
300 entries_pending_doom_.find(entry_hash);
301 Closure to_run_closure = it->second;
302 entries_pending_doom_.erase(it);
303
304 if (!to_run_closure.is_null())
305 to_run_closure.Run();
306 }
307
269 net::CacheType SimpleBackendImpl::GetCacheType() const { 308 net::CacheType SimpleBackendImpl::GetCacheType() const {
270 return net::DISK_CACHE; 309 return net::DISK_CACHE;
271 } 310 }
272 311
273 int32 SimpleBackendImpl::GetEntryCount() const { 312 int32 SimpleBackendImpl::GetEntryCount() const {
274 // TODO(pasko): Use directory file count when index is not ready. 313 // TODO(pasko): Use directory file count when index is not ready.
275 return index_->GetEntryCount(); 314 return index_->GetEntryCount();
276 } 315 }
277 316
278 int SimpleBackendImpl::OpenEntry(const std::string& key, 317 int SimpleBackendImpl::OpenEntry(const std::string& key,
279 Entry** entry, 318 Entry** entry,
280 const CompletionCallback& callback) { 319 const CompletionCallback& callback) {
281 scoped_refptr<SimpleEntryImpl> simple_entry = CreateOrFindActiveEntry(key); 320 const uint64 entry_hash = simple_util::GetEntryHashKey(key);
321
322 base::hash_map<uint64, base::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 = ChainOperationIntoClosure(operation, callback, it->second);
Deprecated (see juliatuttle) 2013/09/03 16:15:11 This is really clever, but I think it's less clear
Philippe 2013/09/03 16:24:33 I agree at a glance that a map/multimap would look
Philippe 2013/09/03 16:25:58 s/how this/what this :)
Randy Smith (Not in Mondays) 2013/09/03 19:04:19 I think I'd prefer a map to a vector as Thomas sug
Philippe 2013/09/04 08:55:49 Right, this should work actually thanks to the ope
gavinp 2013/09/11 15:25:58 The latest upload uses a vector, and the code is v
329 return net::ERR_IO_PENDING;
330 }
331 scoped_refptr<SimpleEntryImpl> simple_entry =
332 CreateOrFindActiveEntry(entry_hash, key);
282 CompletionCallback backend_callback = 333 CompletionCallback backend_callback =
283 base::Bind(&SimpleBackendImpl::OnEntryOpenedFromKey, 334 base::Bind(&SimpleBackendImpl::OnEntryOpenedFromKey,
284 AsWeakPtr(), 335 AsWeakPtr(),
285 key, 336 key,
286 entry, 337 entry,
287 simple_entry, 338 simple_entry,
288 callback); 339 callback);
289 return simple_entry->OpenEntry(entry, backend_callback); 340 return simple_entry->OpenEntry(entry, backend_callback);
290 } 341 }
291 342
292 int SimpleBackendImpl::CreateEntry(const std::string& key, 343 int SimpleBackendImpl::CreateEntry(const std::string& key,
293 Entry** entry, 344 Entry** entry,
294 const CompletionCallback& callback) { 345 const CompletionCallback& callback) {
295 DCHECK(key.size() > 0); 346 DCHECK_GT(key.size(), 0u);
296 scoped_refptr<SimpleEntryImpl> simple_entry = CreateOrFindActiveEntry(key); 347 const uint64 entry_hash = simple_util::GetEntryHashKey(key);
348
349 base::hash_map<uint64, base::Closure>::iterator it =
350 entries_pending_doom_.find(entry_hash);
351 if (it != entries_pending_doom_.end()) {
352 Callback<int(const net::CompletionCallback&)> operation =
353 base::Bind(&SimpleBackendImpl::CreateEntry,
354 base::Unretained(this), key, entry);
355 it->second = ChainOperationIntoClosure(operation, callback, it->second);
356 return net::ERR_IO_PENDING;
357 }
358 scoped_refptr<SimpleEntryImpl> simple_entry =
359 CreateOrFindActiveEntry(entry_hash, key);
297 return simple_entry->CreateEntry(entry, callback); 360 return simple_entry->CreateEntry(entry, callback);
298 } 361 }
299 362
300 int SimpleBackendImpl::DoomEntry(const std::string& key, 363 int SimpleBackendImpl::DoomEntry(const std::string& key,
301 const net::CompletionCallback& callback) { 364 const net::CompletionCallback& callback) {
302 scoped_refptr<SimpleEntryImpl> simple_entry = CreateOrFindActiveEntry(key); 365 const uint64 entry_hash = simple_util::GetEntryHashKey(key);
366
367 base::hash_map<uint64, base::Closure>::iterator it =
368 entries_pending_doom_.find(entry_hash);
369 if (it != entries_pending_doom_.end()) {
370 Callback<int(const net::CompletionCallback&)> operation =
371 base::Bind(&SimpleBackendImpl::DoomEntry, base::Unretained(this), key);
372 it->second = ChainOperationIntoClosure(operation, callback, it->second);
373 return net::ERR_IO_PENDING;
374 }
375 scoped_refptr<SimpleEntryImpl> simple_entry =
376 CreateOrFindActiveEntry(entry_hash, key);
303 return simple_entry->DoomEntry(callback); 377 return simple_entry->DoomEntry(callback);
304 } 378 }
305 379
306 int SimpleBackendImpl::DoomAllEntries(const CompletionCallback& callback) { 380 int SimpleBackendImpl::DoomAllEntries(const CompletionCallback& callback) {
307 return DoomEntriesBetween(Time(), Time(), callback); 381 return DoomEntriesBetween(Time(), Time(), callback);
308 } 382 }
309 383
310 void SimpleBackendImpl::IndexReadyForDoom(Time initial_time, 384 void SimpleBackendImpl::IndexReadyForDoom(Time initial_time,
311 Time end_time, 385 Time end_time,
312 const CompletionCallback& callback, 386 const CompletionCallback& callback,
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 // TODO(pasko): Move PreferedCacheSize() to cache_util.h. Also fix the 489 // TODO(pasko): Move PreferedCacheSize() to cache_util.h. Also fix the
416 // spelling. 490 // spelling.
417 result.max_size = disk_cache::PreferedCacheSize(available); 491 result.max_size = disk_cache::PreferedCacheSize(available);
418 } 492 }
419 DCHECK(result.max_size); 493 DCHECK(result.max_size);
420 } 494 }
421 return result; 495 return result;
422 } 496 }
423 497
424 scoped_refptr<SimpleEntryImpl> SimpleBackendImpl::CreateOrFindActiveEntry( 498 scoped_refptr<SimpleEntryImpl> SimpleBackendImpl::CreateOrFindActiveEntry(
499 const uint64 entry_hash,
425 const std::string& key) { 500 const std::string& key) {
Randy Smith (Not in Mondays) 2013/09/03 19:04:19 Suggestion: DCHECK(entry_hash, simple_util::GetEnt
gavinp 2013/09/11 15:25:58 Done.
426 const uint64 entry_hash = simple_util::GetEntryHashKey(key);
427
428 std::pair<EntryMap::iterator, bool> insert_result = 501 std::pair<EntryMap::iterator, bool> insert_result =
429 active_entries_.insert(std::make_pair(entry_hash, 502 active_entries_.insert(std::make_pair(entry_hash,
430 base::WeakPtr<SimpleEntryImpl>())); 503 base::WeakPtr<SimpleEntryImpl>()));
431 EntryMap::iterator& it = insert_result.first; 504 EntryMap::iterator& it = insert_result.first;
432 if (insert_result.second) 505 if (insert_result.second)
433 DCHECK(!it->second.get()); 506 DCHECK(!it->second.get());
434 if (!it->second.get()) { 507 if (!it->second.get()) {
435 SimpleEntryImpl* entry = new SimpleEntryImpl( 508 SimpleEntryImpl* entry = new SimpleEntryImpl(
436 path_, entry_hash, entry_operations_mode_, this, net_log_); 509 path_, entry_hash, entry_operations_mode_, this, net_log_);
437 entry->SetKey(key); 510 entry->SetKey(key);
438 it->second = entry->AsWeakPtr(); 511 it->second = entry->AsWeakPtr();
439 } 512 }
440 DCHECK(it->second.get()); 513 DCHECK(it->second.get());
441 // It's possible, but unlikely, that we have an entry hash collision with a 514 // It's possible, but unlikely, that we have an entry hash collision with a
442 // currently active entry. 515 // currently active entry.
443 if (key != it->second->key()) { 516 if (key != it->second->key()) {
444 it->second->Doom(); 517 it->second->Doom();
445 DCHECK_EQ(0U, active_entries_.count(entry_hash)); 518 DCHECK_EQ(0U, active_entries_.count(entry_hash));
446 return CreateOrFindActiveEntry(key); 519 return CreateOrFindActiveEntry(entry_hash, key);
447 } 520 }
448 return make_scoped_refptr(it->second.get()); 521 return make_scoped_refptr(it->second.get());
449 } 522 }
450 523
451 int SimpleBackendImpl::OpenEntryFromHash(uint64 hash, 524 int SimpleBackendImpl::OpenEntryFromHash(uint64 hash,
452 Entry** entry, 525 Entry** entry,
453 const CompletionCallback& callback) { 526 const CompletionCallback& callback) {
454 EntryMap::iterator has_active = active_entries_.find(hash); 527 EntryMap::iterator has_active = active_entries_.find(hash);
455 if (has_active != active_entries_.end()) 528 if (has_active != active_entries_.end())
456 return OpenEntry(has_active->second->key(), entry, callback); 529 return OpenEntry(has_active->second->key(), entry, callback);
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 const CompletionCallback& callback, 635 const CompletionCallback& callback,
563 int error_code) { 636 int error_code) {
564 if (error_code == net::ERR_FAILED) { 637 if (error_code == net::ERR_FAILED) {
565 OpenNextEntry(iter, entry, callback); 638 OpenNextEntry(iter, entry, callback);
566 return; 639 return;
567 } 640 }
568 CallCompletionCallback(callback, error_code); 641 CallCompletionCallback(callback, error_code);
569 } 642 }
570 643
571 } // namespace disk_cache 644 } // 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