Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(949)

Side by Side Diff: net/disk_cache/simple/simple_entry_impl.cc

Issue 2874833005: SimpleCache: read small files all at once. (Closed)
Patch Set: Tweak histogram description based on feedback Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « net/disk_cache/simple/simple_entry_impl.h ('k') | net/disk_cache/simple/simple_synchronous_entry.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698