| 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 // See ChainOperationIntoClosure, below. |
| 205 void ChainOperationIntoClosureImpl( |
| 206 const Callback<int(const net::CompletionCallback&)>& to_chain_operation, |
| 207 const net::CompletionCallback& operation_callback, |
| 208 const Closure& closure) { |
| 209 const int operation_result = to_chain_operation.Run(operation_callback); |
| 210 if (operation_result != net::ERR_IO_PENDING) |
| 211 operation_callback.Run(operation_result); |
| 212 if (!closure.is_null()) |
| 213 closure.Run(); |
| 214 } |
| 215 |
| 216 // Returns a Closure that will first run |to_chain_operation|, returning its |
| 217 // result to |operation_callback|, and finally run |closure| if it is not null. |
| 218 Closure ChainOperationIntoClosure( |
| 219 const Callback<int(const net::CompletionCallback&)>& to_chain_operation, |
| 220 const net::CompletionCallback& operation_callback, |
| 221 const Closure& closure) { |
| 222 return base::Bind(&ChainOperationIntoClosureImpl, to_chain_operation, |
| 223 operation_callback, closure); |
| 224 } |
| 225 |
| 203 void RecordIndexLoad(net::CacheType cache_type, | 226 void RecordIndexLoad(net::CacheType cache_type, |
| 204 base::TimeTicks constructed_since, | 227 base::TimeTicks constructed_since, |
| 205 int result) { | 228 int result) { |
| 206 const base::TimeDelta creation_to_index = base::TimeTicks::Now() - | 229 const base::TimeDelta creation_to_index = base::TimeTicks::Now() - |
| 207 constructed_since; | 230 constructed_since; |
| 208 if (result == net::OK) { | 231 if (result == net::OK) { |
| 209 SIMPLE_CACHE_UMA(TIMES, "CreationToIndex", cache_type, creation_to_index); | 232 SIMPLE_CACHE_UMA(TIMES, "CreationToIndex", cache_type, creation_to_index); |
| 210 } else { | 233 } else { |
| 211 SIMPLE_CACHE_UMA(TIMES, | 234 SIMPLE_CACHE_UMA(TIMES, |
| 212 "CreationToIndexFail", cache_type, creation_to_index); | 235 "CreationToIndexFail", cache_type, creation_to_index); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 } | 290 } |
| 268 | 291 |
| 269 int SimpleBackendImpl::GetMaxFileSize() const { | 292 int SimpleBackendImpl::GetMaxFileSize() const { |
| 270 return index_->max_size() / kMaxFileRatio; | 293 return index_->max_size() / kMaxFileRatio; |
| 271 } | 294 } |
| 272 | 295 |
| 273 void SimpleBackendImpl::OnDeactivated(const SimpleEntryImpl* entry) { | 296 void SimpleBackendImpl::OnDeactivated(const SimpleEntryImpl* entry) { |
| 274 active_entries_.erase(entry->entry_hash()); | 297 active_entries_.erase(entry->entry_hash()); |
| 275 } | 298 } |
| 276 | 299 |
| 300 void SimpleBackendImpl::OnDoomStart(uint64 entry_hash) { |
| 301 DCHECK_EQ(0u, entries_pending_doom_.count(entry_hash)); |
| 302 entries_pending_doom_.insert(std::make_pair(entry_hash, Closure())); |
| 303 } |
| 304 |
| 305 void SimpleBackendImpl::OnDoomComplete(uint64 entry_hash) { |
| 306 DCHECK_EQ(1u, entries_pending_doom_.count(entry_hash)); |
| 307 base::hash_map<uint64, base::Closure>::iterator it = |
| 308 entries_pending_doom_.find(entry_hash); |
| 309 Closure to_run_closure = it->second; |
| 310 entries_pending_doom_.erase(it); |
| 311 |
| 312 if (!to_run_closure.is_null()) |
| 313 to_run_closure.Run(); |
| 314 } |
| 315 |
| 277 net::CacheType SimpleBackendImpl::GetCacheType() const { | 316 net::CacheType SimpleBackendImpl::GetCacheType() const { |
| 278 return net::DISK_CACHE; | 317 return net::DISK_CACHE; |
| 279 } | 318 } |
| 280 | 319 |
| 281 int32 SimpleBackendImpl::GetEntryCount() const { | 320 int32 SimpleBackendImpl::GetEntryCount() const { |
| 282 // TODO(pasko): Use directory file count when index is not ready. | 321 // TODO(pasko): Use directory file count when index is not ready. |
| 283 return index_->GetEntryCount(); | 322 return index_->GetEntryCount(); |
| 284 } | 323 } |
| 285 | 324 |
| 286 int SimpleBackendImpl::OpenEntry(const std::string& key, | 325 int SimpleBackendImpl::OpenEntry(const std::string& key, |
| 287 Entry** entry, | 326 Entry** entry, |
| 288 const CompletionCallback& callback) { | 327 const CompletionCallback& callback) { |
| 289 scoped_refptr<SimpleEntryImpl> simple_entry = CreateOrFindActiveEntry(key); | 328 const uint64 entry_hash = simple_util::GetEntryHashKey(key); |
| 329 |
| 330 base::hash_map<uint64, base::Closure>::iterator it = |
| 331 entries_pending_doom_.find(entry_hash); |
| 332 if (it != entries_pending_doom_.end()) { |
| 333 Callback<int(const net::CompletionCallback&)> operation = |
| 334 base::Bind(&SimpleBackendImpl::OpenEntry, |
| 335 base::Unretained(this), key, entry); |
| 336 it->second = ChainOperationIntoClosure(operation, callback, it->second); |
| 337 return net::ERR_IO_PENDING; |
| 338 } |
| 339 scoped_refptr<SimpleEntryImpl> simple_entry = |
| 340 CreateOrFindActiveEntry(entry_hash, key); |
| 290 CompletionCallback backend_callback = | 341 CompletionCallback backend_callback = |
| 291 base::Bind(&SimpleBackendImpl::OnEntryOpenedFromKey, | 342 base::Bind(&SimpleBackendImpl::OnEntryOpenedFromKey, |
| 292 AsWeakPtr(), | 343 AsWeakPtr(), |
| 293 key, | 344 key, |
| 294 entry, | 345 entry, |
| 295 simple_entry, | 346 simple_entry, |
| 296 callback); | 347 callback); |
| 297 return simple_entry->OpenEntry(entry, backend_callback); | 348 return simple_entry->OpenEntry(entry, backend_callback); |
| 298 } | 349 } |
| 299 | 350 |
| 300 int SimpleBackendImpl::CreateEntry(const std::string& key, | 351 int SimpleBackendImpl::CreateEntry(const std::string& key, |
| 301 Entry** entry, | 352 Entry** entry, |
| 302 const CompletionCallback& callback) { | 353 const CompletionCallback& callback) { |
| 303 DCHECK_LT(0u, key.size()); | 354 DCHECK_LT(0u, key.size()); |
| 304 scoped_refptr<SimpleEntryImpl> simple_entry = CreateOrFindActiveEntry(key); | 355 const uint64 entry_hash = simple_util::GetEntryHashKey(key); |
| 356 |
| 357 base::hash_map<uint64, base::Closure>::iterator it = |
| 358 entries_pending_doom_.find(entry_hash); |
| 359 if (it != entries_pending_doom_.end()) { |
| 360 Callback<int(const net::CompletionCallback&)> operation = |
| 361 base::Bind(&SimpleBackendImpl::CreateEntry, |
| 362 base::Unretained(this), key, entry); |
| 363 it->second = ChainOperationIntoClosure(operation, callback, it->second); |
| 364 return net::ERR_IO_PENDING; |
| 365 } |
| 366 scoped_refptr<SimpleEntryImpl> simple_entry = |
| 367 CreateOrFindActiveEntry(entry_hash, key); |
| 305 return simple_entry->CreateEntry(entry, callback); | 368 return simple_entry->CreateEntry(entry, callback); |
| 306 } | 369 } |
| 307 | 370 |
| 308 int SimpleBackendImpl::DoomEntry(const std::string& key, | 371 int SimpleBackendImpl::DoomEntry(const std::string& key, |
| 309 const net::CompletionCallback& callback) { | 372 const net::CompletionCallback& callback) { |
| 310 scoped_refptr<SimpleEntryImpl> simple_entry = CreateOrFindActiveEntry(key); | 373 const uint64 entry_hash = simple_util::GetEntryHashKey(key); |
| 311 return simple_entry->DoomEntry(callback); | 374 |
| 375 base::hash_map<uint64, base::Closure>::iterator it = |
| 376 entries_pending_doom_.find(entry_hash); |
| 377 if (it != entries_pending_doom_.end()) { |
| 378 Callback<int(const net::CompletionCallback&)> operation = |
| 379 base::Bind(&SimpleBackendImpl::DoomEntry, base::Unretained(this), key); |
| 380 it->second = ChainOperationIntoClosure(operation, callback, it->second); |
| 381 return net::ERR_IO_PENDING; |
| 382 } |
| 383 scoped_refptr<SimpleEntryImpl> simple_entry = |
| 384 CreateOrFindActiveEntry(entry_hash, key); |
| 385 return simple_entry->DoomEntry(callback); |
| 312 } | 386 } |
| 313 | 387 |
| 314 int SimpleBackendImpl::DoomAllEntries(const CompletionCallback& callback) { | 388 int SimpleBackendImpl::DoomAllEntries(const CompletionCallback& callback) { |
| 315 return DoomEntriesBetween(Time(), Time(), callback); | 389 return DoomEntriesBetween(Time(), Time(), callback); |
| 316 } | 390 } |
| 317 | 391 |
| 318 void SimpleBackendImpl::IndexReadyForDoom(Time initial_time, | 392 void SimpleBackendImpl::IndexReadyForDoom(Time initial_time, |
| 319 Time end_time, | 393 Time end_time, |
| 320 const CompletionCallback& callback, | 394 const CompletionCallback& callback, |
| 321 int result) { | 395 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 | 496 // TODO(pasko): Move PreferedCacheSize() to cache_util.h. Also fix the |
| 423 // spelling. | 497 // spelling. |
| 424 result.max_size = disk_cache::PreferedCacheSize(available); | 498 result.max_size = disk_cache::PreferedCacheSize(available); |
| 425 } | 499 } |
| 426 DCHECK(result.max_size); | 500 DCHECK(result.max_size); |
| 427 } | 501 } |
| 428 return result; | 502 return result; |
| 429 } | 503 } |
| 430 | 504 |
| 431 scoped_refptr<SimpleEntryImpl> SimpleBackendImpl::CreateOrFindActiveEntry( | 505 scoped_refptr<SimpleEntryImpl> SimpleBackendImpl::CreateOrFindActiveEntry( |
| 506 const uint64 entry_hash, |
| 432 const std::string& key) { | 507 const std::string& key) { |
| 433 const uint64 entry_hash = simple_util::GetEntryHashKey(key); | |
| 434 | |
| 435 std::pair<EntryMap::iterator, bool> insert_result = | 508 std::pair<EntryMap::iterator, bool> insert_result = |
| 436 active_entries_.insert(std::make_pair(entry_hash, | 509 active_entries_.insert(std::make_pair(entry_hash, |
| 437 base::WeakPtr<SimpleEntryImpl>())); | 510 base::WeakPtr<SimpleEntryImpl>())); |
| 438 EntryMap::iterator& it = insert_result.first; | 511 EntryMap::iterator& it = insert_result.first; |
| 439 if (insert_result.second) | 512 if (insert_result.second) |
| 440 DCHECK(!it->second.get()); | 513 DCHECK(!it->second.get()); |
| 441 if (!it->second.get()) { | 514 if (!it->second.get()) { |
| 442 SimpleEntryImpl* entry = new SimpleEntryImpl( | 515 SimpleEntryImpl* entry = new SimpleEntryImpl( |
| 443 cache_type_, path_, entry_hash, entry_operations_mode_, this, net_log_); | 516 cache_type_, path_, entry_hash, entry_operations_mode_, this, net_log_); |
| 444 entry->SetKey(key); | 517 entry->SetKey(key); |
| 445 it->second = entry->AsWeakPtr(); | 518 it->second = entry->AsWeakPtr(); |
| 446 } | 519 } |
| 447 DCHECK(it->second.get()); | 520 DCHECK(it->second.get()); |
| 448 // It's possible, but unlikely, that we have an entry hash collision with a | 521 // It's possible, but unlikely, that we have an entry hash collision with a |
| 449 // currently active entry. | 522 // currently active entry. |
| 450 if (key != it->second->key()) { | 523 if (key != it->second->key()) { |
| 451 it->second->Doom(); | 524 it->second->Doom(); |
| 452 DCHECK_EQ(0U, active_entries_.count(entry_hash)); | 525 DCHECK_EQ(0U, active_entries_.count(entry_hash)); |
| 453 return CreateOrFindActiveEntry(key); | 526 return CreateOrFindActiveEntry(entry_hash, key); |
| 454 } | 527 } |
| 455 return make_scoped_refptr(it->second.get()); | 528 return make_scoped_refptr(it->second.get()); |
| 456 } | 529 } |
| 457 | 530 |
| 458 int SimpleBackendImpl::OpenEntryFromHash(uint64 hash, | 531 int SimpleBackendImpl::OpenEntryFromHash(uint64 hash, |
| 459 Entry** entry, | 532 Entry** entry, |
| 460 const CompletionCallback& callback) { | 533 const CompletionCallback& callback) { |
| 461 EntryMap::iterator has_active = active_entries_.find(hash); | 534 EntryMap::iterator has_active = active_entries_.find(hash); |
| 462 if (has_active != active_entries_.end()) | 535 if (has_active != active_entries_.end()) |
| 463 return OpenEntry(has_active->second->key(), entry, callback); | 536 return OpenEntry(has_active->second->key(), entry, callback); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 } | 647 } |
| 575 callback.Run(error_code); | 648 callback.Run(error_code); |
| 576 } | 649 } |
| 577 | 650 |
| 578 void SimpleBackendImpl::FlushWorkerPoolForTesting() { | 651 void SimpleBackendImpl::FlushWorkerPoolForTesting() { |
| 579 if (g_sequenced_worker_pool) | 652 if (g_sequenced_worker_pool) |
| 580 g_sequenced_worker_pool->FlushForTesting(); | 653 g_sequenced_worker_pool->FlushForTesting(); |
| 581 } | 654 } |
| 582 | 655 |
| 583 } // namespace disk_cache | 656 } // namespace disk_cache |
| OLD | NEW |