OLD | NEW |
1 // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2010 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/backend_impl.h" | 5 #include "net/disk_cache/backend_impl.h" |
6 | 6 |
7 #include "base/field_trial.h" | 7 #include "base/field_trial.h" |
8 #include "base/file_path.h" | 8 #include "base/file_path.h" |
9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
10 #include "base/histogram.h" | 10 #include "base/histogram.h" |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 data_->header.lru.sizes[Rankings::DELETED]; | 359 data_->header.lru.sizes[Rankings::DELETED]; |
360 | 360 |
361 if (not_deleted < 0) { | 361 if (not_deleted < 0) { |
362 NOTREACHED(); | 362 NOTREACHED(); |
363 not_deleted = 0; | 363 not_deleted = 0; |
364 } | 364 } |
365 | 365 |
366 return not_deleted; | 366 return not_deleted; |
367 } | 367 } |
368 | 368 |
369 bool BackendImpl::OpenEntry(const std::string& key, Entry** entry) { | 369 EntryImpl* BackendImpl::OpenEntryImpl(const std::string& key) { |
370 if (disabled_) | 370 if (disabled_) |
371 return false; | 371 return NULL; |
372 | 372 |
373 TimeTicks start = TimeTicks::Now(); | 373 TimeTicks start = TimeTicks::Now(); |
374 uint32 hash = Hash(key); | 374 uint32 hash = Hash(key); |
375 | 375 |
376 EntryImpl* cache_entry = MatchEntry(key, hash, false); | 376 EntryImpl* cache_entry = MatchEntry(key, hash, false); |
377 if (!cache_entry) { | 377 if (!cache_entry) { |
378 stats_.OnEvent(Stats::OPEN_MISS); | 378 stats_.OnEvent(Stats::OPEN_MISS); |
379 return false; | 379 return NULL; |
380 } | 380 } |
381 | 381 |
382 if (ENTRY_NORMAL != cache_entry->entry()->Data()->state) { | 382 if (ENTRY_NORMAL != cache_entry->entry()->Data()->state) { |
383 // The entry was already evicted. | 383 // The entry was already evicted. |
384 cache_entry->Release(); | 384 cache_entry->Release(); |
385 stats_.OnEvent(Stats::OPEN_MISS); | 385 stats_.OnEvent(Stats::OPEN_MISS); |
386 return false; | 386 return NULL; |
387 } | 387 } |
388 | 388 |
389 eviction_.OnOpenEntry(cache_entry); | 389 eviction_.OnOpenEntry(cache_entry); |
390 DCHECK(entry); | |
391 *entry = cache_entry; | |
392 | 390 |
393 CACHE_UMA(AGE_MS, "OpenTime", GetSizeGroup(), start); | 391 CACHE_UMA(AGE_MS, "OpenTime", GetSizeGroup(), start); |
394 stats_.OnEvent(Stats::OPEN_HIT); | 392 stats_.OnEvent(Stats::OPEN_HIT); |
395 return true; | 393 return cache_entry; |
| 394 } |
| 395 |
| 396 bool BackendImpl::OpenEntry(const std::string& key, Entry** entry) { |
| 397 DCHECK(entry); |
| 398 *entry = OpenEntryImpl(key); |
| 399 return (*entry) ? true : false; |
396 } | 400 } |
397 | 401 |
398 int BackendImpl::OpenEntry(const std::string& key, Entry** entry, | 402 int BackendImpl::OpenEntry(const std::string& key, Entry** entry, |
399 CompletionCallback* callback) { | 403 CompletionCallback* callback) { |
400 if (OpenEntry(key, entry)) | 404 if (OpenEntry(key, entry)) |
401 return net::OK; | 405 return net::OK; |
402 | 406 |
403 return net::ERR_FAILED; | 407 return net::ERR_FAILED; |
404 } | 408 } |
405 | 409 |
406 bool BackendImpl::CreateEntry(const std::string& key, Entry** entry) { | 410 EntryImpl* BackendImpl::CreateEntryImpl(const std::string& key) { |
407 if (disabled_ || key.empty()) | 411 if (disabled_ || key.empty()) |
408 return false; | 412 return NULL; |
409 | |
410 DCHECK(entry); | |
411 *entry = NULL; | |
412 | 413 |
413 TimeTicks start = TimeTicks::Now(); | 414 TimeTicks start = TimeTicks::Now(); |
414 uint32 hash = Hash(key); | 415 uint32 hash = Hash(key); |
415 | 416 |
416 scoped_refptr<EntryImpl> parent; | 417 scoped_refptr<EntryImpl> parent; |
417 Addr entry_address(data_->table[hash & mask_]); | 418 Addr entry_address(data_->table[hash & mask_]); |
418 if (entry_address.is_initialized()) { | 419 if (entry_address.is_initialized()) { |
419 // We have an entry already. It could be the one we are looking for, or just | 420 // We have an entry already. It could be the one we are looking for, or just |
420 // a hash conflict. | 421 // a hash conflict. |
421 EntryImpl* old_entry = MatchEntry(key, hash, false); | 422 EntryImpl* old_entry = MatchEntry(key, hash, false); |
422 if (old_entry) | 423 if (old_entry) |
423 return ResurrectEntry(old_entry, entry); | 424 return ResurrectEntry(old_entry); |
424 | 425 |
425 EntryImpl* parent_entry = MatchEntry(key, hash, true); | 426 EntryImpl* parent_entry = MatchEntry(key, hash, true); |
426 if (!parent_entry) { | 427 if (!parent_entry) { |
427 NOTREACHED(); | 428 NOTREACHED(); |
428 return false; | 429 return NULL; |
429 } | 430 } |
430 parent.swap(&parent_entry); | 431 parent.swap(&parent_entry); |
431 } | 432 } |
432 | 433 |
433 int num_blocks; | 434 int num_blocks; |
434 size_t key1_len = sizeof(EntryStore) - offsetof(EntryStore, key); | 435 size_t key1_len = sizeof(EntryStore) - offsetof(EntryStore, key); |
435 if (key.size() < key1_len || | 436 if (key.size() < key1_len || |
436 key.size() > static_cast<size_t>(kMaxInternalKeyLength)) | 437 key.size() > static_cast<size_t>(kMaxInternalKeyLength)) |
437 num_blocks = 1; | 438 num_blocks = 1; |
438 else | 439 else |
439 num_blocks = static_cast<int>((key.size() - key1_len) / 256 + 2); | 440 num_blocks = static_cast<int>((key.size() - key1_len) / 256 + 2); |
440 | 441 |
441 if (!block_files_.CreateBlock(BLOCK_256, num_blocks, &entry_address)) { | 442 if (!block_files_.CreateBlock(BLOCK_256, num_blocks, &entry_address)) { |
442 LOG(ERROR) << "Create entry failed " << key.c_str(); | 443 LOG(ERROR) << "Create entry failed " << key.c_str(); |
443 stats_.OnEvent(Stats::CREATE_ERROR); | 444 stats_.OnEvent(Stats::CREATE_ERROR); |
444 return false; | 445 return NULL; |
445 } | 446 } |
446 | 447 |
447 Addr node_address(0); | 448 Addr node_address(0); |
448 if (!block_files_.CreateBlock(RANKINGS, 1, &node_address)) { | 449 if (!block_files_.CreateBlock(RANKINGS, 1, &node_address)) { |
449 block_files_.DeleteBlock(entry_address, false); | 450 block_files_.DeleteBlock(entry_address, false); |
450 LOG(ERROR) << "Create entry failed " << key.c_str(); | 451 LOG(ERROR) << "Create entry failed " << key.c_str(); |
451 stats_.OnEvent(Stats::CREATE_ERROR); | 452 stats_.OnEvent(Stats::CREATE_ERROR); |
452 return false; | 453 return NULL; |
453 } | 454 } |
454 | 455 |
455 scoped_refptr<EntryImpl> cache_entry(new EntryImpl(this, entry_address)); | 456 scoped_refptr<EntryImpl> cache_entry(new EntryImpl(this, entry_address)); |
456 IncreaseNumRefs(); | 457 IncreaseNumRefs(); |
457 | 458 |
458 if (!cache_entry->CreateEntry(node_address, key, hash)) { | 459 if (!cache_entry->CreateEntry(node_address, key, hash)) { |
459 block_files_.DeleteBlock(entry_address, false); | 460 block_files_.DeleteBlock(entry_address, false); |
460 block_files_.DeleteBlock(node_address, false); | 461 block_files_.DeleteBlock(node_address, false); |
461 LOG(ERROR) << "Create entry failed " << key.c_str(); | 462 LOG(ERROR) << "Create entry failed " << key.c_str(); |
462 stats_.OnEvent(Stats::CREATE_ERROR); | 463 stats_.OnEvent(Stats::CREATE_ERROR); |
463 return false; | 464 return NULL; |
464 } | 465 } |
465 | 466 |
466 // We are not failing the operation; let's add this to the map. | 467 // We are not failing the operation; let's add this to the map. |
467 open_entries_[entry_address.value()] = cache_entry; | 468 open_entries_[entry_address.value()] = cache_entry; |
468 | 469 |
469 if (parent.get()) | 470 if (parent.get()) |
470 parent->SetNextAddress(entry_address); | 471 parent->SetNextAddress(entry_address); |
471 | 472 |
472 block_files_.GetFile(entry_address)->Store(cache_entry->entry()); | 473 block_files_.GetFile(entry_address)->Store(cache_entry->entry()); |
473 block_files_.GetFile(node_address)->Store(cache_entry->rankings()); | 474 block_files_.GetFile(node_address)->Store(cache_entry->rankings()); |
474 | 475 |
475 IncreaseNumEntries(); | 476 IncreaseNumEntries(); |
476 eviction_.OnCreateEntry(cache_entry); | 477 eviction_.OnCreateEntry(cache_entry); |
477 if (!parent.get()) | 478 if (!parent.get()) |
478 data_->table[hash & mask_] = entry_address.value(); | 479 data_->table[hash & mask_] = entry_address.value(); |
479 | 480 |
480 cache_entry.swap(reinterpret_cast<EntryImpl**>(entry)); | |
481 | |
482 CACHE_UMA(AGE_MS, "CreateTime", GetSizeGroup(), start); | 481 CACHE_UMA(AGE_MS, "CreateTime", GetSizeGroup(), start); |
483 stats_.OnEvent(Stats::CREATE_HIT); | 482 stats_.OnEvent(Stats::CREATE_HIT); |
484 Trace("create entry hit "); | 483 Trace("create entry hit "); |
485 return true; | 484 return cache_entry.release(); |
| 485 } |
| 486 |
| 487 bool BackendImpl::CreateEntry(const std::string& key, Entry** entry) { |
| 488 DCHECK(entry); |
| 489 *entry = CreateEntryImpl(key); |
| 490 return (*entry) ? true : false; |
486 } | 491 } |
487 | 492 |
488 int BackendImpl::CreateEntry(const std::string& key, Entry** entry, | 493 int BackendImpl::CreateEntry(const std::string& key, Entry** entry, |
489 CompletionCallback* callback) { | 494 CompletionCallback* callback) { |
490 if (CreateEntry(key, entry)) | 495 if (CreateEntry(key, entry)) |
491 return net::OK; | 496 return net::OK; |
492 | 497 |
493 return net::ERR_FAILED; | 498 return net::ERR_FAILED; |
494 } | 499 } |
495 | 500 |
(...skipping 919 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1415 | 1420 |
1416 // There is no need to store the entry to disk if we want to delete it. | 1421 // There is no need to store the entry to disk if we want to delete it. |
1417 if (!to_evict && !entry->Update()) { | 1422 if (!to_evict && !entry->Update()) { |
1418 entry->Release(); | 1423 entry->Release(); |
1419 return NULL; | 1424 return NULL; |
1420 } | 1425 } |
1421 | 1426 |
1422 return entry; | 1427 return entry; |
1423 } | 1428 } |
1424 | 1429 |
1425 bool BackendImpl::ResurrectEntry(EntryImpl* deleted_entry, Entry** entry) { | 1430 EntryImpl* BackendImpl::ResurrectEntry(EntryImpl* deleted_entry) { |
1426 if (ENTRY_NORMAL == deleted_entry->entry()->Data()->state) { | 1431 if (ENTRY_NORMAL == deleted_entry->entry()->Data()->state) { |
1427 deleted_entry->Release(); | 1432 deleted_entry->Release(); |
1428 stats_.OnEvent(Stats::CREATE_MISS); | 1433 stats_.OnEvent(Stats::CREATE_MISS); |
1429 Trace("create entry miss "); | 1434 Trace("create entry miss "); |
1430 return false; | 1435 return NULL; |
1431 } | 1436 } |
1432 | 1437 |
1433 // We are attempting to create an entry and found out that the entry was | 1438 // We are attempting to create an entry and found out that the entry was |
1434 // previously deleted. | 1439 // previously deleted. |
1435 | 1440 |
1436 eviction_.OnCreateEntry(deleted_entry); | 1441 eviction_.OnCreateEntry(deleted_entry); |
1437 *entry = deleted_entry; | |
1438 | 1442 |
1439 stats_.OnEvent(Stats::CREATE_HIT); | 1443 stats_.OnEvent(Stats::CREATE_HIT); |
1440 Trace("Resurrect entry hit "); | 1444 Trace("Resurrect entry hit "); |
1441 return true; | 1445 return deleted_entry; |
1442 } | 1446 } |
1443 | 1447 |
1444 void BackendImpl::DestroyInvalidEntry(EntryImpl* entry) { | 1448 void BackendImpl::DestroyInvalidEntry(EntryImpl* entry) { |
1445 LOG(WARNING) << "Destroying invalid entry."; | 1449 LOG(WARNING) << "Destroying invalid entry."; |
1446 Trace("Destroying invalid entry 0x%p", entry); | 1450 Trace("Destroying invalid entry 0x%p", entry); |
1447 | 1451 |
1448 entry->SetPointerForInvalidEntry(GetCurrentEntryId()); | 1452 entry->SetPointerForInvalidEntry(GetCurrentEntryId()); |
1449 | 1453 |
1450 eviction_.OnDoomEntry(entry); | 1454 eviction_.OnDoomEntry(entry); |
1451 entry->InternalDoom(); | 1455 entry->InternalDoom(); |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1705 | 1709 |
1706 return num_dirty; | 1710 return num_dirty; |
1707 } | 1711 } |
1708 | 1712 |
1709 bool BackendImpl::CheckEntry(EntryImpl* cache_entry) { | 1713 bool BackendImpl::CheckEntry(EntryImpl* cache_entry) { |
1710 RankingsNode* rankings = cache_entry->rankings()->Data(); | 1714 RankingsNode* rankings = cache_entry->rankings()->Data(); |
1711 return !rankings->dummy; | 1715 return !rankings->dummy; |
1712 } | 1716 } |
1713 | 1717 |
1714 } // namespace disk_cache | 1718 } // namespace disk_cache |
OLD | NEW |