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 | |
406 // stream 0 and always writes them with a single, truncating write. Detect | |
407 // these writes and record the size and size changes of the headers. Also, | |
408 // note writes to stream 0 that violate those assumptions. | |
409 if (stream_index == 0) { | |
410 if (offset == 0 && truncate) | |
411 RecordHeaderSizeChange(cache_type_, data_size_[0], buf_len); | |
412 else | |
413 RecordUnexpectedStream0Write(cache_type_); | |
414 } | |
415 | |
416 // We can only do optimistic Write if there is no pending operations, so | 405 // 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 | 406 // that we are sure that the next call to RunNextOperationIfNeeded will |
418 // actually run the write operation that sets the stream size. It also | 407 // actually run the write operation that sets the stream size. It also |
419 // prevents from previous possibly-conflicting writes that could be stacked | 408 // prevents from previous possibly-conflicting writes that could be stacked |
420 // in the |pending_operations_|. We could optimize this for when we have | 409 // in the |pending_operations_|. We could optimize this for when we have |
421 // only read operations enqueued. | 410 // only read operations enqueued. |
422 const bool optimistic = | 411 const bool optimistic = |
423 (use_optimistic_operations_ && state_ == STATE_READY && | 412 (use_optimistic_operations_ && state_ == STATE_READY && |
424 pending_operations_.size() == 0); | 413 pending_operations_.size() == 0); |
425 CompletionCallback op_callback; | 414 CompletionCallback op_callback; |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
685 DCHECK_EQ(STATE_UNINITIALIZED, state_); | 674 DCHECK_EQ(STATE_UNINITIALIZED, state_); |
686 DCHECK(!synchronous_entry_); | 675 DCHECK(!synchronous_entry_); |
687 | 676 |
688 state_ = STATE_IO_PENDING; | 677 state_ = STATE_IO_PENDING; |
689 | 678 |
690 // Since we don't know the correct values for |last_used_| and | 679 // Since we don't know the correct values for |last_used_| and |
691 // |last_modified_| yet, we make this approximation. | 680 // |last_modified_| yet, we make this approximation. |
692 last_used_ = last_modified_ = base::Time::Now(); | 681 last_used_ = last_modified_ = base::Time::Now(); |
693 | 682 |
694 // If creation succeeds, we should mark all streams to be saved on close. | 683 // If creation succeeds, we should mark all streams to be saved on close. |
695 for (int i = 0; i < kSimpleEntryFileCount; ++i) | 684 for (int i = 0; i < kSimpleEntryStreamCount; ++i) |
696 have_written_[i] = true; | 685 have_written_[i] = true; |
697 | 686 |
698 const base::TimeTicks start_time = base::TimeTicks::Now(); | 687 const base::TimeTicks start_time = base::TimeTicks::Now(); |
699 scoped_ptr<SimpleEntryCreationResults> results( | 688 scoped_ptr<SimpleEntryCreationResults> results( |
700 new SimpleEntryCreationResults( | 689 new SimpleEntryCreationResults( |
701 SimpleEntryStat(last_used_, last_modified_, data_size_))); | 690 SimpleEntryStat(last_used_, last_modified_, data_size_))); |
702 Closure task = base::Bind(&SimpleSynchronousEntry::CreateEntry, | 691 Closure task = base::Bind(&SimpleSynchronousEntry::CreateEntry, |
703 cache_type_, | 692 cache_type_, |
704 path_, | 693 path_, |
705 key_, | 694 key_, |
(...skipping 14 matching lines...) Expand all Loading... | |
720 DCHECK(io_thread_checker_.CalledOnValidThread()); | 709 DCHECK(io_thread_checker_.CalledOnValidThread()); |
721 typedef SimpleSynchronousEntry::CRCRecord CRCRecord; | 710 typedef SimpleSynchronousEntry::CRCRecord CRCRecord; |
722 scoped_ptr<std::vector<CRCRecord> > | 711 scoped_ptr<std::vector<CRCRecord> > |
723 crc32s_to_write(new std::vector<CRCRecord>()); | 712 crc32s_to_write(new std::vector<CRCRecord>()); |
724 | 713 |
725 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_CLOSE_BEGIN); | 714 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_CLOSE_BEGIN); |
726 | 715 |
727 if (state_ == STATE_READY) { | 716 if (state_ == STATE_READY) { |
728 DCHECK(synchronous_entry_); | 717 DCHECK(synchronous_entry_); |
729 state_ = STATE_IO_PENDING; | 718 state_ = STATE_IO_PENDING; |
730 for (int i = 0; i < kSimpleEntryFileCount; ++i) { | 719 for (int i = 0; i < kSimpleEntryStreamCount; ++i) { |
731 if (have_written_[i]) { | 720 if (have_written_[i]) { |
732 if (GetDataSize(i) == crc32s_end_offset_[i]) { | 721 if (GetDataSize(i) == crc32s_end_offset_[i]) { |
733 int32 crc = GetDataSize(i) == 0 ? crc32(0, Z_NULL, 0) : crc32s_[i]; | 722 int32 crc = GetDataSize(i) == 0 ? crc32(0, Z_NULL, 0) : crc32s_[i]; |
734 crc32s_to_write->push_back(CRCRecord(i, true, crc)); | 723 crc32s_to_write->push_back(CRCRecord(i, true, crc)); |
735 } else { | 724 } else { |
736 crc32s_to_write->push_back(CRCRecord(i, false, 0)); | 725 crc32s_to_write->push_back(CRCRecord(i, false, 0)); |
737 } | 726 } |
738 } | 727 } |
739 } | 728 } |
740 } else { | 729 } else { |
741 DCHECK(STATE_UNINITIALIZED == state_ || STATE_FAILURE == state_); | 730 DCHECK(STATE_UNINITIALIZED == state_ || STATE_FAILURE == state_); |
742 } | 731 } |
743 | 732 |
744 if (synchronous_entry_) { | 733 if (synchronous_entry_) { |
745 Closure task = | 734 Closure task = |
746 base::Bind(&SimpleSynchronousEntry::Close, | 735 base::Bind(&SimpleSynchronousEntry::Close, |
747 base::Unretained(synchronous_entry_), | 736 base::Unretained(synchronous_entry_), |
748 SimpleEntryStat(last_used_, last_modified_, data_size_), | 737 SimpleEntryStat(last_used_, last_modified_, data_size_), |
749 base::Passed(&crc32s_to_write)); | 738 base::Passed(&crc32s_to_write), |
739 stream_0_data_); | |
750 Closure reply = base::Bind(&SimpleEntryImpl::CloseOperationComplete, this); | 740 Closure reply = base::Bind(&SimpleEntryImpl::CloseOperationComplete, this); |
751 synchronous_entry_ = NULL; | 741 synchronous_entry_ = NULL; |
752 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply); | 742 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply); |
753 | 743 |
754 for (int i = 0; i < kSimpleEntryFileCount; ++i) { | 744 for (int i = 0; i < kSimpleEntryStreamCount; ++i) { |
755 if (!have_written_[i]) { | 745 if (!have_written_[i]) { |
756 SIMPLE_CACHE_UMA(ENUMERATION, | 746 SIMPLE_CACHE_UMA(ENUMERATION, |
757 "CheckCRCResult", cache_type_, | 747 "CheckCRCResult", cache_type_, |
758 crc_check_state_[i], CRC_CHECK_MAX); | 748 crc_check_state_[i], CRC_CHECK_MAX); |
759 } | 749 } |
760 } | 750 } |
761 } else { | 751 } else { |
762 CloseOperationComplete(); | 752 CloseOperationComplete(); |
763 } | 753 } |
764 } | 754 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
797 DCHECK_EQ(STATE_READY, state_); | 787 DCHECK_EQ(STATE_READY, state_); |
798 if (offset >= GetDataSize(stream_index) || offset < 0 || !buf_len) { | 788 if (offset >= GetDataSize(stream_index) || offset < 0 || !buf_len) { |
799 RecordReadResult(cache_type_, READ_RESULT_FAST_EMPTY_RETURN); | 789 RecordReadResult(cache_type_, READ_RESULT_FAST_EMPTY_RETURN); |
800 // If there is nothing to read, we bail out before setting state_ to | 790 // If there is nothing to read, we bail out before setting state_ to |
801 // STATE_IO_PENDING. | 791 // STATE_IO_PENDING. |
802 if (!callback.is_null()) | 792 if (!callback.is_null()) |
803 MessageLoopProxy::current()->PostTask(FROM_HERE, base::Bind(callback, 0)); | 793 MessageLoopProxy::current()->PostTask(FROM_HERE, base::Bind(callback, 0)); |
804 return; | 794 return; |
805 } | 795 } |
806 | 796 |
797 // Since stream 0 data is kept in memory, it is read immediately. | |
798 if (stream_index == 0) { | |
799 int ret_value = ReadStream0Data(buf, offset, buf_len); | |
800 if (!callback.is_null()) { | |
801 MessageLoopProxy::current()->PostTask(FROM_HERE, | |
802 base::Bind(callback, ret_value)); | |
803 } | |
804 return; | |
805 } | |
806 | |
807 buf_len = std::min(buf_len, GetDataSize(stream_index) - offset); | 807 buf_len = std::min(buf_len, GetDataSize(stream_index) - offset); |
pasko
2013/09/17 14:17:36
we recompute the buf_len here, and in ReadStream0D
clamy
2013/09/18 16:17:14
Done.
| |
808 | 808 |
809 state_ = STATE_IO_PENDING; | 809 state_ = STATE_IO_PENDING; |
810 if (!doomed_ && backend_.get()) | 810 if (!doomed_ && backend_.get()) |
811 backend_->index()->UseIfExists(entry_hash_); | 811 backend_->index()->UseIfExists(entry_hash_); |
812 | 812 |
813 scoped_ptr<uint32> read_crc32(new uint32()); | 813 scoped_ptr<uint32> read_crc32(new uint32()); |
814 scoped_ptr<int> result(new int()); | 814 scoped_ptr<int> result(new int()); |
815 scoped_ptr<base::Time> last_used(new base::Time()); | 815 scoped_ptr<SimpleEntryStat> entry_stat( |
816 new SimpleEntryStat(last_used_, last_modified_, data_size_)); | |
816 Closure task = base::Bind( | 817 Closure task = base::Bind( |
817 &SimpleSynchronousEntry::ReadData, | 818 &SimpleSynchronousEntry::ReadData, |
818 base::Unretained(synchronous_entry_), | 819 base::Unretained(synchronous_entry_), |
819 SimpleSynchronousEntry::EntryOperationData(stream_index, offset, buf_len), | 820 SimpleSynchronousEntry::EntryOperationData(stream_index, offset, buf_len), |
820 make_scoped_refptr(buf), | 821 make_scoped_refptr(buf), |
821 read_crc32.get(), | 822 read_crc32.get(), |
822 last_used.get(), | 823 entry_stat.get(), |
823 result.get()); | 824 result.get()); |
824 Closure reply = base::Bind(&SimpleEntryImpl::ReadOperationComplete, | 825 Closure reply = base::Bind(&SimpleEntryImpl::ReadOperationComplete, |
825 this, | 826 this, |
826 stream_index, | 827 stream_index, |
827 offset, | 828 offset, |
828 callback, | 829 callback, |
829 base::Passed(&read_crc32), | 830 base::Passed(&read_crc32), |
830 base::Passed(&last_used), | 831 base::Passed(&entry_stat), |
831 base::Passed(&result)); | 832 base::Passed(&result)); |
832 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply); | 833 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply); |
833 } | 834 } |
834 | 835 |
835 void SimpleEntryImpl::WriteDataInternal(int stream_index, | 836 void SimpleEntryImpl::WriteDataInternal(int stream_index, |
836 int offset, | 837 int offset, |
837 net::IOBuffer* buf, | 838 net::IOBuffer* buf, |
838 int buf_len, | 839 int buf_len, |
839 const CompletionCallback& callback, | 840 const CompletionCallback& callback, |
840 bool truncate) { | 841 bool truncate) { |
(...skipping 16 matching lines...) Expand all Loading... | |
857 } | 858 } |
858 if (!callback.is_null()) { | 859 if (!callback.is_null()) { |
859 MessageLoopProxy::current()->PostTask( | 860 MessageLoopProxy::current()->PostTask( |
860 FROM_HERE, base::Bind(callback, net::ERR_FAILED)); | 861 FROM_HERE, base::Bind(callback, net::ERR_FAILED)); |
861 } | 862 } |
862 // |this| may be destroyed after return here. | 863 // |this| may be destroyed after return here. |
863 return; | 864 return; |
864 } | 865 } |
865 | 866 |
866 DCHECK_EQ(STATE_READY, state_); | 867 DCHECK_EQ(STATE_READY, state_); |
868 // Since stream 0 data is kept in memory, it will be written immediatly. | |
869 if (stream_index == 0) { | |
870 int ret_value = CopyStream0Data(buf, offset, buf_len, truncate); | |
871 if (!callback.is_null()) { | |
872 // PostTask prevents creating a loop when calling the callback directly. | |
pasko
2013/09/17 14:17:36
nit:
this comment is not necessary, we consistent
clamy
2013/09/18 16:17:14
Done.
| |
873 MessageLoopProxy::current()->PostTask(FROM_HERE, | |
874 base::Bind(callback, ret_value)); | |
875 } | |
876 return; | |
877 } | |
878 | |
867 state_ = STATE_IO_PENDING; | 879 state_ = STATE_IO_PENDING; |
868 if (!doomed_ && backend_.get()) | 880 if (!doomed_ && backend_.get()) |
869 backend_->index()->UseIfExists(entry_hash_); | 881 backend_->index()->UseIfExists(entry_hash_); |
870 // It is easy to incrementally compute the CRC from [0 .. |offset + buf_len|) | 882 // It is easy to incrementally compute the CRC from [0 .. |offset + buf_len|) |
871 // if |offset == 0| or we have already computed the CRC for [0 .. offset). | 883 // if |offset == 0| or we have already computed the CRC for [0 .. offset). |
872 // We rely on most write operations being sequential, start to end to compute | 884 // We rely on most write operations being sequential, start to end to compute |
873 // the crc of the data. When we write to an entry and close without having | 885 // the crc of the data. When we write to an entry and close without having |
874 // done a sequential write, we don't check the CRC on read. | 886 // done a sequential write, we don't check the CRC on read. |
875 if (offset == 0 || crc32s_end_offset_[stream_index] == offset) { | 887 if (offset == 0 || crc32s_end_offset_[stream_index] == offset) { |
876 uint32 initial_crc = (offset != 0) ? crc32s_[stream_index] | 888 uint32 initial_crc = (offset != 0) ? crc32s_[stream_index] |
(...skipping 14 matching lines...) Expand all Loading... | |
891 } else { | 903 } else { |
892 data_size_[stream_index] = std::max(offset + buf_len, | 904 data_size_[stream_index] = std::max(offset + buf_len, |
893 GetDataSize(stream_index)); | 905 GetDataSize(stream_index)); |
894 } | 906 } |
895 | 907 |
896 // Since we don't know the correct values for |last_used_| and | 908 // Since we don't know the correct values for |last_used_| and |
897 // |last_modified_| yet, we make this approximation. | 909 // |last_modified_| yet, we make this approximation. |
898 last_used_ = last_modified_ = base::Time::Now(); | 910 last_used_ = last_modified_ = base::Time::Now(); |
899 | 911 |
900 have_written_[stream_index] = true; | 912 have_written_[stream_index] = true; |
913 // Writing on stream 1 affects the placement of stream 0 in the file. | |
914 if (stream_index == 1) | |
915 have_written_[0] = true; | |
pasko
2013/09/17 14:17:36
this means we would loose the CRC on stream 0 afte
clamy
2013/09/18 16:17:14
Done.
| |
901 | 916 |
902 scoped_ptr<int> result(new int()); | 917 scoped_ptr<int> result(new int()); |
903 Closure task = base::Bind(&SimpleSynchronousEntry::WriteData, | 918 Closure task = base::Bind(&SimpleSynchronousEntry::WriteData, |
904 base::Unretained(synchronous_entry_), | 919 base::Unretained(synchronous_entry_), |
905 SimpleSynchronousEntry::EntryOperationData( | 920 SimpleSynchronousEntry::EntryOperationData( |
906 stream_index, offset, buf_len, truncate), | 921 stream_index, offset, buf_len, truncate), |
907 make_scoped_refptr(buf), | 922 make_scoped_refptr(buf), |
908 entry_stat.get(), | 923 entry_stat.get(), |
909 result.get()); | 924 result.get()); |
910 Closure reply = base::Bind(&SimpleEntryImpl::WriteOperationComplete, | 925 Closure reply = base::Bind(&SimpleEntryImpl::WriteOperationComplete, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
949 MakeUninitialized(); | 964 MakeUninitialized(); |
950 return; | 965 return; |
951 } | 966 } |
952 // If out_entry is NULL, it means we already called ReturnEntryToCaller from | 967 // If out_entry is NULL, it means we already called ReturnEntryToCaller from |
953 // the optimistic Create case. | 968 // the optimistic Create case. |
954 if (out_entry) | 969 if (out_entry) |
955 ReturnEntryToCaller(out_entry); | 970 ReturnEntryToCaller(out_entry); |
956 | 971 |
957 state_ = STATE_READY; | 972 state_ = STATE_READY; |
958 synchronous_entry_ = in_results->sync_entry; | 973 synchronous_entry_ = in_results->sync_entry; |
974 stream_0_data_ = in_results->stream_0_data; | |
975 // The crc was read in SimpleSynchronousEntry. | |
976 crc_check_state_[0] = CRC_CHECK_DONE; | |
pasko
2013/09/17 14:17:36
this should also update the crc32s_end_offset_[0],
clamy
2013/09/18 16:17:14
Done.
| |
959 if (key_.empty()) { | 977 if (key_.empty()) { |
960 SetKey(synchronous_entry_->key()); | 978 SetKey(synchronous_entry_->key()); |
961 } else { | 979 } else { |
962 // This should only be triggered when creating an entry. The key check in | 980 // This should only be triggered when creating an entry. The key check in |
963 // the open case is handled in SimpleBackendImpl. | 981 // the open case is handled in SimpleBackendImpl. |
964 DCHECK_EQ(key_, synchronous_entry_->key()); | 982 DCHECK_EQ(key_, synchronous_entry_->key()); |
965 } | 983 } |
966 UpdateDataFromEntryStat(in_results->entry_stat); | 984 UpdateDataFromEntryStat(in_results->entry_stat); |
967 SIMPLE_CACHE_UMA(TIMES, | 985 SIMPLE_CACHE_UMA(TIMES, |
968 "EntryCreationTime", cache_type_, | 986 "EntryCreationTime", cache_type_, |
(...skipping 27 matching lines...) Expand all Loading... | |
996 completion_callback, *result)); | 1014 completion_callback, *result)); |
997 } | 1015 } |
998 RunNextOperationIfNeeded(); | 1016 RunNextOperationIfNeeded(); |
999 } | 1017 } |
1000 | 1018 |
1001 void SimpleEntryImpl::ReadOperationComplete( | 1019 void SimpleEntryImpl::ReadOperationComplete( |
1002 int stream_index, | 1020 int stream_index, |
1003 int offset, | 1021 int offset, |
1004 const CompletionCallback& completion_callback, | 1022 const CompletionCallback& completion_callback, |
1005 scoped_ptr<uint32> read_crc32, | 1023 scoped_ptr<uint32> read_crc32, |
1006 scoped_ptr<base::Time> last_used, | 1024 scoped_ptr<SimpleEntryStat> entry_stat, |
1007 scoped_ptr<int> result) { | 1025 scoped_ptr<int> result) { |
1008 DCHECK(io_thread_checker_.CalledOnValidThread()); | 1026 DCHECK(io_thread_checker_.CalledOnValidThread()); |
1009 DCHECK(synchronous_entry_); | 1027 DCHECK(synchronous_entry_); |
1010 DCHECK_EQ(STATE_IO_PENDING, state_); | 1028 DCHECK_EQ(STATE_IO_PENDING, state_); |
1011 DCHECK(read_crc32); | 1029 DCHECK(read_crc32); |
1012 DCHECK(result); | 1030 DCHECK(result); |
1013 | 1031 |
1014 if (*result > 0 && | 1032 if (*result > 0 && |
1015 crc_check_state_[stream_index] == CRC_CHECK_NEVER_READ_AT_ALL) { | 1033 crc_check_state_[stream_index] == CRC_CHECK_NEVER_READ_AT_ALL) { |
1016 crc_check_state_[stream_index] = CRC_CHECK_NEVER_READ_TO_END; | 1034 crc_check_state_[stream_index] = CRC_CHECK_NEVER_READ_TO_END; |
(...skipping 15 matching lines...) Expand all Loading... | |
1032 // entry, one reader can be behind the other. In this case we compute | 1050 // entry, one reader can be behind the other. In this case we compute |
1033 // the crc as the most advanced reader progresses, and check it for | 1051 // the crc as the most advanced reader progresses, and check it for |
1034 // both readers as they read the last byte. | 1052 // both readers as they read the last byte. |
1035 | 1053 |
1036 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_CHECKSUM_BEGIN); | 1054 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_CHECKSUM_BEGIN); |
1037 | 1055 |
1038 scoped_ptr<int> new_result(new int()); | 1056 scoped_ptr<int> new_result(new int()); |
1039 Closure task = base::Bind(&SimpleSynchronousEntry::CheckEOFRecord, | 1057 Closure task = base::Bind(&SimpleSynchronousEntry::CheckEOFRecord, |
1040 base::Unretained(synchronous_entry_), | 1058 base::Unretained(synchronous_entry_), |
1041 stream_index, | 1059 stream_index, |
1042 data_size_[stream_index], | 1060 *entry_stat, |
1043 crc32s_[stream_index], | 1061 crc32s_[stream_index], |
1044 new_result.get()); | 1062 new_result.get()); |
1045 Closure reply = base::Bind(&SimpleEntryImpl::ChecksumOperationComplete, | 1063 Closure reply = base::Bind(&SimpleEntryImpl::ChecksumOperationComplete, |
1046 this, *result, stream_index, | 1064 this, *result, stream_index, |
1047 completion_callback, | 1065 completion_callback, |
1048 base::Passed(&new_result)); | 1066 base::Passed(&new_result)); |
1049 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply); | 1067 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply); |
1050 crc_check_state_[stream_index] = CRC_CHECK_DONE; | 1068 crc_check_state_[stream_index] = CRC_CHECK_DONE; |
1051 return; | 1069 return; |
1052 } | 1070 } |
1053 } | 1071 } |
1054 | 1072 |
1055 if (*result < 0) { | 1073 if (*result < 0) { |
1056 RecordReadResult(cache_type_, READ_RESULT_SYNC_READ_FAILURE); | 1074 RecordReadResult(cache_type_, READ_RESULT_SYNC_READ_FAILURE); |
1057 } else { | 1075 } else { |
1058 RecordReadResult(cache_type_, READ_RESULT_SUCCESS); | 1076 RecordReadResult(cache_type_, READ_RESULT_SUCCESS); |
1059 if (crc_check_state_[stream_index] == CRC_CHECK_NEVER_READ_TO_END && | 1077 if (crc_check_state_[stream_index] == CRC_CHECK_NEVER_READ_TO_END && |
1060 offset + *result == GetDataSize(stream_index)) { | 1078 offset + *result == GetDataSize(stream_index)) { |
1061 crc_check_state_[stream_index] = CRC_CHECK_NOT_DONE; | 1079 crc_check_state_[stream_index] = CRC_CHECK_NOT_DONE; |
1062 } | 1080 } |
1063 } | 1081 } |
1064 if (net_log_.IsLoggingAllEvents()) { | 1082 if (net_log_.IsLoggingAllEvents()) { |
1065 net_log_.AddEvent( | 1083 net_log_.AddEvent( |
1066 net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_READ_END, | 1084 net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_READ_END, |
1067 CreateNetLogReadWriteCompleteCallback(*result)); | 1085 CreateNetLogReadWriteCompleteCallback(*result)); |
1068 } | 1086 } |
1069 | 1087 |
1070 EntryOperationComplete( | 1088 EntryOperationComplete( |
1071 stream_index, | 1089 stream_index, completion_callback, *entry_stat, result.Pass()); |
1072 completion_callback, | |
1073 SimpleEntryStat(*last_used, last_modified_, data_size_), | |
1074 result.Pass()); | |
1075 } | 1090 } |
1076 | 1091 |
1077 void SimpleEntryImpl::WriteOperationComplete( | 1092 void SimpleEntryImpl::WriteOperationComplete( |
1078 int stream_index, | 1093 int stream_index, |
1079 const CompletionCallback& completion_callback, | 1094 const CompletionCallback& completion_callback, |
1080 scoped_ptr<SimpleEntryStat> entry_stat, | 1095 scoped_ptr<SimpleEntryStat> entry_stat, |
1081 scoped_ptr<int> result) { | 1096 scoped_ptr<int> result) { |
1082 if (*result >= 0) | 1097 if (*result >= 0) |
1083 RecordWriteResult(cache_type_, WRITE_RESULT_SUCCESS); | 1098 RecordWriteResult(cache_type_, WRITE_RESULT_SUCCESS); |
1084 else | 1099 else |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1153 } | 1168 } |
1154 | 1169 |
1155 void SimpleEntryImpl::UpdateDataFromEntryStat( | 1170 void SimpleEntryImpl::UpdateDataFromEntryStat( |
1156 const SimpleEntryStat& entry_stat) { | 1171 const SimpleEntryStat& entry_stat) { |
1157 DCHECK(io_thread_checker_.CalledOnValidThread()); | 1172 DCHECK(io_thread_checker_.CalledOnValidThread()); |
1158 DCHECK(synchronous_entry_); | 1173 DCHECK(synchronous_entry_); |
1159 DCHECK_EQ(STATE_READY, state_); | 1174 DCHECK_EQ(STATE_READY, state_); |
1160 | 1175 |
1161 last_used_ = entry_stat.last_used; | 1176 last_used_ = entry_stat.last_used; |
1162 last_modified_ = entry_stat.last_modified; | 1177 last_modified_ = entry_stat.last_modified; |
1163 for (int i = 0; i < kSimpleEntryFileCount; ++i) { | 1178 for (int i = 0; i < kSimpleEntryStreamCount; ++i) { |
1164 data_size_[i] = entry_stat.data_size[i]; | 1179 data_size_[i] = entry_stat.data_size[i]; |
1165 } | 1180 } |
1166 if (!doomed_ && backend_.get()) | 1181 if (!doomed_ && backend_.get()) |
1167 backend_->index()->UpdateEntrySize(entry_hash_, GetDiskUsage()); | 1182 backend_->index()->UpdateEntrySize(entry_hash_, GetDiskUsage()); |
1168 } | 1183 } |
1169 | 1184 |
1170 int64 SimpleEntryImpl::GetDiskUsage() const { | 1185 int64 SimpleEntryImpl::GetDiskUsage() const { |
1171 int64 file_size = 0; | 1186 int64 file_size = 0; |
1172 for (int i = 0; i < kSimpleEntryFileCount; ++i) { | 1187 for (int i = 0; i < kSimpleEntryStreamCount; ++i) { |
1173 file_size += | 1188 file_size += |
1174 simple_util::GetFileSizeFromKeyAndDataSize(key_, data_size_[i]); | 1189 simple_util::GetFileSizeFromKeyAndDataSize(key_, data_size_[i]); |
1175 } | 1190 } |
1176 return file_size; | 1191 return file_size; |
1177 } | 1192 } |
1178 | 1193 |
1179 void SimpleEntryImpl::RecordReadIsParallelizable( | 1194 void SimpleEntryImpl::RecordReadIsParallelizable( |
1180 const SimpleEntryOperation& operation) const { | 1195 const SimpleEntryOperation& operation) const { |
1181 if (!executing_operation_) | 1196 if (!executing_operation_) |
1182 return; | 1197 return; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1240 } else { | 1255 } else { |
1241 type = conflicting ? WRITE_FOLLOWS_CONFLICTING_WRITE | 1256 type = conflicting ? WRITE_FOLLOWS_CONFLICTING_WRITE |
1242 : WRITE_FOLLOWS_NON_CONFLICTING_WRITE; | 1257 : WRITE_FOLLOWS_NON_CONFLICTING_WRITE; |
1243 } | 1258 } |
1244 } | 1259 } |
1245 SIMPLE_CACHE_UMA(ENUMERATION, | 1260 SIMPLE_CACHE_UMA(ENUMERATION, |
1246 "WriteDependencyType", cache_type_, | 1261 "WriteDependencyType", cache_type_, |
1247 type, WRITE_DEPENDENCY_TYPE_MAX); | 1262 type, WRITE_DEPENDENCY_TYPE_MAX); |
1248 } | 1263 } |
1249 | 1264 |
1265 int SimpleEntryImpl::ReadStream0Data(net::IOBuffer* buf, | |
1266 int offset, | |
1267 int buf_len) { | |
1268 int read_size = std::min(data_size_[0] - offset, buf_len); | |
1269 if (read_size < 0) { | |
1270 RecordReadResult(cache_type_, READ_RESULT_SYNC_READ_FAILURE); | |
1271 return 0; | |
1272 } | |
1273 memcpy(buf->data(), stream_0_data_->data() + offset, read_size); | |
1274 UpdateDataFromEntryStat( | |
1275 SimpleEntryStat(base::Time::Now(), last_modified_, data_size_)); | |
1276 RecordReadResult(cache_type_, READ_RESULT_SUCCESS); | |
1277 return read_size; | |
1278 } | |
1279 | |
1280 int SimpleEntryImpl::CopyStream0Data(net::IOBuffer* buf, | |
1281 int offset, | |
1282 int buf_len, | |
1283 bool truncate) { | |
1284 // Currently, stream 0 is only used for HTTP headers, and always writes them | |
1285 // with a single, truncating write. Detect these writes and record the size | |
1286 // and size changes of the headers. Also, supports writes to stream 0 that | |
pasko
2013/09/17 14:17:36
nit: "the size and size changes"?
I do not see th
clamy
2013/09/18 16:17:14
Done.
| |
1287 // violate those assumptions. All other clients of the Simple Cache are | |
1288 // encouraged to use stream 1. | |
1289 if (!stream_0_data_) | |
1290 stream_0_data_ = new net::GrowableIOBuffer(); | |
1291 have_written_[0] = true; | |
1292 int data_size = data_size_[0]; | |
pasko
2013/09/17 14:17:36
In this file we tried to remain consistent on alwa
clamy
2013/09/18 16:17:14
Done.
| |
1293 if (offset == 0 && truncate) { | |
1294 RecordHeaderSizeChange(cache_type_, data_size, buf_len); | |
1295 stream_0_data_->SetCapacity(buf_len); | |
1296 memcpy(stream_0_data_->data(), buf->data(), buf_len); | |
1297 data_size_[0] = buf_len; | |
1298 } else { | |
1299 RecordUnexpectedStream0Write(cache_type_); | |
1300 const int buffer_size = | |
1301 truncate ? offset + buf_len : std::max(offset + buf_len, data_size); | |
1302 stream_0_data_->SetCapacity(buffer_size); | |
1303 // If |stream_0_data_| was extended. the extension until offset need to be | |
1304 // zeroed. | |
1305 const int fill_size = offset <= data_size ? 0 : offset - data_size; | |
1306 if (fill_size > 0) | |
1307 memset(stream_0_data_->data() + data_size, 0, fill_size); | |
1308 if (buf) | |
1309 memcpy(stream_0_data_->data() + offset, buf->data(), buf_len); | |
1310 data_size_[0] = buffer_size; | |
1311 } | |
1312 base::Time modification_time = base::Time::Now(); | |
1313 UpdateDataFromEntryStat( | |
1314 SimpleEntryStat(modification_time, modification_time, data_size_)); | |
1315 if (stream_0_data_) { | |
1316 crc32s_[0] = crc32(crc32(0L, Z_NULL, 0), | |
1317 reinterpret_cast<const Bytef*>(stream_0_data_->data()), | |
1318 data_size_[0]); | |
1319 } else { | |
1320 crc32s_[0] = crc32(0L, Z_NULL, 0); | |
1321 } | |
1322 RecordWriteResult(cache_type_, WRITE_RESULT_SUCCESS); | |
1323 return buf_len; | |
1324 } | |
1325 | |
1250 } // namespace disk_cache | 1326 } // namespace disk_cache |
OLD | NEW |