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

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

Issue 2807433002: SimpleCache: synchronously reply on reads from idle if data is in memory.
Patch Set: Experimental: upload a bit of an alternative approach for discussion Created 3 years, 8 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
« no previous file with comments | « net/disk_cache/simple/simple_entry_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 buf_len < 0) { 369 buf_len < 0) {
370 if (net_log_.IsCapturing()) { 370 if (net_log_.IsCapturing()) {
371 net_log_.AddEvent( 371 net_log_.AddEvent(
372 net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_END, 372 net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_END,
373 CreateNetLogReadWriteCompleteCallback(net::ERR_INVALID_ARGUMENT)); 373 CreateNetLogReadWriteCompleteCallback(net::ERR_INVALID_ARGUMENT));
374 } 374 }
375 375
376 RecordReadResult(cache_type_, READ_RESULT_INVALID_ARGUMENT); 376 RecordReadResult(cache_type_, READ_RESULT_INVALID_ARGUMENT);
377 return net::ERR_INVALID_ARGUMENT; 377 return net::ERR_INVALID_ARGUMENT;
378 } 378 }
379 if (pending_operations_.empty() && (offset >= GetDataSize(stream_index) ||
380 offset < 0 || !buf_len)) {
381 if (net_log_.IsCapturing()) {
382 net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_END,
383 CreateNetLogReadWriteCompleteCallback(0));
384 }
385 379
386 RecordReadResult(cache_type_, READ_RESULT_NONBLOCK_EMPTY_RETURN); 380 bool alone_in_queue =
387 return 0; 381 pending_operations_.size() == 0 && state_ == STATE_READY;
382
383 if (alone_in_queue) {
384 return ReadDataInternal(true, stream_index, offset, buf, buf_len, callback);
388 } 385 }
389 386
390 // TODO(clamy): return immediatly when reading from stream 0.
391
392 // TODO(felipeg): Optimization: Add support for truly parallel read
393 // operations.
394 bool alone_in_queue =
395 pending_operations_.size() == 0 && state_ == STATE_READY;
396 pending_operations_.push(SimpleEntryOperation::ReadOperation( 387 pending_operations_.push(SimpleEntryOperation::ReadOperation(
397 this, stream_index, offset, buf_len, buf, callback, alone_in_queue)); 388 this, stream_index, offset, buf_len, buf, callback, alone_in_queue));
398 RunNextOperationIfNeeded(); 389 RunNextOperationIfNeeded();
399 return net::ERR_IO_PENDING; 390 return net::ERR_IO_PENDING;
400 } 391 }
401 392
402 int SimpleEntryImpl::WriteData(int stream_index, 393 int SimpleEntryImpl::WriteData(int stream_index,
403 int offset, 394 int offset,
404 net::IOBuffer* buf, 395 net::IOBuffer* buf,
405 int buf_len, 396 int buf_len,
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 case SimpleEntryOperation::TYPE_CREATE: 623 case SimpleEntryOperation::TYPE_CREATE:
633 CreateEntryInternal(operation->have_index(), 624 CreateEntryInternal(operation->have_index(),
634 operation->callback(), 625 operation->callback(),
635 operation->out_entry()); 626 operation->out_entry());
636 break; 627 break;
637 case SimpleEntryOperation::TYPE_CLOSE: 628 case SimpleEntryOperation::TYPE_CLOSE:
638 CloseInternal(); 629 CloseInternal();
639 break; 630 break;
640 case SimpleEntryOperation::TYPE_READ: 631 case SimpleEntryOperation::TYPE_READ:
641 RecordReadIsParallelizable(*operation); 632 RecordReadIsParallelizable(*operation);
642 ReadDataInternal(operation->index(), 633 ReadDataInternal(false, operation->index(), operation->offset(),
643 operation->offset(), 634 operation->buf(), operation->length(),
644 operation->buf(),
645 operation->length(),
646 operation->callback()); 635 operation->callback());
647 break; 636 break;
648 case SimpleEntryOperation::TYPE_WRITE: 637 case SimpleEntryOperation::TYPE_WRITE:
649 RecordWriteDependencyType(*operation); 638 RecordWriteDependencyType(*operation);
650 WriteDataInternal(operation->index(), 639 WriteDataInternal(operation->index(),
651 operation->offset(), 640 operation->offset(),
652 operation->buf(), 641 operation->buf(),
653 operation->length(), 642 operation->length(),
654 operation->callback(), 643 operation->callback(),
655 operation->truncate()); 644 operation->truncate());
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 SIMPLE_CACHE_UMA(ENUMERATION, 800 SIMPLE_CACHE_UMA(ENUMERATION,
812 "CheckCRCResult", cache_type_, 801 "CheckCRCResult", cache_type_,
813 crc_check_state_[i], CRC_CHECK_MAX); 802 crc_check_state_[i], CRC_CHECK_MAX);
814 } 803 }
815 } 804 }
816 } else { 805 } else {
817 CloseOperationComplete(); 806 CloseOperationComplete();
818 } 807 }
819 } 808 }
820 809
821 void SimpleEntryImpl::ReadDataInternal(int stream_index, 810 int SimpleEntryImpl::ReadDataInternal(bool try_sync,
822 int offset, 811 int stream_index,
823 net::IOBuffer* buf, 812 int offset,
824 int buf_len, 813 net::IOBuffer* buf,
825 const CompletionCallback& callback) { 814 int buf_len,
815 const CompletionCallback& callback) {
826 DCHECK(io_thread_checker_.CalledOnValidThread()); 816 DCHECK(io_thread_checker_.CalledOnValidThread());
827 ScopedOperationRunner operation_runner(this); 817 ScopedOperationRunner operation_runner(this);
828 818
829 if (net_log_.IsCapturing()) { 819 if (net_log_.IsCapturing()) {
830 net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_BEGIN, 820 net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_BEGIN,
831 CreateNetLogReadWriteDataCallback(stream_index, offset, 821 CreateNetLogReadWriteDataCallback(stream_index, offset,
832 buf_len, false)); 822 buf_len, false));
833 } 823 }
834 824
835 if (state_ == STATE_FAILURE || state_ == STATE_UNINITIALIZED) { 825 if (state_ == STATE_FAILURE || state_ == STATE_UNINITIALIZED) {
836 if (!callback.is_null()) { 826 if (!callback.is_null() && !try_sync) {
837 RecordReadResult(cache_type_, READ_RESULT_BAD_STATE); 827 RecordReadResult(cache_type_, READ_RESULT_BAD_STATE);
Maks Orlovich 2017/04/12 14:55:49 I should probably double-check the condition for t
pasko 2017/04/12 16:12:51 this won't appear on the benchmark, so why bother?
838 // Note that the API states that client-provided callbacks for entry-level 828 // Note that the API states that client-provided callbacks for entry-level
839 // (i.e. non-backend) operations (e.g. read, write) are invoked even if 829 // (i.e. non-backend) operations (e.g. read, write) are invoked even if
840 // the backend was already destroyed. 830 // the backend was already destroyed.
841 base::ThreadTaskRunnerHandle::Get()->PostTask( 831 base::ThreadTaskRunnerHandle::Get()->PostTask(
842 FROM_HERE, base::Bind(callback, net::ERR_FAILED)); 832 FROM_HERE, base::Bind(callback, net::ERR_FAILED));
843 } 833 }
844 if (net_log_.IsCapturing()) { 834 if (net_log_.IsCapturing()) {
845 net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_END, 835 net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_READ_END,
846 CreateNetLogReadWriteCompleteCallback(net::ERR_FAILED)); 836 CreateNetLogReadWriteCompleteCallback(net::ERR_FAILED));
847 } 837 }
848 return; 838 return net::ERR_FAILED;
849 } 839 }
850 DCHECK_EQ(STATE_READY, state_); 840 DCHECK_EQ(STATE_READY, state_);
851 if (offset >= GetDataSize(stream_index) || offset < 0 || !buf_len) { 841 if (offset >= GetDataSize(stream_index) || offset < 0 || !buf_len) {
852 RecordReadResult(cache_type_, READ_RESULT_FAST_EMPTY_RETURN); 842 RecordReadResult(cache_type_, try_sync ? READ_RESULT_NONBLOCK_EMPTY_RETURN
843 : READ_RESULT_FAST_EMPTY_RETURN);
853 // If there is nothing to read, we bail out before setting state_ to 844 // If there is nothing to read, we bail out before setting state_ to
854 // STATE_IO_PENDING. 845 // STATE_IO_PENDING.
855 if (!callback.is_null()) 846 if (!callback.is_null() && !try_sync)
856 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, 847 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
857 base::Bind(callback, 0)); 848 base::Bind(callback, 0));
858 return; 849 return 0;
859 } 850 }
860 851
861 buf_len = std::min(buf_len, GetDataSize(stream_index) - offset); 852 buf_len = std::min(buf_len, GetDataSize(stream_index) - offset);
862 853
863 // 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.
864 if (stream_index == 0) { 855 if (stream_index == 0) {
865 int ret_value = ReadStream0Data(buf, offset, buf_len); 856 int ret_value = ReadStream0Data(buf, offset, buf_len);
866 if (!callback.is_null()) { 857 if (!callback.is_null() && !try_sync) {
867 base::ThreadTaskRunnerHandle::Get()->PostTask( 858 base::ThreadTaskRunnerHandle::Get()->PostTask(
868 FROM_HERE, base::Bind(callback, ret_value)); 859 FROM_HERE, base::Bind(callback, ret_value));
869 } 860 }
870 return; 861 return ret_value;
871 } 862 }
872 863
873 state_ = STATE_IO_PENDING; 864 state_ = STATE_IO_PENDING;
874 if (!doomed_ && backend_.get()) 865 if (!doomed_ && backend_.get())
875 backend_->index()->UseIfExists(entry_hash_); 866 backend_->index()->UseIfExists(entry_hash_);
876 867
877 std::unique_ptr<uint32_t> read_crc32(new uint32_t()); 868 std::unique_ptr<uint32_t> read_crc32(new uint32_t());
878 std::unique_ptr<int> result(new int()); 869 std::unique_ptr<int> result(new int());
879 std::unique_ptr<SimpleEntryStat> entry_stat(new SimpleEntryStat( 870 std::unique_ptr<SimpleEntryStat> entry_stat(new SimpleEntryStat(
880 last_used_, last_modified_, data_size_, sparse_data_size_)); 871 last_used_, last_modified_, data_size_, sparse_data_size_));
881 Closure task = base::Bind( 872 Closure task = base::Bind(
882 &SimpleSynchronousEntry::ReadData, base::Unretained(synchronous_entry_), 873 &SimpleSynchronousEntry::ReadData, base::Unretained(synchronous_entry_),
883 SimpleSynchronousEntry::EntryOperationData(stream_index, offset, buf_len), 874 SimpleSynchronousEntry::EntryOperationData(stream_index, offset, buf_len),
884 base::RetainedRef(buf), read_crc32.get(), entry_stat.get(), result.get()); 875 base::RetainedRef(buf), read_crc32.get(), entry_stat.get(), result.get());
885 Closure reply = base::Bind(&SimpleEntryImpl::ReadOperationComplete, 876 Closure reply = base::Bind(&SimpleEntryImpl::ReadOperationComplete,
886 this, 877 this,
887 stream_index, 878 stream_index,
888 offset, 879 offset,
889 callback, 880 callback,
890 base::Passed(&read_crc32), 881 base::Passed(&read_crc32),
891 base::Passed(&entry_stat), 882 base::Passed(&entry_stat),
892 base::Passed(&result)); 883 base::Passed(&result));
893 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply); 884 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply);
885 return net::ERR_IO_PENDING;
894 } 886 }
895 887
896 void SimpleEntryImpl::WriteDataInternal(int stream_index, 888 void SimpleEntryImpl::WriteDataInternal(int stream_index,
897 int offset, 889 int offset,
898 net::IOBuffer* buf, 890 net::IOBuffer* buf,
899 int buf_len, 891 int buf_len,
900 const CompletionCallback& callback, 892 const CompletionCallback& callback,
901 bool truncate) { 893 bool truncate) {
902 DCHECK(io_thread_checker_.CalledOnValidThread()); 894 DCHECK(io_thread_checker_.CalledOnValidThread());
903 ScopedOperationRunner operation_runner(this); 895 ScopedOperationRunner operation_runner(this);
(...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after
1562 } 1554 }
1563 crc32s_end_offset_[stream_index] = offset + length; 1555 crc32s_end_offset_[stream_index] = offset + length;
1564 } else if (offset < crc32s_end_offset_[stream_index]) { 1556 } else if (offset < crc32s_end_offset_[stream_index]) {
1565 // If a range for which the crc32 was already computed is rewritten, the 1557 // If a range for which the crc32 was already computed is rewritten, the
1566 // computation of the crc32 need to start from 0 again. 1558 // computation of the crc32 need to start from 0 again.
1567 crc32s_end_offset_[stream_index] = 0; 1559 crc32s_end_offset_[stream_index] = 0;
1568 } 1560 }
1569 } 1561 }
1570 1562
1571 } // namespace disk_cache 1563 } // namespace disk_cache
OLDNEW
« no previous file with comments | « net/disk_cache/simple/simple_entry_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698