Chromium Code Reviews| 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 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 325 int buf_len, | 325 int buf_len, |
| 326 const CompletionCallback& callback) { | 326 const CompletionCallback& callback) { |
| 327 DCHECK(io_thread_checker_.CalledOnValidThread()); | 327 DCHECK(io_thread_checker_.CalledOnValidThread()); |
| 328 | 328 |
| 329 if (net_log_.IsLoggingAllEvents()) { | 329 if (net_log_.IsLoggingAllEvents()) { |
| 330 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_READ_CALL, | 330 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_READ_CALL, |
| 331 CreateNetLogReadWriteDataCallback(stream_index, offset, buf_len, | 331 CreateNetLogReadWriteDataCallback(stream_index, offset, buf_len, |
| 332 false)); | 332 false)); |
| 333 } | 333 } |
| 334 | 334 |
| 335 if (stream_index < 0 || stream_index >= kSimpleEntryFileCount || | 335 if (stream_index < 0 || stream_index >= kSimpleEntryStreamCount || |
| 336 buf_len < 0) { | 336 buf_len < 0) { |
| 337 if (net_log_.IsLoggingAllEvents()) { | 337 if (net_log_.IsLoggingAllEvents()) { |
| 338 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_READ_END, | 338 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_READ_END, |
| 339 CreateNetLogReadWriteCompleteCallback(net::ERR_INVALID_ARGUMENT)); | 339 CreateNetLogReadWriteCompleteCallback(net::ERR_INVALID_ARGUMENT)); |
| 340 } | 340 } |
| 341 | 341 |
| 342 RecordReadResult(cache_type_, READ_RESULT_INVALID_ARGUMENT); | 342 RecordReadResult(cache_type_, READ_RESULT_INVALID_ARGUMENT); |
| 343 return net::ERR_INVALID_ARGUMENT; | 343 return net::ERR_INVALID_ARGUMENT; |
| 344 } | 344 } |
| 345 if (pending_operations_.empty() && (offset >= GetDataSize(stream_index) || | 345 if (pending_operations_.empty() && (offset >= GetDataSize(stream_index) || |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 371 bool truncate) { | 371 bool truncate) { |
| 372 DCHECK(io_thread_checker_.CalledOnValidThread()); | 372 DCHECK(io_thread_checker_.CalledOnValidThread()); |
| 373 | 373 |
| 374 if (net_log_.IsLoggingAllEvents()) { | 374 if (net_log_.IsLoggingAllEvents()) { |
| 375 net_log_.AddEvent( | 375 net_log_.AddEvent( |
| 376 net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_WRITE_CALL, | 376 net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_WRITE_CALL, |
| 377 CreateNetLogReadWriteDataCallback(stream_index, offset, buf_len, | 377 CreateNetLogReadWriteDataCallback(stream_index, offset, buf_len, |
| 378 truncate)); | 378 truncate)); |
| 379 } | 379 } |
| 380 | 380 |
| 381 if (stream_index < 0 || stream_index >= kSimpleEntryFileCount || offset < 0 || | 381 if (stream_index < 0 || stream_index >= kSimpleEntryStreamCount || |
| 382 buf_len < 0) { | 382 offset < 0 || buf_len < 0) { |
| 383 if (net_log_.IsLoggingAllEvents()) { | 383 if (net_log_.IsLoggingAllEvents()) { |
| 384 net_log_.AddEvent( | 384 net_log_.AddEvent( |
| 385 net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_WRITE_END, | 385 net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_WRITE_END, |
| 386 CreateNetLogReadWriteCompleteCallback(net::ERR_INVALID_ARGUMENT)); | 386 CreateNetLogReadWriteCompleteCallback(net::ERR_INVALID_ARGUMENT)); |
| 387 } | 387 } |
| 388 RecordWriteResult(cache_type_, WRITE_RESULT_INVALID_ARGUMENT); | 388 RecordWriteResult(cache_type_, WRITE_RESULT_INVALID_ARGUMENT); |
| 389 return net::ERR_INVALID_ARGUMENT; | 389 return net::ERR_INVALID_ARGUMENT; |
| 390 } | 390 } |
| 391 if (backend_.get() && offset + buf_len > backend_->GetMaxFileSize()) { | 391 if (backend_.get() && offset + buf_len > backend_->GetMaxFileSize()) { |
| 392 if (net_log_.IsLoggingAllEvents()) { | 392 if (net_log_.IsLoggingAllEvents()) { |
| 393 net_log_.AddEvent( | 393 net_log_.AddEvent( |
| 394 net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_WRITE_END, | 394 net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_WRITE_END, |
| 395 CreateNetLogReadWriteCompleteCallback(net::ERR_FAILED)); | 395 CreateNetLogReadWriteCompleteCallback(net::ERR_FAILED)); |
| 396 } | 396 } |
| 397 RecordWriteResult(cache_type_, WRITE_RESULT_OVER_MAX_SIZE); | 397 RecordWriteResult(cache_type_, WRITE_RESULT_OVER_MAX_SIZE); |
| 398 return net::ERR_FAILED; | 398 return net::ERR_FAILED; |
| 399 } | 399 } |
| 400 ScopedOperationRunner operation_runner(this); | 400 ScopedOperationRunner operation_runner(this); |
| 401 | 401 |
| 402 // Currently, Simple Cache is only used for HTTP, which stores the headers in | |
| 403 // stream 0 and always writes them with a single, truncating write. Detect | |
| 404 // these writes and record the size and size changes of the headers. Also, | |
| 405 // note writes to stream 0 that violate those assumptions. | |
| 406 if (stream_index == 0) { | |
| 407 if (offset == 0 && truncate) | |
| 408 RecordHeaderSizeChange(cache_type_, data_size_[0], buf_len); | |
| 409 else | |
| 410 RecordUnexpectedStream0Write(cache_type_); | |
| 411 } | |
| 412 | |
| 413 // We can only do optimistic Write if there is no pending operations, so | 402 // We can only do optimistic Write if there is no pending operations, so |
| 414 // that we are sure that the next call to RunNextOperationIfNeeded will | 403 // that we are sure that the next call to RunNextOperationIfNeeded will |
| 415 // actually run the write operation that sets the stream size. It also | 404 // actually run the write operation that sets the stream size. It also |
| 416 // prevents from previous possibly-conflicting writes that could be stacked | 405 // prevents from previous possibly-conflicting writes that could be stacked |
| 417 // in the |pending_operations_|. We could optimize this for when we have | 406 // in the |pending_operations_|. We could optimize this for when we have |
| 418 // only read operations enqueued. | 407 // only read operations enqueued. |
| 419 const bool optimistic = | 408 const bool optimistic = |
| 420 (use_optimistic_operations_ && state_ == STATE_READY && | 409 (use_optimistic_operations_ && state_ == STATE_READY && |
| 421 pending_operations_.size() == 0); | 410 pending_operations_.size() == 0); |
| 422 CompletionCallback op_callback; | 411 CompletionCallback op_callback; |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 670 DCHECK_EQ(STATE_UNINITIALIZED, state_); | 659 DCHECK_EQ(STATE_UNINITIALIZED, state_); |
| 671 DCHECK(!synchronous_entry_); | 660 DCHECK(!synchronous_entry_); |
| 672 | 661 |
| 673 state_ = STATE_IO_PENDING; | 662 state_ = STATE_IO_PENDING; |
| 674 | 663 |
| 675 // Since we don't know the correct values for |last_used_| and | 664 // Since we don't know the correct values for |last_used_| and |
| 676 // |last_modified_| yet, we make this approximation. | 665 // |last_modified_| yet, we make this approximation. |
| 677 last_used_ = last_modified_ = base::Time::Now(); | 666 last_used_ = last_modified_ = base::Time::Now(); |
| 678 | 667 |
| 679 // If creation succeeds, we should mark all streams to be saved on close. | 668 // If creation succeeds, we should mark all streams to be saved on close. |
| 680 for (int i = 0; i < kSimpleEntryFileCount; ++i) | 669 for (int i = 0; i < kSimpleEntryStreamCount; ++i) |
| 681 have_written_[i] = true; | 670 have_written_[i] = true; |
| 682 | 671 |
| 683 const base::TimeTicks start_time = base::TimeTicks::Now(); | 672 const base::TimeTicks start_time = base::TimeTicks::Now(); |
| 684 scoped_ptr<SimpleEntryCreationResults> results( | 673 scoped_ptr<SimpleEntryCreationResults> results( |
| 685 new SimpleEntryCreationResults( | 674 new SimpleEntryCreationResults( |
| 686 SimpleEntryStat(last_used_, last_modified_, data_size_))); | 675 SimpleEntryStat(last_used_, last_modified_, data_size_))); |
| 687 Closure task = base::Bind(&SimpleSynchronousEntry::CreateEntry, | 676 Closure task = base::Bind(&SimpleSynchronousEntry::CreateEntry, |
| 688 cache_type_, | 677 cache_type_, |
| 689 path_, | 678 path_, |
| 690 key_, | 679 key_, |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 705 DCHECK(io_thread_checker_.CalledOnValidThread()); | 694 DCHECK(io_thread_checker_.CalledOnValidThread()); |
| 706 typedef SimpleSynchronousEntry::CRCRecord CRCRecord; | 695 typedef SimpleSynchronousEntry::CRCRecord CRCRecord; |
| 707 scoped_ptr<std::vector<CRCRecord> > | 696 scoped_ptr<std::vector<CRCRecord> > |
| 708 crc32s_to_write(new std::vector<CRCRecord>()); | 697 crc32s_to_write(new std::vector<CRCRecord>()); |
| 709 | 698 |
| 710 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_CLOSE_BEGIN); | 699 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_CLOSE_BEGIN); |
| 711 | 700 |
| 712 if (state_ == STATE_READY) { | 701 if (state_ == STATE_READY) { |
| 713 DCHECK(synchronous_entry_); | 702 DCHECK(synchronous_entry_); |
| 714 state_ = STATE_IO_PENDING; | 703 state_ = STATE_IO_PENDING; |
| 715 for (int i = 0; i < kSimpleEntryFileCount; ++i) { | 704 for (int i = 0; i < kSimpleEntryStreamCount; ++i) { |
| 716 if (have_written_[i]) { | 705 if (have_written_[i]) { |
| 717 if (GetDataSize(i) == crc32s_end_offset_[i]) { | 706 if (GetDataSize(i) == crc32s_end_offset_[i]) { |
| 718 int32 crc = GetDataSize(i) == 0 ? crc32(0, Z_NULL, 0) : crc32s_[i]; | 707 int32 crc = GetDataSize(i) == 0 ? crc32(0, Z_NULL, 0) : crc32s_[i]; |
| 719 crc32s_to_write->push_back(CRCRecord(i, true, crc)); | 708 crc32s_to_write->push_back(CRCRecord(i, true, crc)); |
| 720 } else { | 709 } else { |
| 721 crc32s_to_write->push_back(CRCRecord(i, false, 0)); | 710 crc32s_to_write->push_back(CRCRecord(i, false, 0)); |
| 722 } | 711 } |
| 723 } | 712 } |
| 724 } | 713 } |
| 725 } else { | 714 } else { |
| 726 DCHECK(STATE_UNINITIALIZED == state_ || STATE_FAILURE == state_); | 715 DCHECK(STATE_UNINITIALIZED == state_ || STATE_FAILURE == state_); |
| 727 } | 716 } |
| 728 | 717 |
| 729 if (synchronous_entry_) { | 718 if (synchronous_entry_) { |
| 730 Closure task = | 719 Closure task = |
| 731 base::Bind(&SimpleSynchronousEntry::Close, | 720 base::Bind(&SimpleSynchronousEntry::Close, |
| 732 base::Unretained(synchronous_entry_), | 721 base::Unretained(synchronous_entry_), |
| 733 SimpleEntryStat(last_used_, last_modified_, data_size_), | 722 SimpleEntryStat(last_used_, last_modified_, data_size_), |
| 734 base::Passed(&crc32s_to_write)); | 723 base::Passed(&crc32s_to_write), |
| 724 stream_0_data_); | |
| 735 Closure reply = base::Bind(&SimpleEntryImpl::CloseOperationComplete, this); | 725 Closure reply = base::Bind(&SimpleEntryImpl::CloseOperationComplete, this); |
| 736 synchronous_entry_ = NULL; | 726 synchronous_entry_ = NULL; |
| 737 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply); | 727 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply); |
| 738 | 728 |
| 739 for (int i = 0; i < kSimpleEntryFileCount; ++i) { | 729 for (int i = 0; i < kSimpleEntryStreamCount; ++i) { |
| 740 if (!have_written_[i]) { | 730 if (!have_written_[i]) { |
| 741 SIMPLE_CACHE_UMA(ENUMERATION, | 731 SIMPLE_CACHE_UMA(ENUMERATION, |
| 742 "CheckCRCResult", cache_type_, | 732 "CheckCRCResult", cache_type_, |
| 743 crc_check_state_[i], CRC_CHECK_MAX); | 733 crc_check_state_[i], CRC_CHECK_MAX); |
| 744 } | 734 } |
| 745 } | 735 } |
| 746 } else { | 736 } else { |
| 747 CloseOperationComplete(); | 737 CloseOperationComplete(); |
| 748 } | 738 } |
| 749 } | 739 } |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 780 if (offset >= GetDataSize(stream_index) || offset < 0 || !buf_len) { | 770 if (offset >= GetDataSize(stream_index) || offset < 0 || !buf_len) { |
| 781 RecordReadResult(cache_type_, READ_RESULT_FAST_EMPTY_RETURN); | 771 RecordReadResult(cache_type_, READ_RESULT_FAST_EMPTY_RETURN); |
| 782 // If there is nothing to read, we bail out before setting state_ to | 772 // If there is nothing to read, we bail out before setting state_ to |
| 783 // STATE_IO_PENDING. | 773 // STATE_IO_PENDING. |
| 784 if (!callback.is_null()) | 774 if (!callback.is_null()) |
| 785 MessageLoopProxy::current()->PostTask(FROM_HERE, base::Bind( | 775 MessageLoopProxy::current()->PostTask(FROM_HERE, base::Bind( |
| 786 callback, 0)); | 776 callback, 0)); |
| 787 return; | 777 return; |
| 788 } | 778 } |
| 789 | 779 |
| 780 // Since stream 0 data is kept in memory, it is read immediately. | |
| 781 if (stream_index == 0) { | |
| 782 int ret_value = ReadStream0Data(buf, offset, buf_len); | |
| 783 if (!callback.is_null()) { | |
| 784 MessageLoopProxy::current() | |
| 785 ->PostTask(FROM_HERE, base::Bind(callback, ret_value)); | |
| 786 } | |
| 787 return; | |
| 788 } | |
| 789 | |
| 790 buf_len = std::min(buf_len, GetDataSize(stream_index) - offset); | 790 buf_len = std::min(buf_len, GetDataSize(stream_index) - offset); |
| 791 | 791 |
| 792 state_ = STATE_IO_PENDING; | 792 state_ = STATE_IO_PENDING; |
| 793 if (backend_.get()) | 793 if (backend_.get()) |
| 794 backend_->index()->UseIfExists(entry_hash_); | 794 backend_->index()->UseIfExists(entry_hash_); |
| 795 | 795 |
| 796 scoped_ptr<uint32> read_crc32(new uint32()); | 796 scoped_ptr<uint32> read_crc32(new uint32()); |
| 797 scoped_ptr<int> result(new int()); | 797 scoped_ptr<int> result(new int()); |
| 798 scoped_ptr<base::Time> last_used(new base::Time()); | 798 scoped_ptr<SimpleEntryStat> entry_stat( |
| 799 new SimpleEntryStat(last_used_, last_modified_, data_size_)); | |
| 799 Closure task = base::Bind( | 800 Closure task = base::Bind( |
| 800 &SimpleSynchronousEntry::ReadData, | 801 &SimpleSynchronousEntry::ReadData, |
| 801 base::Unretained(synchronous_entry_), | 802 base::Unretained(synchronous_entry_), |
| 802 SimpleSynchronousEntry::EntryOperationData(stream_index, offset, buf_len), | 803 SimpleSynchronousEntry::EntryOperationData(stream_index, offset, buf_len), |
| 803 make_scoped_refptr(buf), | 804 make_scoped_refptr(buf), |
| 804 read_crc32.get(), | 805 read_crc32.get(), |
| 805 last_used.get(), | 806 entry_stat.get(), |
| 806 result.get()); | 807 result.get()); |
| 807 Closure reply = base::Bind(&SimpleEntryImpl::ReadOperationComplete, | 808 Closure reply = base::Bind(&SimpleEntryImpl::ReadOperationComplete, |
| 808 this, | 809 this, |
| 809 stream_index, | 810 stream_index, |
| 810 offset, | 811 offset, |
| 811 callback, | 812 callback, |
| 812 base::Passed(&read_crc32), | 813 base::Passed(&read_crc32), |
| 813 base::Passed(&last_used), | 814 base::Passed(&entry_stat), |
| 814 base::Passed(&result)); | 815 base::Passed(&result)); |
| 815 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply); | 816 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply); |
| 816 } | 817 } |
| 817 | 818 |
| 818 void SimpleEntryImpl::WriteDataInternal(int stream_index, | 819 void SimpleEntryImpl::WriteDataInternal(int stream_index, |
| 819 int offset, | 820 int offset, |
| 820 net::IOBuffer* buf, | 821 net::IOBuffer* buf, |
| 821 int buf_len, | 822 int buf_len, |
| 822 const CompletionCallback& callback, | 823 const CompletionCallback& callback, |
| 823 bool truncate) { | 824 bool truncate) { |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 842 // We need to posttask so that we don't go in a loop when we call the | 843 // We need to posttask so that we don't go in a loop when we call the |
| 843 // callback directly. | 844 // callback directly. |
| 844 MessageLoopProxy::current()->PostTask(FROM_HERE, base::Bind( | 845 MessageLoopProxy::current()->PostTask(FROM_HERE, base::Bind( |
| 845 callback, net::ERR_FAILED)); | 846 callback, net::ERR_FAILED)); |
| 846 } | 847 } |
| 847 // |this| may be destroyed after return here. | 848 // |this| may be destroyed after return here. |
| 848 return; | 849 return; |
| 849 } | 850 } |
| 850 | 851 |
| 851 DCHECK_EQ(STATE_READY, state_); | 852 DCHECK_EQ(STATE_READY, state_); |
| 853 // Since stream 0 data is kept in memory, it will be written immediatly. | |
| 854 if (stream_index == 0) { | |
| 855 int ret_value = CopyStream0Data(buf, offset, buf_len, truncate); | |
| 856 if (!callback.is_null()) { | |
| 857 // Postask prevents creating a loop when calling the callback directly. | |
|
Deprecated (see juliatuttle)
2013/09/12 22:05:56
nit: PostTask
clamy
2013/09/16 15:01:17
Done.
| |
| 858 MessageLoopProxy::current() | |
| 859 ->PostTask(FROM_HERE, base::Bind(callback, ret_value)); | |
| 860 } | |
| 861 return; | |
| 862 } | |
| 863 | |
| 852 state_ = STATE_IO_PENDING; | 864 state_ = STATE_IO_PENDING; |
| 853 if (backend_.get()) | 865 if (backend_.get()) |
| 854 backend_->index()->UseIfExists(entry_hash_); | 866 backend_->index()->UseIfExists(entry_hash_); |
| 855 // It is easy to incrementally compute the CRC from [0 .. |offset + buf_len|) | 867 // 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). | 868 // 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 | 869 // 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 | 870 // 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. | 871 // done a sequential write, we don't check the CRC on read. |
| 860 if (offset == 0 || crc32s_end_offset_[stream_index] == offset) { | 872 if (offset == 0 || crc32s_end_offset_[stream_index] == offset) { |
| 861 uint32 initial_crc = (offset != 0) ? crc32s_[stream_index] | 873 uint32 initial_crc = (offset != 0) ? crc32s_[stream_index] |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 876 } else { | 888 } else { |
| 877 data_size_[stream_index] = std::max(offset + buf_len, | 889 data_size_[stream_index] = std::max(offset + buf_len, |
| 878 GetDataSize(stream_index)); | 890 GetDataSize(stream_index)); |
| 879 } | 891 } |
| 880 | 892 |
| 881 // Since we don't know the correct values for |last_used_| and | 893 // Since we don't know the correct values for |last_used_| and |
| 882 // |last_modified_| yet, we make this approximation. | 894 // |last_modified_| yet, we make this approximation. |
| 883 last_used_ = last_modified_ = base::Time::Now(); | 895 last_used_ = last_modified_ = base::Time::Now(); |
| 884 | 896 |
| 885 have_written_[stream_index] = true; | 897 have_written_[stream_index] = true; |
| 898 // Writing on stream 1 affects the placement of stream 0 in the file. | |
| 899 if (stream_index == 1) | |
| 900 have_written_[0] = true; | |
| 886 | 901 |
| 887 scoped_ptr<int> result(new int()); | 902 scoped_ptr<int> result(new int()); |
| 888 Closure task = base::Bind(&SimpleSynchronousEntry::WriteData, | 903 Closure task = base::Bind(&SimpleSynchronousEntry::WriteData, |
| 889 base::Unretained(synchronous_entry_), | 904 base::Unretained(synchronous_entry_), |
| 890 SimpleSynchronousEntry::EntryOperationData( | 905 SimpleSynchronousEntry::EntryOperationData( |
| 891 stream_index, offset, buf_len, truncate), | 906 stream_index, offset, buf_len, truncate), |
| 892 make_scoped_refptr(buf), | 907 make_scoped_refptr(buf), |
| 893 entry_stat.get(), | 908 entry_stat.get(), |
| 894 result.get()); | 909 result.get()); |
| 895 Closure reply = base::Bind(&SimpleEntryImpl::WriteOperationComplete, | 910 Closure reply = base::Bind(&SimpleEntryImpl::WriteOperationComplete, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 936 MakeUninitialized(); | 951 MakeUninitialized(); |
| 937 return; | 952 return; |
| 938 } | 953 } |
| 939 // If out_entry is NULL, it means we already called ReturnEntryToCaller from | 954 // If out_entry is NULL, it means we already called ReturnEntryToCaller from |
| 940 // the optimistic Create case. | 955 // the optimistic Create case. |
| 941 if (out_entry) | 956 if (out_entry) |
| 942 ReturnEntryToCaller(out_entry); | 957 ReturnEntryToCaller(out_entry); |
| 943 | 958 |
| 944 state_ = STATE_READY; | 959 state_ = STATE_READY; |
| 945 synchronous_entry_ = in_results->sync_entry; | 960 synchronous_entry_ = in_results->sync_entry; |
| 961 stream_0_data_ = in_results->stream_0_data; | |
| 962 // The crc was read in SimpleSynchronousEntry. | |
| 963 crc_check_state_[0] = CRC_CHECK_DONE; | |
| 946 if (key_.empty()) { | 964 if (key_.empty()) { |
| 947 SetKey(synchronous_entry_->key()); | 965 SetKey(synchronous_entry_->key()); |
| 948 } else { | 966 } else { |
| 949 // This should only be triggered when creating an entry. The key check in | 967 // This should only be triggered when creating an entry. The key check in |
| 950 // the open case is handled in SimpleBackendImpl. | 968 // the open case is handled in SimpleBackendImpl. |
| 951 DCHECK_EQ(key_, synchronous_entry_->key()); | 969 DCHECK_EQ(key_, synchronous_entry_->key()); |
| 952 } | 970 } |
| 953 UpdateDataFromEntryStat(in_results->entry_stat); | 971 UpdateDataFromEntryStat(in_results->entry_stat); |
| 954 SIMPLE_CACHE_UMA(TIMES, | 972 SIMPLE_CACHE_UMA(TIMES, |
| 955 "EntryCreationTime", cache_type_, | 973 "EntryCreationTime", cache_type_, |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 986 completion_callback, *result)); | 1004 completion_callback, *result)); |
| 987 } | 1005 } |
| 988 RunNextOperationIfNeeded(); | 1006 RunNextOperationIfNeeded(); |
| 989 } | 1007 } |
| 990 | 1008 |
| 991 void SimpleEntryImpl::ReadOperationComplete( | 1009 void SimpleEntryImpl::ReadOperationComplete( |
| 992 int stream_index, | 1010 int stream_index, |
| 993 int offset, | 1011 int offset, |
| 994 const CompletionCallback& completion_callback, | 1012 const CompletionCallback& completion_callback, |
| 995 scoped_ptr<uint32> read_crc32, | 1013 scoped_ptr<uint32> read_crc32, |
| 996 scoped_ptr<base::Time> last_used, | 1014 scoped_ptr<SimpleEntryStat> entry_stat, |
| 997 scoped_ptr<int> result) { | 1015 scoped_ptr<int> result) { |
| 998 DCHECK(io_thread_checker_.CalledOnValidThread()); | 1016 DCHECK(io_thread_checker_.CalledOnValidThread()); |
| 999 DCHECK(synchronous_entry_); | 1017 DCHECK(synchronous_entry_); |
| 1000 DCHECK_EQ(STATE_IO_PENDING, state_); | 1018 DCHECK_EQ(STATE_IO_PENDING, state_); |
| 1001 DCHECK(read_crc32); | 1019 DCHECK(read_crc32); |
| 1002 DCHECK(result); | 1020 DCHECK(result); |
| 1003 | 1021 |
| 1004 if (*result > 0 && | 1022 if (*result > 0 && |
| 1005 crc_check_state_[stream_index] == CRC_CHECK_NEVER_READ_AT_ALL) { | 1023 crc_check_state_[stream_index] == CRC_CHECK_NEVER_READ_AT_ALL) { |
| 1006 crc_check_state_[stream_index] = CRC_CHECK_NEVER_READ_TO_END; | 1024 crc_check_state_[stream_index] = CRC_CHECK_NEVER_READ_TO_END; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1022 // entry, one reader can be behind the other. In this case we compute | 1040 // entry, one reader can be behind the other. In this case we compute |
| 1023 // the crc as the most advanced reader progresses, and check it for | 1041 // the crc as the most advanced reader progresses, and check it for |
| 1024 // both readers as they read the last byte. | 1042 // both readers as they read the last byte. |
| 1025 | 1043 |
| 1026 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_CHECKSUM_BEGIN); | 1044 net_log_.AddEvent(net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_CHECKSUM_BEGIN); |
| 1027 | 1045 |
| 1028 scoped_ptr<int> new_result(new int()); | 1046 scoped_ptr<int> new_result(new int()); |
| 1029 Closure task = base::Bind(&SimpleSynchronousEntry::CheckEOFRecord, | 1047 Closure task = base::Bind(&SimpleSynchronousEntry::CheckEOFRecord, |
| 1030 base::Unretained(synchronous_entry_), | 1048 base::Unretained(synchronous_entry_), |
| 1031 stream_index, | 1049 stream_index, |
| 1032 data_size_[stream_index], | 1050 data_size_, |
| 1033 crc32s_[stream_index], | 1051 crc32s_[stream_index], |
| 1034 new_result.get()); | 1052 new_result.get()); |
| 1035 Closure reply = base::Bind(&SimpleEntryImpl::ChecksumOperationComplete, | 1053 Closure reply = base::Bind(&SimpleEntryImpl::ChecksumOperationComplete, |
| 1036 this, *result, stream_index, | 1054 this, *result, stream_index, |
| 1037 completion_callback, | 1055 completion_callback, |
| 1038 base::Passed(&new_result)); | 1056 base::Passed(&new_result)); |
| 1039 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply); | 1057 worker_pool_->PostTaskAndReply(FROM_HERE, task, reply); |
| 1040 crc_check_state_[stream_index] = CRC_CHECK_DONE; | 1058 crc_check_state_[stream_index] = CRC_CHECK_DONE; |
| 1041 return; | 1059 return; |
| 1042 } | 1060 } |
| 1043 } | 1061 } |
| 1044 | 1062 |
| 1045 if (*result < 0) { | 1063 if (*result < 0) { |
| 1046 RecordReadResult(cache_type_, READ_RESULT_SYNC_READ_FAILURE); | 1064 RecordReadResult(cache_type_, READ_RESULT_SYNC_READ_FAILURE); |
| 1047 } else { | 1065 } else { |
| 1048 RecordReadResult(cache_type_, READ_RESULT_SUCCESS); | 1066 RecordReadResult(cache_type_, READ_RESULT_SUCCESS); |
| 1049 if (crc_check_state_[stream_index] == CRC_CHECK_NEVER_READ_TO_END && | 1067 if (crc_check_state_[stream_index] == CRC_CHECK_NEVER_READ_TO_END && |
| 1050 offset + *result == GetDataSize(stream_index)) { | 1068 offset + *result == GetDataSize(stream_index)) { |
| 1051 crc_check_state_[stream_index] = CRC_CHECK_NOT_DONE; | 1069 crc_check_state_[stream_index] = CRC_CHECK_NOT_DONE; |
| 1052 } | 1070 } |
| 1053 } | 1071 } |
| 1054 if (net_log_.IsLoggingAllEvents()) { | 1072 if (net_log_.IsLoggingAllEvents()) { |
| 1055 net_log_.AddEvent( | 1073 net_log_.AddEvent( |
| 1056 net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_READ_END, | 1074 net::NetLog::TYPE_SIMPLE_CACHE_ENTRY_READ_END, |
| 1057 CreateNetLogReadWriteCompleteCallback(*result)); | 1075 CreateNetLogReadWriteCompleteCallback(*result)); |
| 1058 } | 1076 } |
| 1059 | 1077 |
| 1060 EntryOperationComplete( | 1078 EntryOperationComplete( |
| 1061 stream_index, | 1079 stream_index, completion_callback, *entry_stat, result.Pass()); |
| 1062 completion_callback, | |
| 1063 SimpleEntryStat(*last_used, last_modified_, data_size_), | |
| 1064 result.Pass()); | |
| 1065 } | 1080 } |
| 1066 | 1081 |
| 1067 void SimpleEntryImpl::WriteOperationComplete( | 1082 void SimpleEntryImpl::WriteOperationComplete( |
| 1068 int stream_index, | 1083 int stream_index, |
| 1069 const CompletionCallback& completion_callback, | 1084 const CompletionCallback& completion_callback, |
| 1070 scoped_ptr<SimpleEntryStat> entry_stat, | 1085 scoped_ptr<SimpleEntryStat> entry_stat, |
| 1071 scoped_ptr<int> result) { | 1086 scoped_ptr<int> result) { |
| 1072 if (*result >= 0) | 1087 if (*result >= 0) |
| 1073 RecordWriteResult(cache_type_, WRITE_RESULT_SUCCESS); | 1088 RecordWriteResult(cache_type_, WRITE_RESULT_SUCCESS); |
| 1074 else | 1089 else |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1140 } | 1155 } |
| 1141 | 1156 |
| 1142 void SimpleEntryImpl::UpdateDataFromEntryStat( | 1157 void SimpleEntryImpl::UpdateDataFromEntryStat( |
| 1143 const SimpleEntryStat& entry_stat) { | 1158 const SimpleEntryStat& entry_stat) { |
| 1144 DCHECK(io_thread_checker_.CalledOnValidThread()); | 1159 DCHECK(io_thread_checker_.CalledOnValidThread()); |
| 1145 DCHECK(synchronous_entry_); | 1160 DCHECK(synchronous_entry_); |
| 1146 DCHECK_EQ(STATE_READY, state_); | 1161 DCHECK_EQ(STATE_READY, state_); |
| 1147 | 1162 |
| 1148 last_used_ = entry_stat.last_used; | 1163 last_used_ = entry_stat.last_used; |
| 1149 last_modified_ = entry_stat.last_modified; | 1164 last_modified_ = entry_stat.last_modified; |
| 1150 for (int i = 0; i < kSimpleEntryFileCount; ++i) { | 1165 for (int i = 0; i < kSimpleEntryStreamCount; ++i) { |
| 1151 data_size_[i] = entry_stat.data_size[i]; | 1166 data_size_[i] = entry_stat.data_size[i]; |
| 1152 } | 1167 } |
| 1153 if (backend_.get()) | 1168 if (backend_.get()) |
| 1154 backend_->index()->UpdateEntrySize(entry_hash_, GetDiskUsage()); | 1169 backend_->index()->UpdateEntrySize(entry_hash_, GetDiskUsage()); |
| 1155 } | 1170 } |
| 1156 | 1171 |
| 1157 int64 SimpleEntryImpl::GetDiskUsage() const { | 1172 int64 SimpleEntryImpl::GetDiskUsage() const { |
| 1158 int64 file_size = 0; | 1173 int64 file_size = 0; |
| 1159 for (int i = 0; i < kSimpleEntryFileCount; ++i) { | 1174 for (int i = 0; i < kSimpleEntryStreamCount; ++i) { |
| 1160 file_size += | 1175 file_size += |
| 1161 simple_util::GetFileSizeFromKeyAndDataSize(key_, data_size_[i]); | 1176 simple_util::GetFileSizeFromKeyAndDataSize(key_, data_size_[i]); |
| 1162 } | 1177 } |
| 1163 return file_size; | 1178 return file_size; |
| 1164 } | 1179 } |
| 1165 | 1180 |
| 1166 void SimpleEntryImpl::RecordReadIsParallelizable( | 1181 void SimpleEntryImpl::RecordReadIsParallelizable( |
| 1167 const SimpleEntryOperation& operation) const { | 1182 const SimpleEntryOperation& operation) const { |
| 1168 if (!executing_operation_) | 1183 if (!executing_operation_) |
| 1169 return; | 1184 return; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1227 } else { | 1242 } else { |
| 1228 type = conflicting ? WRITE_FOLLOWS_CONFLICTING_WRITE | 1243 type = conflicting ? WRITE_FOLLOWS_CONFLICTING_WRITE |
| 1229 : WRITE_FOLLOWS_NON_CONFLICTING_WRITE; | 1244 : WRITE_FOLLOWS_NON_CONFLICTING_WRITE; |
| 1230 } | 1245 } |
| 1231 } | 1246 } |
| 1232 SIMPLE_CACHE_UMA(ENUMERATION, | 1247 SIMPLE_CACHE_UMA(ENUMERATION, |
| 1233 "WriteDependencyType", cache_type_, | 1248 "WriteDependencyType", cache_type_, |
| 1234 type, WRITE_DEPENDENCY_TYPE_MAX); | 1249 type, WRITE_DEPENDENCY_TYPE_MAX); |
| 1235 } | 1250 } |
| 1236 | 1251 |
| 1252 int SimpleEntryImpl::ReadStream0Data(net::IOBuffer* buf, | |
| 1253 int offset, | |
| 1254 int buf_len) { | |
| 1255 int read_size = std::min(data_size_[0] - offset, buf_len); | |
| 1256 if (read_size < 0) { | |
| 1257 RecordReadResult(cache_type_, READ_RESULT_SUCCESS); | |
|
pasko
2013/09/13 19:09:21
READ_RESULT_SYNC_READ_FAILURE
clamy
2013/09/16 15:01:17
Done.
| |
| 1258 return 0; | |
| 1259 } | |
| 1260 memcpy(buf->data(), stream_0_data_->data() + offset, read_size); | |
| 1261 UpdateDataFromEntryStat( | |
| 1262 SimpleEntryStat(base::Time::Now(), last_modified_, data_size_)); | |
| 1263 RecordReadResult(cache_type_, READ_RESULT_SUCCESS); | |
| 1264 return read_size; | |
| 1265 } | |
| 1266 | |
| 1267 int SimpleEntryImpl::CopyStream0Data(net::IOBuffer* buf, | |
|
gavinp
2013/09/10 22:20:49
Does stream 0 need to support anything than a trun
clamy
2013/09/11 12:46:21
Well on HTTP cache, according to UMA other cases n
| |
| 1268 int offset, | |
| 1269 int buf_len, | |
| 1270 bool truncate) { | |
| 1271 // Currently, Simple Cache is only used for HTTP, which stores the headers in | |
|
pasko
2013/09/13 19:09:21
"only used for HTTP" will have to be changed soon.
clamy
2013/09/16 15:01:17
Done.
| |
| 1272 // stream 0 and always writes them with a single, truncating write. Detect | |
| 1273 // these writes and record the size and size changes of the headers. Also, | |
| 1274 // supports writes to stream 0 that violate those assumptions. | |
| 1275 if (!stream_0_data_) | |
| 1276 stream_0_data_ = new net::GrowableIOBuffer(); | |
| 1277 have_written_[0] = true; | |
|
pasko
2013/09/13 19:09:21
I am somewhat annoyed to observe the zero index in
clamy
2013/09/16 15:01:17
Done.
| |
| 1278 if (offset == 0 && truncate) { | |
| 1279 RecordHeaderSizeChange(cache_type_, data_size_[0], buf_len); | |
| 1280 stream_0_data_->SetCapacity(buf_len); | |
| 1281 memcpy(stream_0_data_->data(), buf->data(), buf_len); | |
| 1282 data_size_[0] = buf_len; | |
| 1283 } else { | |
| 1284 RecordUnexpectedStream0Write(cache_type_); | |
| 1285 const int buffer_size = | |
| 1286 truncate ? offset + buf_len : std::max(offset + buf_len, data_size_[0]); | |
| 1287 stream_0_data_->SetCapacity(buffer_size); | |
| 1288 // If |stream_0_data_| was extended. the extension need to be zeroed. | |
| 1289 const int fill_size = buffer_size - data_size_[0]; | |
|
gavinp
2013/09/10 22:20:49
const int fill_size = (truncate || offset <= data_
clamy
2013/09/11 12:46:21
With a comment such as
// The extension until off
| |
| 1290 if (fill_size > 0) | |
| 1291 memset(stream_0_data_->data() + data_size_[0], 0, fill_size); | |
| 1292 if (buf) | |
| 1293 memcpy(stream_0_data_->data() + offset, buf->data(), buf_len); | |
| 1294 data_size_[0] = buffer_size; | |
| 1295 } | |
| 1296 base::Time modification_time = base::Time::Now(); | |
| 1297 UpdateDataFromEntryStat( | |
| 1298 SimpleEntryStat(modification_time, modification_time, data_size_)); | |
| 1299 if (stream_0_data_) { | |
| 1300 crc32s_[0] = crc32(crc32(0L, Z_NULL, 0), | |
| 1301 reinterpret_cast<const Bytef*>(stream_0_data_->data()), | |
| 1302 data_size_[0]); | |
| 1303 } else { | |
| 1304 crc32s_[0] = crc32(0L, Z_NULL, 0); | |
| 1305 } | |
| 1306 RecordWriteResult(cache_type_, WRITE_RESULT_SUCCESS); | |
| 1307 return buf_len; | |
| 1308 } | |
| 1309 | |
| 1237 } // namespace disk_cache | 1310 } // namespace disk_cache |
| OLD | NEW |