Chromium Code Reviews| 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 15 matching lines...) Expand all Loading... | |
| 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 Loading... | |
| 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 base::WeakPtr<disk_cache::SimpleBackendImpl>& backend_weak_ptr, | |
| 203 const Callback<int(const net::CompletionCallback&)>& to_chain_operation, | |
| 204 const net::CompletionCallback& operation_callback, | |
| 205 const Closure& closure) { | |
| 206 if (backend_weak_ptr) { | |
|
Philippe
2013/08/30 13:33:14
I might be wrong but I believe that we have the gu
gavinp
2013/08/30 18:03:10
I think you're right. Done.
| |
| 207 const int operation_result = to_chain_operation.Run(operation_callback); | |
| 208 if (operation_result != net::ERR_IO_PENDING) | |
| 209 operation_callback.Run(operation_result); | |
| 210 } | |
| 211 if (!closure.is_null()) | |
| 212 closure.Run(); | |
| 213 } | |
| 214 | |
| 215 // Returns a Closure that will first run |to_chain_operation|, returning its | |
| 216 // result to |operation_callback|, and finally run |closure| if it is not null. | |
| 217 // Note that the |to_chain_operation| has to keep a base::Unretained pointer to | |
| 218 // the backend, so we add |backend_weak_ptr| and explicitly check it before any | |
| 219 // operation dereferences the backend. | |
| 220 Closure ChainOperationIntoClosure( | |
| 221 const base::WeakPtr<disk_cache::SimpleBackendImpl>& backend_weak_ptr, | |
| 222 const Callback<int(const net::CompletionCallback&)>& to_chain_operation, | |
| 223 const net::CompletionCallback& operation_callback, | |
| 224 const Closure& closure) { | |
| 225 return base::Bind(&ChainOperationIntoClosureImpl, backend_weak_ptr, | |
| 226 to_chain_operation, operation_callback, closure); | |
| 227 } | |
| 228 | |
| 199 void RecordIndexLoad(base::TimeTicks constructed_since, int result) { | 229 void RecordIndexLoad(base::TimeTicks constructed_since, int result) { |
| 200 const base::TimeDelta creation_to_index = base::TimeTicks::Now() - | 230 const base::TimeDelta creation_to_index = base::TimeTicks::Now() - |
| 201 constructed_since; | 231 constructed_since; |
| 202 if (result == net::OK) | 232 if (result == net::OK) |
| 203 UMA_HISTOGRAM_TIMES("SimpleCache.CreationToIndex", creation_to_index); | 233 UMA_HISTOGRAM_TIMES("SimpleCache.CreationToIndex", creation_to_index); |
| 204 else | 234 else |
| 205 UMA_HISTOGRAM_TIMES("SimpleCache.CreationToIndexFail", creation_to_index); | 235 UMA_HISTOGRAM_TIMES("SimpleCache.CreationToIndexFail", creation_to_index); |
| 206 } | 236 } |
| 207 | 237 |
| 208 } // namespace | 238 } // namespace |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 259 } | 289 } |
| 260 | 290 |
| 261 int SimpleBackendImpl::GetMaxFileSize() const { | 291 int SimpleBackendImpl::GetMaxFileSize() const { |
| 262 return index_->max_size() / kMaxFileRatio; | 292 return index_->max_size() / kMaxFileRatio; |
| 263 } | 293 } |
| 264 | 294 |
| 265 void SimpleBackendImpl::OnDeactivated(const SimpleEntryImpl* entry) { | 295 void SimpleBackendImpl::OnDeactivated(const SimpleEntryImpl* entry) { |
| 266 active_entries_.erase(entry->entry_hash()); | 296 active_entries_.erase(entry->entry_hash()); |
| 267 } | 297 } |
| 268 | 298 |
| 299 void SimpleBackendImpl::OnDoomStart(const uint64 entry_hash) { | |
|
Philippe
2013/08/30 13:33:14
Nit: As much as I like const, this one (and the on
gavinp
2013/08/30 18:03:10
Done.
| |
| 300 DCHECK_EQ(0u, entries_pending_doom_.count(entry_hash)); | |
| 301 entries_pending_doom_.insert( | |
| 302 base::hash_map<uint64, Closure>::value_type(entry_hash, Closure())); | |
|
Philippe
2013/08/30 13:33:14
Nit: any reason not to use the shorter make_pair()
gavinp
2013/08/30 18:03:10
No, none. Done.
| |
| 303 } | |
| 304 | |
| 305 void SimpleBackendImpl::OnDoomComplete(const 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 | |
| 269 net::CacheType SimpleBackendImpl::GetCacheType() const { | 316 net::CacheType SimpleBackendImpl::GetCacheType() const { |
| 270 return net::DISK_CACHE; | 317 return net::DISK_CACHE; |
| 271 } | 318 } |
| 272 | 319 |
| 273 int32 SimpleBackendImpl::GetEntryCount() const { | 320 int32 SimpleBackendImpl::GetEntryCount() const { |
| 274 // TODO(pasko): Use directory file count when index is not ready. | 321 // TODO(pasko): Use directory file count when index is not ready. |
| 275 return index_->GetEntryCount(); | 322 return index_->GetEntryCount(); |
| 276 } | 323 } |
| 277 | 324 |
| 278 int SimpleBackendImpl::OpenEntry(const std::string& key, | 325 int SimpleBackendImpl::OpenEntry(const std::string& key, |
| 279 Entry** entry, | 326 Entry** entry, |
| 280 const CompletionCallback& callback) { | 327 const CompletionCallback& callback) { |
| 281 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 | |
| 331 it = entries_pending_doom_.find(entry_hash); | |
|
Philippe
2013/08/30 13:33:14
Nit: wouldn't it be more common to break after '='
gavinp
2013/08/30 18:03:10
Done.
| |
| 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(AsWeakPtr(), | |
| 337 operation, callback, it->second); | |
| 338 return net::ERR_IO_PENDING; | |
| 339 } | |
| 340 scoped_refptr<SimpleEntryImpl> | |
| 341 simple_entry = CreateOrFindActiveEntry(entry_hash, key); | |
| 282 CompletionCallback backend_callback = | 342 CompletionCallback backend_callback = |
| 283 base::Bind(&SimpleBackendImpl::OnEntryOpenedFromKey, | 343 base::Bind(&SimpleBackendImpl::OnEntryOpenedFromKey, |
| 284 AsWeakPtr(), | 344 AsWeakPtr(), |
| 285 key, | 345 key, |
| 286 entry, | 346 entry, |
| 287 simple_entry, | 347 simple_entry, |
| 288 callback); | 348 callback); |
| 289 return simple_entry->OpenEntry(entry, backend_callback); | 349 return simple_entry->OpenEntry(entry, backend_callback); |
| 290 } | 350 } |
| 291 | 351 |
| 292 int SimpleBackendImpl::CreateEntry(const std::string& key, | 352 int SimpleBackendImpl::CreateEntry(const std::string& key, |
| 293 Entry** entry, | 353 Entry** entry, |
| 294 const CompletionCallback& callback) { | 354 const CompletionCallback& callback) { |
| 295 DCHECK(key.size() > 0); | 355 DCHECK_GT(key.size(), 0u); |
| 296 scoped_refptr<SimpleEntryImpl> simple_entry = CreateOrFindActiveEntry(key); | 356 const uint64 entry_hash = simple_util::GetEntryHashKey(key); |
| 357 | |
| 358 base::hash_map<uint64, base::Closure>::iterator | |
| 359 it = entries_pending_doom_.find(entry_hash); | |
| 360 if (it != entries_pending_doom_.end()) { | |
| 361 Callback<int(const net::CompletionCallback&)> operation = | |
| 362 base::Bind(&SimpleBackendImpl::CreateEntry, | |
| 363 base::Unretained(this), key, entry); | |
| 364 it->second = ChainOperationIntoClosure(AsWeakPtr(), | |
| 365 operation, callback, it->second); | |
| 366 return net::ERR_IO_PENDING; | |
| 367 } | |
| 368 scoped_refptr<SimpleEntryImpl> | |
| 369 simple_entry = CreateOrFindActiveEntry(entry_hash, key); | |
| 297 return simple_entry->CreateEntry(entry, callback); | 370 return simple_entry->CreateEntry(entry, callback); |
| 298 } | 371 } |
| 299 | 372 |
| 300 int SimpleBackendImpl::DoomEntry(const std::string& key, | 373 int SimpleBackendImpl::DoomEntry(const std::string& key, |
| 301 const net::CompletionCallback& callback) { | 374 const net::CompletionCallback& callback) { |
| 302 scoped_refptr<SimpleEntryImpl> simple_entry = CreateOrFindActiveEntry(key); | 375 const uint64 entry_hash = simple_util::GetEntryHashKey(key); |
| 376 | |
| 377 base::hash_map<uint64, base::Closure>::iterator | |
| 378 it = entries_pending_doom_.find(entry_hash); | |
| 379 if (it != entries_pending_doom_.end()) { | |
| 380 Callback<int(const net::CompletionCallback&)> operation = | |
| 381 base::Bind(&SimpleBackendImpl::DoomEntry, base::Unretained(this), key); | |
| 382 it->second = ChainOperationIntoClosure(AsWeakPtr(), | |
| 383 operation, callback, it->second); | |
| 384 return net::ERR_IO_PENDING; | |
| 385 } | |
| 386 scoped_refptr<SimpleEntryImpl> | |
| 387 simple_entry = CreateOrFindActiveEntry(entry_hash, key); | |
| 303 return simple_entry->DoomEntry(callback); | 388 return simple_entry->DoomEntry(callback); |
| 304 } | 389 } |
| 305 | 390 |
| 306 int SimpleBackendImpl::DoomAllEntries(const CompletionCallback& callback) { | 391 int SimpleBackendImpl::DoomAllEntries(const CompletionCallback& callback) { |
| 307 return DoomEntriesBetween(Time(), Time(), callback); | 392 return DoomEntriesBetween(Time(), Time(), callback); |
| 308 } | 393 } |
| 309 | 394 |
| 310 void SimpleBackendImpl::IndexReadyForDoom(Time initial_time, | 395 void SimpleBackendImpl::IndexReadyForDoom(Time initial_time, |
| 311 Time end_time, | 396 Time end_time, |
| 312 const CompletionCallback& callback, | 397 const CompletionCallback& callback, |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 415 // TODO(pasko): Move PreferedCacheSize() to cache_util.h. Also fix the | 500 // TODO(pasko): Move PreferedCacheSize() to cache_util.h. Also fix the |
| 416 // spelling. | 501 // spelling. |
| 417 result.max_size = disk_cache::PreferedCacheSize(available); | 502 result.max_size = disk_cache::PreferedCacheSize(available); |
| 418 } | 503 } |
| 419 DCHECK(result.max_size); | 504 DCHECK(result.max_size); |
| 420 } | 505 } |
| 421 return result; | 506 return result; |
| 422 } | 507 } |
| 423 | 508 |
| 424 scoped_refptr<SimpleEntryImpl> SimpleBackendImpl::CreateOrFindActiveEntry( | 509 scoped_refptr<SimpleEntryImpl> SimpleBackendImpl::CreateOrFindActiveEntry( |
| 510 const uint64 entry_hash, | |
| 425 const std::string& key) { | 511 const std::string& key) { |
| 426 const uint64 entry_hash = simple_util::GetEntryHashKey(key); | |
| 427 | |
| 428 std::pair<EntryMap::iterator, bool> insert_result = | 512 std::pair<EntryMap::iterator, bool> insert_result = |
| 429 active_entries_.insert(std::make_pair(entry_hash, | 513 active_entries_.insert(std::make_pair(entry_hash, |
| 430 base::WeakPtr<SimpleEntryImpl>())); | 514 base::WeakPtr<SimpleEntryImpl>())); |
| 431 EntryMap::iterator& it = insert_result.first; | 515 EntryMap::iterator& it = insert_result.first; |
| 432 if (insert_result.second) | 516 if (insert_result.second) |
| 433 DCHECK(!it->second.get()); | 517 DCHECK(!it->second.get()); |
| 434 if (!it->second.get()) { | 518 if (!it->second.get()) { |
| 435 SimpleEntryImpl* entry = new SimpleEntryImpl( | 519 SimpleEntryImpl* entry = new SimpleEntryImpl( |
| 436 path_, entry_hash, entry_operations_mode_, this, net_log_); | 520 path_, entry_hash, entry_operations_mode_, this, net_log_); |
| 437 entry->SetKey(key); | 521 entry->SetKey(key); |
| 438 it->second = entry->AsWeakPtr(); | 522 it->second = entry->AsWeakPtr(); |
| 439 } | 523 } |
| 440 DCHECK(it->second.get()); | 524 DCHECK(it->second.get()); |
| 441 // It's possible, but unlikely, that we have an entry hash collision with a | 525 // It's possible, but unlikely, that we have an entry hash collision with a |
| 442 // currently active entry. | 526 // currently active entry. |
| 443 if (key != it->second->key()) { | 527 if (key != it->second->key()) { |
| 444 it->second->Doom(); | 528 it->second->Doom(); |
| 445 DCHECK_EQ(0U, active_entries_.count(entry_hash)); | 529 DCHECK_EQ(0U, active_entries_.count(entry_hash)); |
| 446 return CreateOrFindActiveEntry(key); | 530 return CreateOrFindActiveEntry(entry_hash, key); |
| 447 } | 531 } |
| 448 return make_scoped_refptr(it->second.get()); | 532 return make_scoped_refptr(it->second.get()); |
| 449 } | 533 } |
| 450 | 534 |
| 451 int SimpleBackendImpl::OpenEntryFromHash(uint64 hash, | 535 int SimpleBackendImpl::OpenEntryFromHash(uint64 hash, |
| 452 Entry** entry, | 536 Entry** entry, |
| 453 const CompletionCallback& callback) { | 537 const CompletionCallback& callback) { |
| 454 EntryMap::iterator has_active = active_entries_.find(hash); | 538 EntryMap::iterator has_active = active_entries_.find(hash); |
| 455 if (has_active != active_entries_.end()) | 539 if (has_active != active_entries_.end()) |
| 456 return OpenEntry(has_active->second->key(), entry, callback); | 540 return OpenEntry(has_active->second->key(), entry, callback); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 562 const CompletionCallback& callback, | 646 const CompletionCallback& callback, |
| 563 int error_code) { | 647 int error_code) { |
| 564 if (error_code == net::ERR_FAILED) { | 648 if (error_code == net::ERR_FAILED) { |
| 565 OpenNextEntry(iter, entry, callback); | 649 OpenNextEntry(iter, entry, callback); |
| 566 return; | 650 return; |
| 567 } | 651 } |
| 568 CallCompletionCallback(callback, error_code); | 652 CallCompletionCallback(callback, error_code); |
| 569 } | 653 } |
| 570 | 654 |
| 571 } // namespace disk_cache | 655 } // namespace disk_cache |
| OLD | NEW |