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 <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
328 int buf_len, | 328 int buf_len, |
329 const CompletionCallback& callback) { | 329 const CompletionCallback& callback) { |
330 DCHECK(io_thread_checker_.CalledOnValidThread()); | 330 DCHECK(io_thread_checker_.CalledOnValidThread()); |
331 | 331 |
332 if (net_log_.IsLoggingAllEvents()) { | 332 if (net_log_.IsLoggingAllEvents()) { |
333 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_READ_CALL, | 333 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_READ_CALL, |
334 CreateNetLogReadWriteDataCallback(stream_index, offset, buf_len, | 334 CreateNetLogReadWriteDataCallback(stream_index, offset, buf_len, |
335 false)); | 335 false)); |
336 } | 336 } |
337 | 337 |
338 if (stream_index < 0 || stream_index >= kSimpleEntryFileCount || | 338 if (stream_index < 0 || stream_index >= kSimpleEntryStreamCount || |
339 buf_len < 0) { | 339 buf_len < 0) { |
340 if (net_log_.IsLoggingAllEvents()) { | 340 if (net_log_.IsLoggingAllEvents()) { |
341 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_READ_END, | 341 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_READ_END, |
342 CreateNetLogReadWriteCompleteCallback(net::ERR_INVALID_ARGUMENT)); | 342 CreateNetLogReadWriteCompleteCallback(net::ERR_INVALID_ARGUMENT)); |
343 } | 343 } |
344 | 344 |
345 RecordReadResult(cache_type_, READ_RESULT_INVALID_ARGUMENT); | 345 RecordReadResult(cache_type_, READ_RESULT_INVALID_ARGUMENT); |
346 return net::ERR_INVALID_ARGUMENT; | 346 return net::ERR_INVALID_ARGUMENT; |
347 } | 347 } |
348 if (pending_operations_.empty() && (offset >= GetDataSize(stream_index) || | 348 if (pending_operations_.empty() && (offset >= GetDataSize(stream_index) || |
(...skipping 25 matching lines...) Expand all Loading... | |
374 bool truncate) { | 374 bool truncate) { |
375 DCHECK(io_thread_checker_.CalledOnValidThread()); | 375 DCHECK(io_thread_checker_.CalledOnValidThread()); |
376 | 376 |
377 if (net_log_.IsLoggingAllEvents()) { | 377 if (net_log_.IsLoggingAllEvents()) { |
378 net_log_.AddEvent( | 378 net_log_.AddEvent( |
379 net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_WRITE_CALL, | 379 net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_WRITE_CALL, |
380 CreateNetLogReadWriteDataCallback(stream_index, offset, buf_len, | 380 CreateNetLogReadWriteDataCallback(stream_index, offset, buf_len, |
381 truncate)); | 381 truncate)); |
382 } | 382 } |
383 | 383 |
384 if (stream_index < 0 || stream_index >= kSimpleEntryFileCount || offset < 0 || | 384 if (stream_index < 0 || stream_index >= kSimpleEntryStreamCount || |
385 buf_len < 0) { | 385 offset < 0 || buf_len < 0) { |
386 if (net_log_.IsLoggingAllEvents()) { | 386 if (net_log_.IsLoggingAllEvents()) { |
387 net_log_.AddEvent( | 387 net_log_.AddEvent( |
388 net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_WRITE_END, | 388 net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_WRITE_END, |
389 CreateNetLogReadWriteCompleteCallback(net::ERR_INVALID_ARGUMENT)); | 389 CreateNetLogReadWriteCompleteCallback(net::ERR_INVALID_ARGUMENT)); |
390 } | 390 } |
391 RecordWriteResult(cache_type_, WRITE_RESULT_INVALID_ARGUMENT); | 391 RecordWriteResult(cache_type_, WRITE_RESULT_INVALID_ARGUMENT); |
392 return net::ERR_INVALID_ARGUMENT; | 392 return net::ERR_INVALID_ARGUMENT; |
393 } | 393 } |
394 if (backend_.get() && offset + buf_len > backend_->GetMaxFileSize()) { | 394 if (backend_.get() && offset + buf_len > backend_->GetMaxFileSize()) { |
395 if (net_log_.IsLoggingAllEvents()) { | 395 if (net_log_.IsLoggingAllEvents()) { |
396 net_log_.AddEvent( | 396 net_log_.AddEvent( |
397 net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_WRITE_END, | 397 net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_WRITE_END, |
398 CreateNetLogReadWriteCompleteCallback(net::ERR_FAILED)); | 398 CreateNetLogReadWriteCompleteCallback(net::ERR_FAILED)); |
399 } | 399 } |
400 RecordWriteResult(cache_type_, WRITE_RESULT_OVER_MAX_SIZE); | 400 RecordWriteResult(cache_type_, WRITE_RESULT_OVER_MAX_SIZE); |
401 return net::ERR_FAILED; | 401 return net::ERR_FAILED; |
402 } | 402 } |
403 ScopedOperationRunner operation_runner(this); | 403 ScopedOperationRunner operation_runner(this); |
404 | 404 |
405 // Currently, Simple Cache is only used for HTTP, which stores the headers in | 405 // Stream 0 data is kept in memory, so can be written immediatly if there are |
406 // stream 0 and always writes them with a single, truncating write. Detect | 406 // no IO operations pending. |
407 // these writes and record the size and size changes of the headers. Also, | 407 if (stream_index == 0 && state_ == STATE_READY && |
408 // note writes to stream 0 that violate those assumptions. | 408 pending_operations_.size() == 0) |
409 if (stream_index == 0) { | 409 return WriteStream0Data(buf, offset, buf_len, truncate); |
pasko
2013/09/09 20:01:22
This is an optimization over copying the contents
clamy
2013/09/10 14:35:59
Done.
| |
410 if (offset == 0 && truncate) | |
411 RecordHeaderSizeChange(cache_type_, data_size_[0], buf_len); | |
412 else | |
413 RecordUnexpectedStream0Write(cache_type_); | |
414 } | |
415 | 410 |
416 // We can only do optimistic Write if there is no pending operations, so | 411 // We can only do optimistic Write if there is no pending operations, so |
417 // that we are sure that the next call to RunNextOperationIfNeeded will | 412 // that we are sure that the next call to RunNextOperationIfNeeded will |
418 // actually run the write operation that sets the stream size. It also | 413 // actually run the write operation that sets the stream size. It also |
419 // prevents from previous possibly-conflicting writes that could be stacked | 414 // prevents from previous possibly-conflicting writes that could be stacked |
420 // in the |pending_operations_|. We could optimize this for when we have | 415 // in the |pending_operations_|. We could optimize this for when we have |
421 // only read operations enqueued. | 416 // only read operations enqueued. |
422 const bool optimistic = | 417 const bool optimistic = |
423 (use_optimistic_operations_ && state_ == STATE_READY && | 418 (use_optimistic_operations_ && state_ == STATE_READY && |
424 pending_operations_.size() == 0); | 419 pending_operations_.size() == 0); |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
669 DCHECK_EQ(STATE_UNINITIALIZED, state_); | 664 DCHECK_EQ(STATE_UNINITIALIZED, state_); |
670 DCHECK(!synchronous_entry_); | 665 DCHECK(!synchronous_entry_); |
671 | 666 |
672 state_ = STATE_IO_PENDING; | 667 state_ = STATE_IO_PENDING; |
673 | 668 |
674 // Since we don't know the correct values for |last_used_| and | 669 // Since we don't know the correct values for |last_used_| and |
675 // |last_modified_| yet, we make this approximation. | 670 // |last_modified_| yet, we make this approximation. |
676 last_used_ = last_modified_ = base::Time::Now(); | 671 last_used_ = last_modified_ = base::Time::Now(); |
677 | 672 |
678 // If creation succeeds, we should mark all streams to be saved on close. | 673 // If creation succeeds, we should mark all streams to be saved on close. |
679 for (int i = 0; i < kSimpleEntryFileCount; ++i) | 674 for (int i = 0; i < kSimpleEntryStreamCount; ++i) |
680 have_written_[i] = true; | 675 have_written_[i] = true; |
681 | 676 |
682 const base::TimeTicks start_time = base::TimeTicks::Now(); | 677 const base::TimeTicks start_time = base::TimeTicks::Now(); |
683 scoped_ptr<SimpleEntryCreationResults> results( | 678 scoped_ptr<SimpleEntryCreationResults> results( |
684 new SimpleEntryCreationResults( | 679 new SimpleEntryCreationResults( |
685 SimpleEntryStat(last_used_, last_modified_, data_size_))); | 680 SimpleEntryStat(last_used_, last_modified_, data_size_))); |
686 Closure task = base::Bind(&SimpleSynchronousEntry::CreateEntry, | 681 Closure task = base::Bind(&SimpleSynchronousEntry::CreateEntry, |
687 cache_type_, | 682 cache_type_, |
688 path_, | 683 path_, |
689 key_, | 684 key_, |
(...skipping 14 matching lines...) Expand all Loading... | |
704 DCHECK(io_thread_checker_.CalledOnValidThread()); | 699 DCHECK(io_thread_checker_.CalledOnValidThread()); |
705 typedef SimpleSynchronousEntry::CRCRecord CRCRecord; | 700 typedef SimpleSynchronousEntry::CRCRecord CRCRecord; |
706 scoped_ptr<std::vector<CRCRecord> > | 701 scoped_ptr<std::vector<CRCRecord> > |
707 crc32s_to_write(new std::vector<CRCRecord>()); | 702 crc32s_to_write(new std::vector<CRCRecord>()); |
708 | 703 |
709 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_CLOSE_BEGIN); | 704 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_CLOSE_BEGIN); |
710 | 705 |
711 if (state_ == STATE_READY) { | 706 if (state_ == STATE_READY) { |
712 DCHECK(synchronous_entry_); | 707 DCHECK(synchronous_entry_); |
713 state_ = STATE_IO_PENDING; | 708 state_ = STATE_IO_PENDING; |
714 for (int i = 0; i < kSimpleEntryFileCount; ++i) { | 709 for (int i = 0; i < kSimpleEntryStreamCount; ++i) { |
715 if (have_written_[i]) { | 710 if (have_written_[i]) { |
716 if (GetDataSize(i) == crc32s_end_offset_[i]) { | 711 if (GetDataSize(i) == crc32s_end_offset_[i]) { |
717 int32 crc = GetDataSize(i) == 0 ? crc32(0, Z_NULL, 0) : crc32s_[i]; | 712 int32 crc = GetDataSize(i) == 0 ? crc32(0, Z_NULL, 0) : crc32s_[i]; |
718 crc32s_to_write->push_back(CRCRecord(i, true, crc)); | 713 crc32s_to_write->push_back(CRCRecord(i, true, crc)); |
719 } else { | 714 } else { |
720 crc32s_to_write->push_back(CRCRecord(i, false, 0)); | 715 crc32s_to_write->push_back(CRCRecord(i, false, 0)); |
721 } | 716 } |
722 } | 717 } |
723 } | 718 } |
724 } else { | 719 } else { |
725 DCHECK(STATE_UNINITIALIZED == state_ || STATE_FAILURE == state_); | 720 DCHECK(STATE_UNINITIALIZED == state_ || STATE_FAILURE == state_); |
726 } | 721 } |
727 | 722 |
728 if (synchronous_entry_) { | 723 if (synchronous_entry_) { |
729 Closure task = | 724 Closure task = |
730 base::Bind(&SimpleSynchronousEntry::Close, | 725 base::Bind(&SimpleSynchronousEntry::Close, |
731 base::Unretained(synchronous_entry_), | 726 base::Unretained(synchronous_entry_), |
732 SimpleEntryStat(last_used_, last_modified_, data_size_), | 727 SimpleEntryStat(last_used_, last_modified_, data_size_), |
733 base::Passed(&crc32s_to_write)); | 728 base::Passed(&crc32s_to_write), |
729 stream_0_data_); | |
734 Closure reply = base::Bind(&SimpleEntryImpl::CloseOperationComplete, this); | 730 Closure reply = base::Bind(&SimpleEntryImpl::CloseOperationComplete, this); |
735 synchronous_entry_ = NULL; | 731 synchronous_entry_ = NULL; |
736 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply); | 732 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply); |
737 | 733 |
738 for (int i = 0; i < kSimpleEntryFileCount; ++i) { | 734 for (int i = 0; i < kSimpleEntryStreamCount; ++i) { |
739 if (!have_written_[i]) { | 735 if (!have_written_[i]) { |
740 SIMPLE_CACHE_UMA(ENUMERATION, | 736 SIMPLE_CACHE_UMA(ENUMERATION, |
741 "CheckCRCResult", cache_type_, | 737 "CheckCRCResult", cache_type_, |
742 crc_check_state_[i], CRC_CHECK_MAX); | 738 crc_check_state_[i], CRC_CHECK_MAX); |
743 } | 739 } |
744 } | 740 } |
745 } else { | 741 } else { |
746 synchronous_entry_ = NULL; | 742 synchronous_entry_ = NULL; |
747 CloseOperationComplete(); | 743 CloseOperationComplete(); |
748 } | 744 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
780 if (offset >= GetDataSize(stream_index) || offset < 0 || !buf_len) { | 776 if (offset >= GetDataSize(stream_index) || offset < 0 || !buf_len) { |
781 RecordReadResult(cache_type_, READ_RESULT_FAST_EMPTY_RETURN); | 777 RecordReadResult(cache_type_, READ_RESULT_FAST_EMPTY_RETURN); |
782 // If there is nothing to read, we bail out before setting state_ to | 778 // If there is nothing to read, we bail out before setting state_ to |
783 // STATE_IO_PENDING. | 779 // STATE_IO_PENDING. |
784 if (!callback.is_null()) | 780 if (!callback.is_null()) |
785 MessageLoopProxy::current()->PostTask(FROM_HERE, base::Bind( | 781 MessageLoopProxy::current()->PostTask(FROM_HERE, base::Bind( |
786 callback, 0)); | 782 callback, 0)); |
787 return; | 783 return; |
788 } | 784 } |
789 | 785 |
786 // Stream 0 data is kept in memory, so can be read immediately. | |
pasko
2013/09/09 20:01:22
s/so can be//
we do not have an option to post a
clamy
2013/09/10 14:35:59
Done.
| |
787 if (stream_index == 0) { | |
788 int ret_value = ReadStream0Data(buf, offset, buf_len); | |
789 if (!callback.is_null()) { | |
790 MessageLoopProxy::current() | |
791 ->PostTask(FROM_HERE, base::Bind(callback, ret_value)); | |
792 } | |
793 return; | |
794 } | |
795 | |
790 buf_len = std::min(buf_len, GetDataSize(stream_index) - offset); | 796 buf_len = std::min(buf_len, GetDataSize(stream_index) - offset); |
791 | 797 |
792 state_ = STATE_IO_PENDING; | 798 state_ = STATE_IO_PENDING; |
793 if (backend_.get()) | 799 if (backend_.get()) |
794 backend_->index()->UseIfExists(entry_hash_); | 800 backend_->index()->UseIfExists(entry_hash_); |
795 | 801 |
796 scoped_ptr<uint32> read_crc32(new uint32()); | 802 scoped_ptr<uint32> read_crc32(new uint32()); |
797 scoped_ptr<int> result(new int()); | 803 scoped_ptr<int> result(new int()); |
798 scoped_ptr<base::Time> last_used(new base::Time()); | 804 scoped_ptr<SimpleEntryStat> entry_stat( |
805 new SimpleEntryStat(last_used_, last_modified_, data_size_)); | |
799 Closure task = base::Bind( | 806 Closure task = base::Bind( |
800 &SimpleSynchronousEntry::ReadData, | 807 &SimpleSynchronousEntry::ReadData, |
801 base::Unretained(synchronous_entry_), | 808 base::Unretained(synchronous_entry_), |
802 SimpleSynchronousEntry::EntryOperationData(stream_index, offset, buf_len), | 809 SimpleSynchronousEntry::EntryOperationData(stream_index, offset, buf_len), |
803 make_scoped_refptr(buf), | 810 make_scoped_refptr(buf), |
804 read_crc32.get(), | 811 read_crc32.get(), |
805 last_used.get(), | 812 entry_stat.get(), |
806 result.get()); | 813 result.get()); |
807 Closure reply = base::Bind(&SimpleEntryImpl::ReadOperationComplete, | 814 Closure reply = base::Bind(&SimpleEntryImpl::ReadOperationComplete, |
808 this, | 815 this, |
809 stream_index, | 816 stream_index, |
810 offset, | 817 offset, |
811 callback, | 818 callback, |
812 base::Passed(&read_crc32), | 819 base::Passed(&read_crc32), |
813 base::Passed(&last_used), | 820 base::Passed(&entry_stat), |
814 base::Passed(&result)); | 821 base::Passed(&result)); |
815 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply); | 822 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply); |
816 } | 823 } |
817 | 824 |
818 void SimpleEntryImpl::WriteDataInternal(int stream_index, | 825 void SimpleEntryImpl::WriteDataInternal(int stream_index, |
819 int offset, | 826 int offset, |
820 net::IOBuffer* buf, | 827 net::IOBuffer* buf, |
821 int buf_len, | 828 int buf_len, |
822 const CompletionCallback& callback, | 829 const CompletionCallback& callback, |
823 bool truncate) { | 830 bool truncate) { |
(...skipping 17 matching lines...) Expand all Loading... | |
841 if (!callback.is_null()) { | 848 if (!callback.is_null()) { |
842 // We need to posttask so that we don't go in a loop when we call the | 849 // We need to posttask so that we don't go in a loop when we call the |
843 // callback directly. | 850 // callback directly. |
844 MessageLoopProxy::current()->PostTask(FROM_HERE, base::Bind( | 851 MessageLoopProxy::current()->PostTask(FROM_HERE, base::Bind( |
845 callback, net::ERR_FAILED)); | 852 callback, net::ERR_FAILED)); |
846 } | 853 } |
847 // |this| may be destroyed after return here. | 854 // |this| may be destroyed after return here. |
848 return; | 855 return; |
849 } | 856 } |
850 | 857 |
858 // Stream 0 data is kept in memory, so can be written immediatly. | |
859 if (stream_index == 0) { | |
860 int ret_value = WriteStream0Data(buf, offset, buf_len, truncate); | |
861 if (!callback.is_null()) { | |
862 // Postask prevents creating a loop when calling the callback directly. | |
863 MessageLoopProxy::current() | |
864 ->PostTask(FROM_HERE, base::Bind(callback, ret_value)); | |
865 } | |
866 return; | |
867 } | |
868 | |
851 DCHECK_EQ(STATE_READY, state_); | 869 DCHECK_EQ(STATE_READY, state_); |
pasko
2013/09/09 20:01:22
this DCHECK belongs better to a place _before_ we
clamy
2013/09/10 14:35:59
Done.
| |
852 state_ = STATE_IO_PENDING; | 870 state_ = STATE_IO_PENDING; |
853 if (backend_.get()) | 871 if (backend_.get()) |
854 backend_->index()->UseIfExists(entry_hash_); | 872 backend_->index()->UseIfExists(entry_hash_); |
855 // It is easy to incrementally compute the CRC from [0 .. |offset + buf_len|) | 873 // It is easy to incrementally compute the CRC from [0 .. |offset + buf_len|) |
856 // if |offset == 0| or we have already computed the CRC for [0 .. offset). | 874 // if |offset == 0| or we have already computed the CRC for [0 .. offset). |
857 // We rely on most write operations being sequential, start to end to compute | 875 // We rely on most write operations being sequential, start to end to compute |
858 // the crc of the data. When we write to an entry and close without having | 876 // the crc of the data. When we write to an entry and close without having |
859 // done a sequential write, we don't check the CRC on read. | 877 // done a sequential write, we don't check the CRC on read. |
860 if (offset == 0 || crc32s_end_offset_[stream_index] == offset) { | 878 if (offset == 0 || crc32s_end_offset_[stream_index] == offset) { |
861 uint32 initial_crc = (offset != 0) ? crc32s_[stream_index] | 879 uint32 initial_crc = (offset != 0) ? crc32s_[stream_index] |
(...skipping 14 matching lines...) Expand all Loading... | |
876 } else { | 894 } else { |
877 data_size_[stream_index] = std::max(offset + buf_len, | 895 data_size_[stream_index] = std::max(offset + buf_len, |
878 GetDataSize(stream_index)); | 896 GetDataSize(stream_index)); |
879 } | 897 } |
880 | 898 |
881 // Since we don't know the correct values for |last_used_| and | 899 // Since we don't know the correct values for |last_used_| and |
882 // |last_modified_| yet, we make this approximation. | 900 // |last_modified_| yet, we make this approximation. |
883 last_used_ = last_modified_ = base::Time::Now(); | 901 last_used_ = last_modified_ = base::Time::Now(); |
884 | 902 |
885 have_written_[stream_index] = true; | 903 have_written_[stream_index] = true; |
904 // Writing on stream 1 affects the placement of stream 0 in the file. | |
905 if (stream_index == 1) | |
906 have_written_[0] = true; | |
886 | 907 |
887 scoped_ptr<int> result(new int()); | 908 scoped_ptr<int> result(new int()); |
888 Closure task = base::Bind(&SimpleSynchronousEntry::WriteData, | 909 Closure task = base::Bind(&SimpleSynchronousEntry::WriteData, |
889 base::Unretained(synchronous_entry_), | 910 base::Unretained(synchronous_entry_), |
890 SimpleSynchronousEntry::EntryOperationData( | 911 SimpleSynchronousEntry::EntryOperationData( |
891 stream_index, offset, buf_len, truncate), | 912 stream_index, offset, buf_len, truncate), |
892 make_scoped_refptr(buf), | 913 make_scoped_refptr(buf), |
893 entry_stat.get(), | 914 entry_stat.get(), |
894 result.get()); | 915 result.get()); |
895 Closure reply = base::Bind(&SimpleEntryImpl::WriteOperationComplete, | 916 Closure reply = base::Bind(&SimpleEntryImpl::WriteOperationComplete, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
927 MakeUninitialized(); | 948 MakeUninitialized(); |
928 return; | 949 return; |
929 } | 950 } |
930 // If out_entry is NULL, it means we already called ReturnEntryToCaller from | 951 // If out_entry is NULL, it means we already called ReturnEntryToCaller from |
931 // the optimistic Create case. | 952 // the optimistic Create case. |
932 if (out_entry) | 953 if (out_entry) |
933 ReturnEntryToCaller(out_entry); | 954 ReturnEntryToCaller(out_entry); |
934 | 955 |
935 state_ = STATE_READY; | 956 state_ = STATE_READY; |
936 synchronous_entry_ = in_results->sync_entry; | 957 synchronous_entry_ = in_results->sync_entry; |
958 stream_0_data_ = in_results->stream_0_data; | |
959 // The crc was read in SimpleSynchronousEntry. | |
960 crc_check_state_[0] = CRC_CHECK_DONE; | |
937 if (key_.empty()) { | 961 if (key_.empty()) { |
938 SetKey(synchronous_entry_->key()); | 962 SetKey(synchronous_entry_->key()); |
939 } else { | 963 } else { |
940 // This should only be triggered when creating an entry. The key check in | 964 // This should only be triggered when creating an entry. The key check in |
941 // the open case is handled in SimpleBackendImpl. | 965 // the open case is handled in SimpleBackendImpl. |
942 DCHECK_EQ(key_, synchronous_entry_->key()); | 966 DCHECK_EQ(key_, synchronous_entry_->key()); |
943 } | 967 } |
944 UpdateDataFromEntryStat(in_results->entry_stat); | 968 UpdateDataFromEntryStat(in_results->entry_stat); |
945 SIMPLE_CACHE_UMA(TIMES, | 969 SIMPLE_CACHE_UMA(TIMES, |
946 "EntryCreationTime", cache_type_, | 970 "EntryCreationTime", cache_type_, |
(...skipping 30 matching lines...) Expand all Loading... | |
977 completion_callback, *result)); | 1001 completion_callback, *result)); |
978 } | 1002 } |
979 RunNextOperationIfNeeded(); | 1003 RunNextOperationIfNeeded(); |
980 } | 1004 } |
981 | 1005 |
982 void SimpleEntryImpl::ReadOperationComplete( | 1006 void SimpleEntryImpl::ReadOperationComplete( |
983 int stream_index, | 1007 int stream_index, |
984 int offset, | 1008 int offset, |
985 const CompletionCallback& completion_callback, | 1009 const CompletionCallback& completion_callback, |
986 scoped_ptr<uint32> read_crc32, | 1010 scoped_ptr<uint32> read_crc32, |
987 scoped_ptr<base::Time> last_used, | 1011 scoped_ptr<SimpleEntryStat> entry_stat, |
988 scoped_ptr<int> result) { | 1012 scoped_ptr<int> result) { |
989 DCHECK(io_thread_checker_.CalledOnValidThread()); | 1013 DCHECK(io_thread_checker_.CalledOnValidThread()); |
990 DCHECK(synchronous_entry_); | 1014 DCHECK(synchronous_entry_); |
991 DCHECK_EQ(STATE_IO_PENDING, state_); | 1015 DCHECK_EQ(STATE_IO_PENDING, state_); |
992 DCHECK(read_crc32); | 1016 DCHECK(read_crc32); |
993 DCHECK(result); | 1017 DCHECK(result); |
994 | 1018 |
995 if (*result > 0 && | 1019 if (*result > 0 && |
996 crc_check_state_[stream_index] == CRC_CHECK_NEVER_READ_AT_ALL) { | 1020 crc_check_state_[stream_index] == CRC_CHECK_NEVER_READ_AT_ALL) { |
997 crc_check_state_[stream_index] = CRC_CHECK_NEVER_READ_TO_END; | 1021 crc_check_state_[stream_index] = CRC_CHECK_NEVER_READ_TO_END; |
(...skipping 15 matching lines...) Expand all Loading... | |
1013 // entry, one reader can be behind the other. In this case we compute | 1037 // entry, one reader can be behind the other. In this case we compute |
1014 // the crc as the most advanced reader progresses, and check it for | 1038 // the crc as the most advanced reader progresses, and check it for |
1015 // both readers as they read the last byte. | 1039 // both readers as they read the last byte. |
1016 | 1040 |
1017 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_CHECKSUM_BEGIN); | 1041 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_CHECKSUM_BEGIN); |
1018 | 1042 |
1019 scoped_ptr<int> new_result(new int()); | 1043 scoped_ptr<int> new_result(new int()); |
1020 Closure task = base::Bind(&SimpleSynchronousEntry::CheckEOFRecord, | 1044 Closure task = base::Bind(&SimpleSynchronousEntry::CheckEOFRecord, |
1021 base::Unretained(synchronous_entry_), | 1045 base::Unretained(synchronous_entry_), |
1022 stream_index, | 1046 stream_index, |
1023 data_size_[stream_index], | 1047 data_size_, |
1024 crc32s_[stream_index], | 1048 crc32s_[stream_index], |
1025 new_result.get()); | 1049 new_result.get()); |
1026 Closure reply = base::Bind(&SimpleEntryImpl::ChecksumOperationComplete, | 1050 Closure reply = base::Bind(&SimpleEntryImpl::ChecksumOperationComplete, |
1027 this, *result, stream_index, | 1051 this, *result, stream_index, |
1028 completion_callback, | 1052 completion_callback, |
1029 base::Passed(&new_result)); | 1053 base::Passed(&new_result)); |
1030 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply); | 1054 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply); |
1031 crc_check_state_[stream_index] = CRC_CHECK_DONE; | 1055 crc_check_state_[stream_index] = CRC_CHECK_DONE; |
1032 return; | 1056 return; |
1033 } | 1057 } |
1034 } | 1058 } |
1035 | 1059 |
1036 if (*result < 0) { | 1060 if (*result < 0) { |
1037 RecordReadResult(cache_type_, READ_RESULT_SYNC_READ_FAILURE); | 1061 RecordReadResult(cache_type_, READ_RESULT_SYNC_READ_FAILURE); |
1038 } else { | 1062 } else { |
1039 RecordReadResult(cache_type_, READ_RESULT_SUCCESS); | 1063 RecordReadResult(cache_type_, READ_RESULT_SUCCESS); |
1040 if (crc_check_state_[stream_index] == CRC_CHECK_NEVER_READ_TO_END && | 1064 if (crc_check_state_[stream_index] == CRC_CHECK_NEVER_READ_TO_END && |
1041 offset + *result == GetDataSize(stream_index)) { | 1065 offset + *result == GetDataSize(stream_index)) { |
1042 crc_check_state_[stream_index] = CRC_CHECK_NOT_DONE; | 1066 crc_check_state_[stream_index] = CRC_CHECK_NOT_DONE; |
1043 } | 1067 } |
1044 } | 1068 } |
1045 if (net_log_.IsLoggingAllEvents()) { | 1069 if (net_log_.IsLoggingAllEvents()) { |
1046 net_log_.AddEvent( | 1070 net_log_.AddEvent( |
1047 net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_READ_END, | 1071 net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_READ_END, |
1048 CreateNetLogReadWriteCompleteCallback(*result)); | 1072 CreateNetLogReadWriteCompleteCallback(*result)); |
1049 } | 1073 } |
1050 | 1074 |
1051 EntryOperationComplete( | 1075 EntryOperationComplete( |
1052 stream_index, | 1076 stream_index, completion_callback, *entry_stat, result.Pass()); |
pasko
2013/09/09 20:01:22
probably .Pass() would be more stylish
clamy
2013/09/10 14:35:59
EntryOperationComplete expects a const SimpleEntry
| |
1053 completion_callback, | |
1054 SimpleEntryStat(*last_used, last_modified_, data_size_), | |
1055 result.Pass()); | |
1056 } | 1077 } |
1057 | 1078 |
1058 void SimpleEntryImpl::WriteOperationComplete( | 1079 void SimpleEntryImpl::WriteOperationComplete( |
1059 int stream_index, | 1080 int stream_index, |
1060 const CompletionCallback& completion_callback, | 1081 const CompletionCallback& completion_callback, |
1061 scoped_ptr<SimpleEntryStat> entry_stat, | 1082 scoped_ptr<SimpleEntryStat> entry_stat, |
1062 scoped_ptr<int> result) { | 1083 scoped_ptr<int> result) { |
1063 if (*result >= 0) | 1084 if (*result >= 0) |
1064 RecordWriteResult(cache_type_, WRITE_RESULT_SUCCESS); | 1085 RecordWriteResult(cache_type_, WRITE_RESULT_SUCCESS); |
1065 else | 1086 else |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1122 } | 1143 } |
1123 | 1144 |
1124 void SimpleEntryImpl::UpdateDataFromEntryStat( | 1145 void SimpleEntryImpl::UpdateDataFromEntryStat( |
1125 const SimpleEntryStat& entry_stat) { | 1146 const SimpleEntryStat& entry_stat) { |
1126 DCHECK(io_thread_checker_.CalledOnValidThread()); | 1147 DCHECK(io_thread_checker_.CalledOnValidThread()); |
1127 DCHECK(synchronous_entry_); | 1148 DCHECK(synchronous_entry_); |
1128 DCHECK_EQ(STATE_READY, state_); | 1149 DCHECK_EQ(STATE_READY, state_); |
1129 | 1150 |
1130 last_used_ = entry_stat.last_used; | 1151 last_used_ = entry_stat.last_used; |
1131 last_modified_ = entry_stat.last_modified; | 1152 last_modified_ = entry_stat.last_modified; |
1132 for (int i = 0; i < kSimpleEntryFileCount; ++i) { | 1153 for (int i = 0; i < kSimpleEntryStreamCount; ++i) { |
1133 data_size_[i] = entry_stat.data_size[i]; | 1154 data_size_[i] = entry_stat.data_size[i]; |
1134 } | 1155 } |
1135 if (backend_.get()) | 1156 if (backend_.get()) |
1136 backend_->index()->UpdateEntrySize(entry_hash_, GetDiskUsage()); | 1157 backend_->index()->UpdateEntrySize(entry_hash_, GetDiskUsage()); |
1137 } | 1158 } |
1138 | 1159 |
1139 int64 SimpleEntryImpl::GetDiskUsage() const { | 1160 int64 SimpleEntryImpl::GetDiskUsage() const { |
1140 int64 file_size = 0; | 1161 int64 file_size = 0; |
1141 for (int i = 0; i < kSimpleEntryFileCount; ++i) { | 1162 for (int i = 0; i < kSimpleEntryStreamCount; ++i) { |
1142 file_size += | 1163 file_size += |
1143 simple_util::GetFileSizeFromKeyAndDataSize(key_, data_size_[i]); | 1164 simple_util::GetFileSizeFromKeyAndDataSize(key_, data_size_[i]); |
1144 } | 1165 } |
1145 return file_size; | 1166 return file_size; |
1146 } | 1167 } |
1147 | 1168 |
1148 void SimpleEntryImpl::RecordReadIsParallelizable( | 1169 void SimpleEntryImpl::RecordReadIsParallelizable( |
1149 const SimpleEntryOperation& operation) const { | 1170 const SimpleEntryOperation& operation) const { |
1150 if (!executing_operation_) | 1171 if (!executing_operation_) |
1151 return; | 1172 return; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1209 } else { | 1230 } else { |
1210 type = conflicting ? WRITE_FOLLOWS_CONFLICTING_WRITE | 1231 type = conflicting ? WRITE_FOLLOWS_CONFLICTING_WRITE |
1211 : WRITE_FOLLOWS_NON_CONFLICTING_WRITE; | 1232 : WRITE_FOLLOWS_NON_CONFLICTING_WRITE; |
1212 } | 1233 } |
1213 } | 1234 } |
1214 SIMPLE_CACHE_UMA(ENUMERATION, | 1235 SIMPLE_CACHE_UMA(ENUMERATION, |
1215 "WriteDependencyType", cache_type_, | 1236 "WriteDependencyType", cache_type_, |
1216 type, WRITE_DEPENDENCY_TYPE_MAX); | 1237 type, WRITE_DEPENDENCY_TYPE_MAX); |
1217 } | 1238 } |
1218 | 1239 |
1240 int SimpleEntryImpl::ReadStream0Data(net::IOBuffer* buf, | |
1241 int offset, | |
1242 int buf_len) { | |
1243 int read_size = std::min(data_size_[0] - offset, buf_len); | |
1244 if (read_size < 0) { | |
1245 RecordReadResult(cache_type_, READ_RESULT_SUCCESS); | |
1246 return 0; | |
1247 } | |
1248 memcpy(buf->data(), stream_0_data_->data() + offset, read_size); | |
1249 UpdateDataFromEntryStat( | |
1250 SimpleEntryStat(base::Time::Now(), last_modified_, data_size_)); | |
1251 RecordReadResult(cache_type_, READ_RESULT_SUCCESS); | |
1252 return read_size; | |
1253 } | |
1254 | |
1255 int SimpleEntryImpl::WriteStream0Data(net::IOBuffer* buf, | |
1256 int offset, | |
1257 int buf_len, | |
1258 bool truncate) { | |
1259 // Currently, Simple Cache is only used for HTTP, which stores the headers in | |
1260 // stream 0 and always writes them with a single, truncating write. Detect | |
1261 // these writes and record the size and size changes of the headers. Also, | |
1262 // note writes to stream 0 that violate those assumptions. | |
pasko
2013/09/09 20:01:22
nit: not sure: s/note/support/ ?
clamy
2013/09/10 14:35:59
Done.
| |
1263 have_written_[0] = true; | |
1264 if (offset == 0 && truncate) { | |
1265 RecordHeaderSizeChange(cache_type_, data_size_[0], buf_len); | |
1266 stream_0_data_ = new IOBuffer(buf_len); | |
pasko
2013/09/09 20:01:22
please use a GrowableIOBuffer, it might be less op
clamy
2013/09/10 14:35:59
Done.
| |
1267 memcpy(stream_0_data_->data(), buf->data(), buf_len); | |
1268 data_size_[0] = buf_len; | |
1269 } else { | |
1270 RecordUnexpectedStream0Write(cache_type_); | |
1271 int buffer_size; | |
1272 if (truncate) | |
1273 buffer_size = offset + buf_len; | |
1274 else | |
1275 buffer_size = std::max(offset + buf_len, data_size_[0]); | |
1276 scoped_refptr<IOBuffer> new_data = new IOBuffer(buffer_size); | |
1277 memset(new_data->data(), 0, buffer_size); | |
1278 if (stream_0_data_) { | |
1279 memcpy(new_data->data(), | |
1280 stream_0_data_->data(), | |
1281 std::min(data_size_[0], buffer_size)); | |
1282 } | |
1283 if (buf) | |
1284 memcpy(new_data->data() + offset, buf->data(), buf_len); | |
1285 stream_0_data_ = new_data; | |
1286 data_size_[0] = buffer_size; | |
1287 } | |
1288 base::Time modification_time = base::Time::Now(); | |
1289 UpdateDataFromEntryStat( | |
1290 SimpleEntryStat(modification_time, modification_time, data_size_)); | |
1291 if (stream_0_data_) { | |
1292 crc32s_[0] = crc32(crc32(0L, Z_NULL, 0), | |
1293 reinterpret_cast<const Bytef*>(stream_0_data_->data()), | |
1294 data_size_[0]); | |
1295 } else { | |
1296 crc32s_[0] = crc32(0L, Z_NULL, 0); | |
1297 } | |
1298 RecordWriteResult(cache_type_, WRITE_RESULT_SUCCESS); | |
1299 return buf_len; | |
1300 } | |
1301 | |
1219 } // namespace disk_cache | 1302 } // namespace disk_cache |
OLD | NEW |