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