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_entry_impl.h" | 5 #include "net/disk_cache/simple/simple_entry_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cstring> | 8 #include <cstring> |
9 #include <limits> | 9 #include <limits> |
10 #include <utility> | 10 #include <utility> |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 const uint64_t entry_hash, | 167 const uint64_t entry_hash, |
168 OperationsMode operations_mode, | 168 OperationsMode operations_mode, |
169 SimpleBackendImpl* backend, | 169 SimpleBackendImpl* backend, |
170 net::NetLog* net_log) | 170 net::NetLog* net_log) |
171 : backend_(backend->AsWeakPtr()), | 171 : backend_(backend->AsWeakPtr()), |
172 cache_type_(cache_type), | 172 cache_type_(cache_type), |
173 worker_pool_(backend->worker_pool()), | 173 worker_pool_(backend->worker_pool()), |
174 path_(path), | 174 path_(path), |
175 entry_hash_(entry_hash), | 175 entry_hash_(entry_hash), |
176 use_optimistic_operations_(operations_mode == OPTIMISTIC_OPERATIONS), | 176 use_optimistic_operations_(operations_mode == OPTIMISTIC_OPERATIONS), |
| 177 first_stream1_read_(true), |
177 last_used_(Time::Now()), | 178 last_used_(Time::Now()), |
178 last_modified_(last_used_), | 179 last_modified_(last_used_), |
179 sparse_data_size_(0), | 180 sparse_data_size_(0), |
180 open_count_(0), | 181 open_count_(0), |
181 doomed_(false), | 182 doomed_(false), |
182 state_(STATE_UNINITIALIZED), | 183 state_(STATE_UNINITIALIZED), |
183 synchronous_entry_(NULL), | 184 synchronous_entry_(NULL), |
184 net_log_( | 185 net_log_( |
185 net::NetLogWithSource::Make(net_log, | 186 net::NetLogWithSource::Make(net_log, |
186 net::NetLogSourceType::DISK_CACHE_ENTRY)), | 187 net::NetLogSourceType::DISK_CACHE_ENTRY)), |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 // I/O. Therefore, CancelSparseIO and ReadyForSparseIO succeed instantly. | 539 // I/O. Therefore, CancelSparseIO and ReadyForSparseIO succeed instantly. |
539 return net::OK; | 540 return net::OK; |
540 } | 541 } |
541 | 542 |
542 size_t SimpleEntryImpl::EstimateMemoryUsage() const { | 543 size_t SimpleEntryImpl::EstimateMemoryUsage() const { |
543 // TODO(xunjieli): crbug.com/669108. It'd be nice to have the rest of |entry| | 544 // TODO(xunjieli): crbug.com/669108. It'd be nice to have the rest of |entry| |
544 // measured, but the ownership of SimpleSynchronousEntry isn't straightforward | 545 // measured, but the ownership of SimpleSynchronousEntry isn't straightforward |
545 return sizeof(SimpleSynchronousEntry) + | 546 return sizeof(SimpleSynchronousEntry) + |
546 base::trace_event::EstimateMemoryUsage(pending_operations_) + | 547 base::trace_event::EstimateMemoryUsage(pending_operations_) + |
547 base::trace_event::EstimateMemoryUsage(executing_operation_) + | 548 base::trace_event::EstimateMemoryUsage(executing_operation_) + |
548 (stream_0_data_ ? stream_0_data_->capacity() : 0); | 549 (stream_0_data_ ? stream_0_data_->capacity() : 0) + |
| 550 (stream_1_prefetch_data_ ? stream_1_prefetch_data_->capacity() : 0); |
549 } | 551 } |
550 | 552 |
551 SimpleEntryImpl::~SimpleEntryImpl() { | 553 SimpleEntryImpl::~SimpleEntryImpl() { |
552 DCHECK(io_thread_checker_.CalledOnValidThread()); | 554 DCHECK(io_thread_checker_.CalledOnValidThread()); |
553 DCHECK_EQ(0U, pending_operations_.size()); | 555 DCHECK_EQ(0U, pending_operations_.size()); |
554 DCHECK(state_ == STATE_UNINITIALIZED || state_ == STATE_FAILURE); | 556 DCHECK(state_ == STATE_UNINITIALIZED || state_ == STATE_FAILURE); |
555 DCHECK(!synchronous_entry_); | 557 DCHECK(!synchronous_entry_); |
556 net_log_.EndEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY); | 558 net_log_.EndEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY); |
557 } | 559 } |
558 | 560 |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
839 if (!callback.is_null()) | 841 if (!callback.is_null()) |
840 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | 842 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
841 base::Bind(callback, 0)); | 843 base::Bind(callback, 0)); |
842 return; | 844 return; |
843 } | 845 } |
844 | 846 |
845 buf_len = std::min(buf_len, GetDataSize(stream_index) - offset); | 847 buf_len = std::min(buf_len, GetDataSize(stream_index) - offset); |
846 | 848 |
847 // Since stream 0 data is kept in memory, it is read immediately. | 849 // Since stream 0 data is kept in memory, it is read immediately. |
848 if (stream_index == 0) { | 850 if (stream_index == 0) { |
849 int ret_value = ReadStream0Data(buf, offset, buf_len); | 851 ReadInMemoryStreamData(stream_0_data_.get(), offset, buf_len, buf, |
850 if (!callback.is_null()) { | 852 callback); |
851 base::ThreadTaskRunnerHandle::Get()->PostTask( | 853 return; |
852 FROM_HERE, base::Bind(callback, ret_value)); | 854 } |
| 855 |
| 856 // Sometimes we can read in-ram prefetched stream 1 data immediately, too. |
| 857 if (stream_index == 1) { |
| 858 if (first_stream1_read_) { |
| 859 SIMPLE_CACHE_UMA(BOOLEAN, "ReadStream1FromPrefetched", cache_type_, |
| 860 stream_1_prefetch_data_ != nullptr); |
853 } | 861 } |
854 return; | 862 first_stream1_read_ = false; |
| 863 |
| 864 if (stream_1_prefetch_data_) { |
| 865 ReadInMemoryStreamData(stream_1_prefetch_data_.get(), offset, buf_len, |
| 866 buf, callback); |
| 867 return; |
| 868 } |
855 } | 869 } |
856 | 870 |
857 state_ = STATE_IO_PENDING; | 871 state_ = STATE_IO_PENDING; |
858 if (!doomed_ && backend_.get()) | 872 if (!doomed_ && backend_.get()) |
859 backend_->index()->UseIfExists(entry_hash_); | 873 backend_->index()->UseIfExists(entry_hash_); |
860 | 874 |
861 // Figure out if we should be computing the checksum for this read, | 875 // Figure out if we should be computing the checksum for this read, |
862 // and whether we should be verifying it, too. | 876 // and whether we should be verifying it, too. |
863 std::unique_ptr<SimpleSynchronousEntry::CRCRequest> crc_request; | 877 std::unique_ptr<SimpleSynchronousEntry::CRCRequest> crc_request; |
864 if (crc32s_end_offset_[stream_index] == offset) { | 878 if (crc32s_end_offset_[stream_index] == offset) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
938 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, | 952 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
939 base::Bind(callback, 0)); | 953 base::Bind(callback, 0)); |
940 } | 954 } |
941 return; | 955 return; |
942 } | 956 } |
943 } | 957 } |
944 state_ = STATE_IO_PENDING; | 958 state_ = STATE_IO_PENDING; |
945 if (!doomed_ && backend_.get()) | 959 if (!doomed_ && backend_.get()) |
946 backend_->index()->UseIfExists(entry_hash_); | 960 backend_->index()->UseIfExists(entry_hash_); |
947 | 961 |
| 962 // Any stream 1 write invalidates the prefetched data. |
| 963 if (stream_index == 1) |
| 964 stream_1_prefetch_data_ = nullptr; |
| 965 |
948 AdvanceCrc(buf, offset, buf_len, stream_index); | 966 AdvanceCrc(buf, offset, buf_len, stream_index); |
949 | 967 |
950 // |entry_stat| needs to be initialized before modifying |data_size_|. | 968 // |entry_stat| needs to be initialized before modifying |data_size_|. |
951 std::unique_ptr<SimpleEntryStat> entry_stat(new SimpleEntryStat( | 969 std::unique_ptr<SimpleEntryStat> entry_stat(new SimpleEntryStat( |
952 last_used_, last_modified_, data_size_, sparse_data_size_)); | 970 last_used_, last_modified_, data_size_, sparse_data_size_)); |
953 if (truncate) { | 971 if (truncate) { |
954 data_size_[stream_index] = offset + buf_len; | 972 data_size_[stream_index] = offset + buf_len; |
955 } else { | 973 } else { |
956 data_size_[stream_index] = std::max(offset + buf_len, | 974 data_size_[stream_index] = std::max(offset + buf_len, |
957 GetDataSize(stream_index)); | 975 GetDataSize(stream_index)); |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1142 | 1160 |
1143 state_ = STATE_READY; | 1161 state_ = STATE_READY; |
1144 synchronous_entry_ = in_results->sync_entry; | 1162 synchronous_entry_ = in_results->sync_entry; |
1145 if (in_results->stream_0_data.get()) { | 1163 if (in_results->stream_0_data.get()) { |
1146 stream_0_data_ = in_results->stream_0_data; | 1164 stream_0_data_ = in_results->stream_0_data; |
1147 // The crc was read in SimpleSynchronousEntry. | 1165 // The crc was read in SimpleSynchronousEntry. |
1148 crc_check_state_[0] = CRC_CHECK_DONE; | 1166 crc_check_state_[0] = CRC_CHECK_DONE; |
1149 crc32s_[0] = in_results->stream_0_crc32; | 1167 crc32s_[0] = in_results->stream_0_crc32; |
1150 crc32s_end_offset_[0] = in_results->entry_stat.data_size(0); | 1168 crc32s_end_offset_[0] = in_results->entry_stat.data_size(0); |
1151 } | 1169 } |
| 1170 |
| 1171 if (in_results->stream_1_data.get()) { |
| 1172 stream_1_prefetch_data_ = in_results->stream_1_data; |
| 1173 // The crc was read in SimpleSynchronousEntry. |
| 1174 crc_check_state_[1] = CRC_CHECK_DONE; |
| 1175 crc32s_[1] = in_results->stream_1_crc32; |
| 1176 crc32s_end_offset_[1] = in_results->entry_stat.data_size(1); |
| 1177 } |
| 1178 |
1152 // If this entry was opened by hash, key_ could still be empty. If so, update | 1179 // If this entry was opened by hash, key_ could still be empty. If so, update |
1153 // it with the key read from the synchronous entry. | 1180 // it with the key read from the synchronous entry. |
1154 if (key_.empty()) { | 1181 if (key_.empty()) { |
1155 SetKey(synchronous_entry_->key()); | 1182 SetKey(synchronous_entry_->key()); |
1156 } else { | 1183 } else { |
1157 // This should only be triggered when creating an entry. In the open case | 1184 // This should only be triggered when creating an entry. In the open case |
1158 // the key is either copied from the arguments to open, or checked | 1185 // the key is either copied from the arguments to open, or checked |
1159 // in the synchronous entry. | 1186 // in the synchronous entry. |
1160 DCHECK_EQ(key_, synchronous_entry_->key()); | 1187 DCHECK_EQ(key_, synchronous_entry_->key()); |
1161 } | 1188 } |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1437 } else { | 1464 } else { |
1438 type = conflicting ? WRITE_FOLLOWS_CONFLICTING_WRITE | 1465 type = conflicting ? WRITE_FOLLOWS_CONFLICTING_WRITE |
1439 : WRITE_FOLLOWS_NON_CONFLICTING_WRITE; | 1466 : WRITE_FOLLOWS_NON_CONFLICTING_WRITE; |
1440 } | 1467 } |
1441 } | 1468 } |
1442 SIMPLE_CACHE_UMA(ENUMERATION, | 1469 SIMPLE_CACHE_UMA(ENUMERATION, |
1443 "WriteDependencyType", cache_type_, | 1470 "WriteDependencyType", cache_type_, |
1444 type, WRITE_DEPENDENCY_TYPE_MAX); | 1471 type, WRITE_DEPENDENCY_TYPE_MAX); |
1445 } | 1472 } |
1446 | 1473 |
1447 int SimpleEntryImpl::ReadStream0Data(net::IOBuffer* buf, | 1474 void SimpleEntryImpl::ReadInMemoryStreamData( |
1448 int offset, | 1475 net::GrowableIOBuffer* in_buf, |
1449 int buf_len) { | 1476 int offset, |
| 1477 int buf_len, |
| 1478 net::IOBuffer* out_buf, |
| 1479 const CompletionCallback& callback) { |
| 1480 int rv; |
1450 if (buf_len < 0) { | 1481 if (buf_len < 0) { |
1451 RecordReadResult(cache_type_, READ_RESULT_SYNC_READ_FAILURE); | 1482 RecordReadResult(cache_type_, READ_RESULT_SYNC_READ_FAILURE); |
1452 return 0; | 1483 rv = 0; |
| 1484 } else { |
| 1485 memcpy(out_buf->data(), in_buf->data() + offset, buf_len); |
| 1486 UpdateDataFromEntryStat(SimpleEntryStat(base::Time::Now(), last_modified_, |
| 1487 data_size_, sparse_data_size_)); |
| 1488 RecordReadResult(cache_type_, READ_RESULT_SUCCESS); |
| 1489 rv = buf_len; |
1453 } | 1490 } |
1454 memcpy(buf->data(), stream_0_data_->data() + offset, buf_len); | 1491 if (!callback.is_null()) { |
1455 UpdateDataFromEntryStat( | 1492 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
1456 SimpleEntryStat(base::Time::Now(), last_modified_, data_size_, | 1493 base::Bind(callback, rv)); |
1457 sparse_data_size_)); | 1494 } |
1458 RecordReadResult(cache_type_, READ_RESULT_SUCCESS); | |
1459 return buf_len; | |
1460 } | 1495 } |
1461 | 1496 |
1462 int SimpleEntryImpl::SetStream0Data(net::IOBuffer* buf, | 1497 int SimpleEntryImpl::SetStream0Data(net::IOBuffer* buf, |
1463 int offset, | 1498 int offset, |
1464 int buf_len, | 1499 int buf_len, |
1465 bool truncate) { | 1500 bool truncate) { |
1466 // Currently, stream 0 is only used for HTTP headers, and always writes them | 1501 // Currently, stream 0 is only used for HTTP headers, and always writes them |
1467 // with a single, truncating write. Detect these writes and record the size | 1502 // with a single, truncating write. Detect these writes and record the size |
1468 // changes of the headers. Also, support writes to stream 0 that have | 1503 // changes of the headers. Also, support writes to stream 0 that have |
1469 // different access patterns, as required by the API contract. | 1504 // different access patterns, as required by the API contract. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1516 } | 1551 } |
1517 crc32s_end_offset_[stream_index] = offset + length; | 1552 crc32s_end_offset_[stream_index] = offset + length; |
1518 } else if (offset < crc32s_end_offset_[stream_index]) { | 1553 } else if (offset < crc32s_end_offset_[stream_index]) { |
1519 // If a range for which the crc32 was already computed is rewritten, the | 1554 // If a range for which the crc32 was already computed is rewritten, the |
1520 // computation of the crc32 need to start from 0 again. | 1555 // computation of the crc32 need to start from 0 again. |
1521 crc32s_end_offset_[stream_index] = 0; | 1556 crc32s_end_offset_[stream_index] = 0; |
1522 } | 1557 } |
1523 } | 1558 } |
1524 | 1559 |
1525 } // namespace disk_cache | 1560 } // namespace disk_cache |
OLD | NEW |