OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |