OLD | NEW |
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2009 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/entry_impl.h" | 5 #include "net/disk_cache/entry_impl.h" |
6 | 6 |
7 #include "base/histogram.h" | 7 #include "base/histogram.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "net/base/io_buffer.h" | 10 #include "net/base/io_buffer.h" |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 for (int index = 0; index < kNumStreams; index++) { | 103 for (int index = 0; index < kNumStreams; index++) { |
104 if (user_buffers_[index].get()) { | 104 if (user_buffers_[index].get()) { |
105 if (!(ret = Flush(index, entry_.Data()->data_size[index], false))) | 105 if (!(ret = Flush(index, entry_.Data()->data_size[index], false))) |
106 LOG(ERROR) << "Failed to save user data"; | 106 LOG(ERROR) << "Failed to save user data"; |
107 } else if (unreported_size_[index]) { | 107 } else if (unreported_size_[index]) { |
108 backend_->ModifyStorageSize( | 108 backend_->ModifyStorageSize( |
109 entry_.Data()->data_size[index] - unreported_size_[index], | 109 entry_.Data()->data_size[index] - unreported_size_[index], |
110 entry_.Data()->data_size[index]); | 110 entry_.Data()->data_size[index]); |
111 } | 111 } |
112 } | 112 } |
113 if (node_.HasData() && this == node_.Data()->pointer) { | |
114 // We have to do this after Flush because we may trigger a cache trim from | |
115 // there, and technically this entry should be "in use". | |
116 node_.Data()->pointer = NULL; | |
117 node_.set_modified(); | |
118 } | |
119 | 113 |
120 if (!ret) { | 114 if (!ret) { |
121 // There was a failure writing the actual data. Mark the entry as dirty. | 115 // There was a failure writing the actual data. Mark the entry as dirty. |
122 int current_id = backend_->GetCurrentEntryId(); | 116 int current_id = backend_->GetCurrentEntryId(); |
123 node_.Data()->dirty = current_id == 1 ? -1 : current_id - 1; | 117 node_.Data()->dirty = current_id == 1 ? -1 : current_id - 1; |
124 node_.Store(); | 118 node_.Store(); |
125 } else if (node_.HasData() && node_.Data()->dirty) { | 119 } else if (node_.HasData() && node_.Data()->dirty) { |
126 node_.Data()->dirty = 0; | 120 node_.Data()->dirty = 0; |
127 node_.Store(); | 121 node_.Store(); |
128 } | 122 } |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 Trace("Create entry In"); | 385 Trace("Create entry In"); |
392 EntryStore* entry_store = entry_.Data(); | 386 EntryStore* entry_store = entry_.Data(); |
393 RankingsNode* node = node_.Data(); | 387 RankingsNode* node = node_.Data(); |
394 memset(entry_store, 0, sizeof(EntryStore) * entry_.address().num_blocks()); | 388 memset(entry_store, 0, sizeof(EntryStore) * entry_.address().num_blocks()); |
395 memset(node, 0, sizeof(RankingsNode)); | 389 memset(node, 0, sizeof(RankingsNode)); |
396 if (!node_.LazyInit(backend_->File(node_address), node_address)) | 390 if (!node_.LazyInit(backend_->File(node_address), node_address)) |
397 return false; | 391 return false; |
398 | 392 |
399 entry_store->rankings_node = node_address.value(); | 393 entry_store->rankings_node = node_address.value(); |
400 node->contents = entry_.address().value(); | 394 node->contents = entry_.address().value(); |
401 node->pointer = this; | |
402 | 395 |
403 entry_store->hash = hash; | 396 entry_store->hash = hash; |
404 entry_store->creation_time = Time::Now().ToInternalValue(); | 397 entry_store->creation_time = Time::Now().ToInternalValue(); |
405 entry_store->key_len = static_cast<int32>(key.size()); | 398 entry_store->key_len = static_cast<int32>(key.size()); |
406 if (entry_store->key_len > kMaxInternalKeyLength) { | 399 if (entry_store->key_len > kMaxInternalKeyLength) { |
407 Addr address(0); | 400 Addr address(0); |
408 if (!CreateBlock(entry_store->key_len + 1, &address)) | 401 if (!CreateBlock(entry_store->key_len + 1, &address)) |
409 return false; | 402 return false; |
410 | 403 |
411 entry_store->long_key = address.value(); | 404 entry_store->long_key = address.value(); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 Addr address(entry_.Data()->rankings_node); | 501 Addr address(entry_.Data()->rankings_node); |
509 if (!node_.LazyInit(backend_->File(address), address)) | 502 if (!node_.LazyInit(backend_->File(address), address)) |
510 return false; | 503 return false; |
511 return node_.Load(); | 504 return node_.Load(); |
512 } | 505 } |
513 | 506 |
514 bool EntryImpl::Update() { | 507 bool EntryImpl::Update() { |
515 DCHECK(node_.HasData()); | 508 DCHECK(node_.HasData()); |
516 | 509 |
517 RankingsNode* rankings = node_.Data(); | 510 RankingsNode* rankings = node_.Data(); |
518 if (rankings->pointer) { | 511 if (!rankings->dirty) { |
519 // Nothing to do here, the entry was in memory. | |
520 DCHECK(rankings->pointer == this); | |
521 } else { | |
522 rankings->dirty = backend_->GetCurrentEntryId(); | 512 rankings->dirty = backend_->GetCurrentEntryId(); |
523 rankings->pointer = this; | |
524 if (!node_.Store()) | 513 if (!node_.Store()) |
525 return false; | 514 return false; |
526 } | 515 } |
527 return true; | 516 return true; |
528 } | 517 } |
529 | 518 |
530 bool EntryImpl::IsDirty(int32 current_id) { | 519 bool EntryImpl::IsDirty(int32 current_id) { |
531 DCHECK(node_.HasData()); | 520 DCHECK(node_.HasData()); |
532 // We are checking if the entry is valid or not. If there is a pointer here, | 521 // We are checking if the entry is valid or not. If there is a pointer here, |
533 // we should not be checking the entry. | 522 // we should not be checking the entry. |
534 if (node_.Data()->pointer) | 523 if (node_.Data()->dummy) |
535 return true; | 524 return true; |
536 | 525 |
537 return node_.Data()->dirty && current_id != node_.Data()->dirty; | 526 return node_.Data()->dirty && current_id != node_.Data()->dirty; |
538 } | 527 } |
539 | 528 |
540 void EntryImpl::ClearDirtyFlag() { | 529 void EntryImpl::ClearDirtyFlag() { |
541 node_.Data()->dirty = 0; | 530 node_.Data()->dirty = 0; |
542 } | 531 } |
543 | 532 |
544 void EntryImpl::SetPointerForInvalidEntry(int32 new_id) { | 533 void EntryImpl::SetPointerForInvalidEntry(int32 new_id) { |
545 node_.Data()->dirty = new_id; | 534 node_.Data()->dirty = new_id; |
546 node_.Data()->pointer = this; | 535 node_.Data()->dummy = 0; |
547 node_.Store(); | 536 node_.Store(); |
548 } | 537 } |
549 | 538 |
550 bool EntryImpl::SanityCheck() { | 539 bool EntryImpl::SanityCheck() { |
551 if (!entry_.Data()->rankings_node || !entry_.Data()->key_len) | 540 if (!entry_.Data()->rankings_node || !entry_.Data()->key_len) |
552 return false; | 541 return false; |
553 | 542 |
554 Addr rankings_addr(entry_.Data()->rankings_node); | 543 Addr rankings_addr(entry_.Data()->rankings_node); |
555 if (!rankings_addr.is_initialized() || rankings_addr.is_separate_file() || | 544 if (!rankings_addr.is_initialized() || rankings_addr.is_separate_file() || |
556 rankings_addr.file_type() != RANKINGS) | 545 rankings_addr.file_type() != RANKINGS) |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
885 break; | 874 break; |
886 case kSparseWrite: | 875 case kSparseWrite: |
887 CACHE_UMA(AGE_MS, "SparseWriteTime", 0, start); | 876 CACHE_UMA(AGE_MS, "SparseWriteTime", 0, start); |
888 break; | 877 break; |
889 default: | 878 default: |
890 NOTREACHED(); | 879 NOTREACHED(); |
891 } | 880 } |
892 } | 881 } |
893 | 882 |
894 void EntryImpl::Log(const char* msg) { | 883 void EntryImpl::Log(const char* msg) { |
895 void* pointer = NULL; | |
896 int dirty = 0; | 884 int dirty = 0; |
897 if (node_.HasData()) { | 885 if (node_.HasData()) { |
898 pointer = node_.Data()->pointer; | |
899 dirty = node_.Data()->dirty; | 886 dirty = node_.Data()->dirty; |
900 } | 887 } |
901 | 888 |
902 Trace("%s 0x%p 0x%x 0x%x", msg, reinterpret_cast<void*>(this), | 889 Trace("%s 0x%p 0x%x 0x%x", msg, reinterpret_cast<void*>(this), |
903 entry_.address().value(), node_.address().value()); | 890 entry_.address().value(), node_.address().value()); |
904 | 891 |
905 Trace(" data: 0x%x 0x%x 0x%x", entry_.Data()->data_addr[0], | 892 Trace(" data: 0x%x 0x%x 0x%x", entry_.Data()->data_addr[0], |
906 entry_.Data()->data_addr[1], entry_.Data()->long_key); | 893 entry_.Data()->data_addr[1], entry_.Data()->long_key); |
907 | 894 |
908 Trace(" doomed: %d 0x%p 0x%x", doomed_, pointer, dirty); | 895 Trace(" doomed: %d 0x%x", doomed_, dirty); |
909 } | 896 } |
910 | 897 |
911 } // namespace disk_cache | 898 } // namespace disk_cache |
OLD | NEW |