| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/entry_impl.h" | 5 #include "net/disk_cache/entry_impl.h" |
| 6 | 6 |
| 7 #include "base/hash.h" | 7 #include "base/hash.h" |
| 8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
| 9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
| 10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 // anywhere in the first 16KB of the file (kMaxBlockSize), we set the offset to | 89 // anywhere in the first 16KB of the file (kMaxBlockSize), we set the offset to |
| 90 // zero. The buffer grows up to a size determined by the backend, to keep the | 90 // zero. The buffer grows up to a size determined by the backend, to keep the |
| 91 // total memory used under control. | 91 // total memory used under control. |
| 92 class EntryImpl::UserBuffer { | 92 class EntryImpl::UserBuffer { |
| 93 public: | 93 public: |
| 94 explicit UserBuffer(BackendImpl* backend) | 94 explicit UserBuffer(BackendImpl* backend) |
| 95 : backend_(backend->GetWeakPtr()), offset_(0), grow_allowed_(true) { | 95 : backend_(backend->GetWeakPtr()), offset_(0), grow_allowed_(true) { |
| 96 buffer_.reserve(kMaxBlockSize); | 96 buffer_.reserve(kMaxBlockSize); |
| 97 } | 97 } |
| 98 ~UserBuffer() { | 98 ~UserBuffer() { |
| 99 if (backend_.get()) | 99 if (backend_) |
| 100 backend_->BufferDeleted(capacity() - kMaxBlockSize); | 100 backend_->BufferDeleted(capacity() - kMaxBlockSize); |
| 101 } | 101 } |
| 102 | 102 |
| 103 // Returns true if we can handle writing |len| bytes to |offset|. | 103 // Returns true if we can handle writing |len| bytes to |offset|. |
| 104 bool PreWrite(int offset, int len); | 104 bool PreWrite(int offset, int len); |
| 105 | 105 |
| 106 // Truncates the buffer to |offset| bytes. | 106 // Truncates the buffer to |offset| bytes. |
| 107 void Truncate(int offset); | 107 void Truncate(int offset); |
| 108 | 108 |
| 109 // Writes |len| bytes from |buf| at the given |offset|. | 109 // Writes |len| bytes from |buf| at the given |offset|. |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 int available = Size() - start; | 246 int available = Size() - start; |
| 247 DCHECK_GE(start, 0); | 247 DCHECK_GE(start, 0); |
| 248 DCHECK_GE(available, 0); | 248 DCHECK_GE(available, 0); |
| 249 len = std::min(len, available); | 249 len = std::min(len, available); |
| 250 memcpy(buf->data() + clean_bytes, &buffer_[start], len); | 250 memcpy(buf->data() + clean_bytes, &buffer_[start], len); |
| 251 return len + clean_bytes; | 251 return len + clean_bytes; |
| 252 } | 252 } |
| 253 | 253 |
| 254 void EntryImpl::UserBuffer::Reset() { | 254 void EntryImpl::UserBuffer::Reset() { |
| 255 if (!grow_allowed_) { | 255 if (!grow_allowed_) { |
| 256 if (backend_.get()) | 256 if (backend_) |
| 257 backend_->BufferDeleted(capacity() - kMaxBlockSize); | 257 backend_->BufferDeleted(capacity() - kMaxBlockSize); |
| 258 grow_allowed_ = true; | 258 grow_allowed_ = true; |
| 259 std::vector<char> tmp; | 259 std::vector<char> tmp; |
| 260 buffer_.swap(tmp); | 260 buffer_.swap(tmp); |
| 261 buffer_.reserve(kMaxBlockSize); | 261 buffer_.reserve(kMaxBlockSize); |
| 262 } | 262 } |
| 263 offset_ = 0; | 263 offset_ = 0; |
| 264 buffer_.clear(); | 264 buffer_.clear(); |
| 265 } | 265 } |
| 266 | 266 |
| 267 bool EntryImpl::UserBuffer::GrowBuffer(int required, int limit) { | 267 bool EntryImpl::UserBuffer::GrowBuffer(int required, int limit) { |
| 268 DCHECK_GE(required, 0); | 268 DCHECK_GE(required, 0); |
| 269 int current_size = capacity(); | 269 int current_size = capacity(); |
| 270 if (required <= current_size) | 270 if (required <= current_size) |
| 271 return true; | 271 return true; |
| 272 | 272 |
| 273 if (required > limit) | 273 if (required > limit) |
| 274 return false; | 274 return false; |
| 275 | 275 |
| 276 if (!backend_.get()) | 276 if (!backend_) |
| 277 return false; | 277 return false; |
| 278 | 278 |
| 279 int to_add = std::max(required - current_size, kMaxBlockSize * 4); | 279 int to_add = std::max(required - current_size, kMaxBlockSize * 4); |
| 280 to_add = std::max(current_size, to_add); | 280 to_add = std::max(current_size, to_add); |
| 281 required = std::min(current_size + to_add, limit); | 281 required = std::min(current_size + to_add, limit); |
| 282 | 282 |
| 283 grow_allowed_ = backend_->IsAllocAllowed(current_size, required); | 283 grow_allowed_ = backend_->IsAllocAllowed(current_size, required); |
| 284 if (!grow_allowed_) | 284 if (!grow_allowed_) |
| 285 return false; | 285 return false; |
| 286 | 286 |
| 287 DVLOG(3) << "Buffer grow to " << required; | 287 DVLOG(3) << "Buffer grow to " << required; |
| 288 | 288 |
| 289 buffer_.reserve(required); | 289 buffer_.reserve(required); |
| 290 return true; | 290 return true; |
| 291 } | 291 } |
| 292 | 292 |
| 293 // ------------------------------------------------------------------------ | 293 // ------------------------------------------------------------------------ |
| 294 | 294 |
| 295 EntryImpl::EntryImpl(BackendImpl* backend, Addr address, bool read_only) | 295 EntryImpl::EntryImpl(BackendImpl* backend, Addr address, bool read_only) |
| 296 : entry_(NULL, Addr(0)), node_(NULL, Addr(0)), | 296 : entry_(NULL, Addr(0)), node_(NULL, Addr(0)), |
| 297 backend_(backend->GetWeakPtr()), doomed_(false), read_only_(read_only), | 297 backend_(backend->GetWeakPtr()), doomed_(false), read_only_(read_only), |
| 298 dirty_(false) { | 298 dirty_(false) { |
| 299 entry_.LazyInit(backend->File(address), address); | 299 entry_.LazyInit(backend->File(address), address); |
| 300 for (int i = 0; i < kNumStreams; i++) { | 300 for (int i = 0; i < kNumStreams; i++) { |
| 301 unreported_size_[i] = 0; | 301 unreported_size_[i] = 0; |
| 302 } | 302 } |
| 303 } | 303 } |
| 304 | 304 |
| 305 void EntryImpl::DoomImpl() { | 305 void EntryImpl::DoomImpl() { |
| 306 if (doomed_ || !backend_.get()) | 306 if (doomed_ || !backend_) |
| 307 return; | 307 return; |
| 308 | 308 |
| 309 SetPointerForInvalidEntry(backend_->GetCurrentEntryId()); | 309 SetPointerForInvalidEntry(backend_->GetCurrentEntryId()); |
| 310 backend_->InternalDoomEntry(this); | 310 backend_->InternalDoomEntry(this); |
| 311 } | 311 } |
| 312 | 312 |
| 313 int EntryImpl::ReadDataImpl(int index, int offset, IOBuffer* buf, int buf_len, | 313 int EntryImpl::ReadDataImpl(int index, int offset, IOBuffer* buf, int buf_len, |
| 314 const CompletionCallback& callback) { | 314 const CompletionCallback& callback) { |
| 315 if (net_log_.IsLoggingAllEvents()) { | 315 if (net_log_.IsLoggingAllEvents()) { |
| 316 net_log_.BeginEvent( | 316 net_log_.BeginEvent( |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 666 stored->data_size[i] = 0; | 666 stored->data_size[i] = 0; |
| 667 } | 667 } |
| 668 entry_.Store(); | 668 entry_.Store(); |
| 669 } | 669 } |
| 670 | 670 |
| 671 void EntryImpl::IncrementIoCount() { | 671 void EntryImpl::IncrementIoCount() { |
| 672 backend_->IncrementIoCount(); | 672 backend_->IncrementIoCount(); |
| 673 } | 673 } |
| 674 | 674 |
| 675 void EntryImpl::DecrementIoCount() { | 675 void EntryImpl::DecrementIoCount() { |
| 676 if (backend_.get()) | 676 if (backend_) |
| 677 backend_->DecrementIoCount(); | 677 backend_->DecrementIoCount(); |
| 678 } | 678 } |
| 679 | 679 |
| 680 void EntryImpl::OnEntryCreated(BackendImpl* backend) { | 680 void EntryImpl::OnEntryCreated(BackendImpl* backend) { |
| 681 // Just grab a reference to the backround queue. | 681 // Just grab a reference to the backround queue. |
| 682 background_queue_ = backend->GetBackgroundQueue(); | 682 background_queue_ = backend->GetBackgroundQueue(); |
| 683 } | 683 } |
| 684 | 684 |
| 685 void EntryImpl::SetTimes(base::Time last_used, base::Time last_modified) { | 685 void EntryImpl::SetTimes(base::Time last_used, base::Time last_modified) { |
| 686 node_.Data()->last_used = last_used.ToInternalValue(); | 686 node_.Data()->last_used = last_used.ToInternalValue(); |
| 687 node_.Data()->last_modified = last_modified.ToInternalValue(); | 687 node_.Data()->last_modified = last_modified.ToInternalValue(); |
| 688 node_.set_modified(); | 688 node_.set_modified(); |
| 689 } | 689 } |
| 690 | 690 |
| 691 void EntryImpl::ReportIOTime(Operation op, const base::TimeTicks& start) { | 691 void EntryImpl::ReportIOTime(Operation op, const base::TimeTicks& start) { |
| 692 if (!backend_.get()) | 692 if (!backend_) |
| 693 return; | 693 return; |
| 694 | 694 |
| 695 switch (op) { | 695 switch (op) { |
| 696 case kRead: | 696 case kRead: |
| 697 CACHE_UMA(AGE_MS, "ReadTime", 0, start); | 697 CACHE_UMA(AGE_MS, "ReadTime", 0, start); |
| 698 break; | 698 break; |
| 699 case kWrite: | 699 case kWrite: |
| 700 CACHE_UMA(AGE_MS, "WriteTime", 0, start); | 700 CACHE_UMA(AGE_MS, "WriteTime", 0, start); |
| 701 break; | 701 break; |
| 702 case kSparseRead: | 702 case kSparseRead: |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 | 740 |
| 741 if (key_size < key1_len || key_size > kMaxInternalKeyLength) | 741 if (key_size < key1_len || key_size > kMaxInternalKeyLength) |
| 742 return 1; | 742 return 1; |
| 743 | 743 |
| 744 return ((key_size - key1_len) / 256 + 2); | 744 return ((key_size - key1_len) / 256 + 2); |
| 745 } | 745 } |
| 746 | 746 |
| 747 // ------------------------------------------------------------------------ | 747 // ------------------------------------------------------------------------ |
| 748 | 748 |
| 749 void EntryImpl::Doom() { | 749 void EntryImpl::Doom() { |
| 750 if (background_queue_.get()) | 750 if (background_queue_) |
| 751 background_queue_->DoomEntryImpl(this); | 751 background_queue_->DoomEntryImpl(this); |
| 752 } | 752 } |
| 753 | 753 |
| 754 void EntryImpl::Close() { | 754 void EntryImpl::Close() { |
| 755 if (background_queue_.get()) | 755 if (background_queue_) |
| 756 background_queue_->CloseEntryImpl(this); | 756 background_queue_->CloseEntryImpl(this); |
| 757 } | 757 } |
| 758 | 758 |
| 759 std::string EntryImpl::GetKey() const { | 759 std::string EntryImpl::GetKey() const { |
| 760 CacheEntryBlock* entry = const_cast<CacheEntryBlock*>(&entry_); | 760 CacheEntryBlock* entry = const_cast<CacheEntryBlock*>(&entry_); |
| 761 int key_len = entry->Data()->key_len; | 761 int key_len = entry->Data()->key_len; |
| 762 if (key_len <= kMaxInternalKeyLength) | 762 if (key_len <= kMaxInternalKeyLength) |
| 763 return std::string(entry->Data()->key); | 763 return std::string(entry->Data()->key); |
| 764 | 764 |
| 765 // We keep a copy of the key so that we can always return it, even if the | 765 // We keep a copy of the key so that we can always return it, even if the |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 815 if (index < 0 || index >= kNumStreams) | 815 if (index < 0 || index >= kNumStreams) |
| 816 return net::ERR_INVALID_ARGUMENT; | 816 return net::ERR_INVALID_ARGUMENT; |
| 817 | 817 |
| 818 int entry_size = entry_.Data()->data_size[index]; | 818 int entry_size = entry_.Data()->data_size[index]; |
| 819 if (offset >= entry_size || offset < 0 || !buf_len) | 819 if (offset >= entry_size || offset < 0 || !buf_len) |
| 820 return 0; | 820 return 0; |
| 821 | 821 |
| 822 if (buf_len < 0) | 822 if (buf_len < 0) |
| 823 return net::ERR_INVALID_ARGUMENT; | 823 return net::ERR_INVALID_ARGUMENT; |
| 824 | 824 |
| 825 if (!background_queue_.get()) | 825 if (!background_queue_) |
| 826 return net::ERR_UNEXPECTED; | 826 return net::ERR_UNEXPECTED; |
| 827 | 827 |
| 828 background_queue_->ReadData(this, index, offset, buf, buf_len, callback); | 828 background_queue_->ReadData(this, index, offset, buf, buf_len, callback); |
| 829 return net::ERR_IO_PENDING; | 829 return net::ERR_IO_PENDING; |
| 830 } | 830 } |
| 831 | 831 |
| 832 int EntryImpl::WriteData(int index, int offset, IOBuffer* buf, int buf_len, | 832 int EntryImpl::WriteData(int index, int offset, IOBuffer* buf, int buf_len, |
| 833 const CompletionCallback& callback, bool truncate) { | 833 const CompletionCallback& callback, bool truncate) { |
| 834 if (callback.is_null()) | 834 if (callback.is_null()) |
| 835 return WriteDataImpl(index, offset, buf, buf_len, callback, truncate); | 835 return WriteDataImpl(index, offset, buf, buf_len, callback, truncate); |
| 836 | 836 |
| 837 DCHECK(node_.Data()->dirty || read_only_); | 837 DCHECK(node_.Data()->dirty || read_only_); |
| 838 if (index < 0 || index >= kNumStreams) | 838 if (index < 0 || index >= kNumStreams) |
| 839 return net::ERR_INVALID_ARGUMENT; | 839 return net::ERR_INVALID_ARGUMENT; |
| 840 | 840 |
| 841 if (offset < 0 || buf_len < 0) | 841 if (offset < 0 || buf_len < 0) |
| 842 return net::ERR_INVALID_ARGUMENT; | 842 return net::ERR_INVALID_ARGUMENT; |
| 843 | 843 |
| 844 if (!background_queue_.get()) | 844 if (!background_queue_) |
| 845 return net::ERR_UNEXPECTED; | 845 return net::ERR_UNEXPECTED; |
| 846 | 846 |
| 847 background_queue_->WriteData(this, index, offset, buf, buf_len, truncate, | 847 background_queue_->WriteData(this, index, offset, buf, buf_len, truncate, |
| 848 callback); | 848 callback); |
| 849 return net::ERR_IO_PENDING; | 849 return net::ERR_IO_PENDING; |
| 850 } | 850 } |
| 851 | 851 |
| 852 int EntryImpl::ReadSparseData(int64 offset, IOBuffer* buf, int buf_len, | 852 int EntryImpl::ReadSparseData(int64 offset, IOBuffer* buf, int buf_len, |
| 853 const CompletionCallback& callback) { | 853 const CompletionCallback& callback) { |
| 854 if (callback.is_null()) | 854 if (callback.is_null()) |
| 855 return ReadSparseDataImpl(offset, buf, buf_len, callback); | 855 return ReadSparseDataImpl(offset, buf, buf_len, callback); |
| 856 | 856 |
| 857 if (!background_queue_.get()) | 857 if (!background_queue_) |
| 858 return net::ERR_UNEXPECTED; | 858 return net::ERR_UNEXPECTED; |
| 859 | 859 |
| 860 background_queue_->ReadSparseData(this, offset, buf, buf_len, callback); | 860 background_queue_->ReadSparseData(this, offset, buf, buf_len, callback); |
| 861 return net::ERR_IO_PENDING; | 861 return net::ERR_IO_PENDING; |
| 862 } | 862 } |
| 863 | 863 |
| 864 int EntryImpl::WriteSparseData(int64 offset, IOBuffer* buf, int buf_len, | 864 int EntryImpl::WriteSparseData(int64 offset, IOBuffer* buf, int buf_len, |
| 865 const CompletionCallback& callback) { | 865 const CompletionCallback& callback) { |
| 866 if (callback.is_null()) | 866 if (callback.is_null()) |
| 867 return WriteSparseDataImpl(offset, buf, buf_len, callback); | 867 return WriteSparseDataImpl(offset, buf, buf_len, callback); |
| 868 | 868 |
| 869 if (!background_queue_.get()) | 869 if (!background_queue_) |
| 870 return net::ERR_UNEXPECTED; | 870 return net::ERR_UNEXPECTED; |
| 871 | 871 |
| 872 background_queue_->WriteSparseData(this, offset, buf, buf_len, callback); | 872 background_queue_->WriteSparseData(this, offset, buf, buf_len, callback); |
| 873 return net::ERR_IO_PENDING; | 873 return net::ERR_IO_PENDING; |
| 874 } | 874 } |
| 875 | 875 |
| 876 int EntryImpl::GetAvailableRange(int64 offset, int len, int64* start, | 876 int EntryImpl::GetAvailableRange(int64 offset, int len, int64* start, |
| 877 const CompletionCallback& callback) { | 877 const CompletionCallback& callback) { |
| 878 if (!background_queue_.get()) | 878 if (!background_queue_) |
| 879 return net::ERR_UNEXPECTED; | 879 return net::ERR_UNEXPECTED; |
| 880 | 880 |
| 881 background_queue_->GetAvailableRange(this, offset, len, start, callback); | 881 background_queue_->GetAvailableRange(this, offset, len, start, callback); |
| 882 return net::ERR_IO_PENDING; | 882 return net::ERR_IO_PENDING; |
| 883 } | 883 } |
| 884 | 884 |
| 885 bool EntryImpl::CouldBeSparse() const { | 885 bool EntryImpl::CouldBeSparse() const { |
| 886 if (sparse_.get()) | 886 if (sparse_.get()) |
| 887 return true; | 887 return true; |
| 888 | 888 |
| 889 scoped_ptr<SparseControl> sparse; | 889 scoped_ptr<SparseControl> sparse; |
| 890 sparse.reset(new SparseControl(const_cast<EntryImpl*>(this))); | 890 sparse.reset(new SparseControl(const_cast<EntryImpl*>(this))); |
| 891 return sparse->CouldBeSparse(); | 891 return sparse->CouldBeSparse(); |
| 892 } | 892 } |
| 893 | 893 |
| 894 void EntryImpl::CancelSparseIO() { | 894 void EntryImpl::CancelSparseIO() { |
| 895 if (background_queue_.get()) | 895 if (background_queue_) |
| 896 background_queue_->CancelSparseIO(this); | 896 background_queue_->CancelSparseIO(this); |
| 897 } | 897 } |
| 898 | 898 |
| 899 int EntryImpl::ReadyForSparseIO(const CompletionCallback& callback) { | 899 int EntryImpl::ReadyForSparseIO(const CompletionCallback& callback) { |
| 900 if (!sparse_.get()) | 900 if (!sparse_.get()) |
| 901 return net::OK; | 901 return net::OK; |
| 902 | 902 |
| 903 if (!background_queue_.get()) | 903 if (!background_queue_) |
| 904 return net::ERR_UNEXPECTED; | 904 return net::ERR_UNEXPECTED; |
| 905 | 905 |
| 906 background_queue_->ReadyForSparseIO(this, callback); | 906 background_queue_->ReadyForSparseIO(this, callback); |
| 907 return net::ERR_IO_PENDING; | 907 return net::ERR_IO_PENDING; |
| 908 } | 908 } |
| 909 | 909 |
| 910 // When an entry is deleted from the cache, we clean up all the data associated | 910 // When an entry is deleted from the cache, we clean up all the data associated |
| 911 // with it for two reasons: to simplify the reuse of the block (we know that any | 911 // with it for two reasons: to simplify the reuse of the block (we know that any |
| 912 // unused block is filled with zeros), and to simplify the handling of write / | 912 // unused block is filled with zeros), and to simplify the handling of write / |
| 913 // read partial information from an entry (don't have to worry about returning | 913 // read partial information from an entry (don't have to worry about returning |
| 914 // data related to a previous cache entry because the range was not fully | 914 // data related to a previous cache entry because the range was not fully |
| 915 // written before). | 915 // written before). |
| 916 EntryImpl::~EntryImpl() { | 916 EntryImpl::~EntryImpl() { |
| 917 if (!backend_.get()) { | 917 if (!backend_) { |
| 918 entry_.clear_modified(); | 918 entry_.clear_modified(); |
| 919 node_.clear_modified(); | 919 node_.clear_modified(); |
| 920 return; | 920 return; |
| 921 } | 921 } |
| 922 Log("~EntryImpl in"); | 922 Log("~EntryImpl in"); |
| 923 | 923 |
| 924 // Save the sparse info to disk. This will generate IO for this entry and | 924 // Save the sparse info to disk. This will generate IO for this entry and |
| 925 // maybe for a child entry, so it is important to do it before deleting this | 925 // maybe for a child entry, so it is important to do it before deleting this |
| 926 // entry. | 926 // entry. |
| 927 sparse_.reset(); | 927 sparse_.reset(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 if (index < 0 || index >= kNumStreams) | 975 if (index < 0 || index >= kNumStreams) |
| 976 return net::ERR_INVALID_ARGUMENT; | 976 return net::ERR_INVALID_ARGUMENT; |
| 977 | 977 |
| 978 int entry_size = entry_.Data()->data_size[index]; | 978 int entry_size = entry_.Data()->data_size[index]; |
| 979 if (offset >= entry_size || offset < 0 || !buf_len) | 979 if (offset >= entry_size || offset < 0 || !buf_len) |
| 980 return 0; | 980 return 0; |
| 981 | 981 |
| 982 if (buf_len < 0) | 982 if (buf_len < 0) |
| 983 return net::ERR_INVALID_ARGUMENT; | 983 return net::ERR_INVALID_ARGUMENT; |
| 984 | 984 |
| 985 if (!backend_.get()) | 985 if (!backend_) |
| 986 return net::ERR_UNEXPECTED; | 986 return net::ERR_UNEXPECTED; |
| 987 | 987 |
| 988 TimeTicks start = TimeTicks::Now(); | 988 TimeTicks start = TimeTicks::Now(); |
| 989 | 989 |
| 990 if (offset + buf_len > entry_size) | 990 if (offset + buf_len > entry_size) |
| 991 buf_len = entry_size - offset; | 991 buf_len = entry_size - offset; |
| 992 | 992 |
| 993 UpdateRank(false); | 993 UpdateRank(false); |
| 994 | 994 |
| 995 backend_->OnEvent(Stats::READ_DATA); | 995 backend_->OnEvent(Stats::READ_DATA); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1057 const CompletionCallback& callback, | 1057 const CompletionCallback& callback, |
| 1058 bool truncate) { | 1058 bool truncate) { |
| 1059 DCHECK(node_.Data()->dirty || read_only_); | 1059 DCHECK(node_.Data()->dirty || read_only_); |
| 1060 DVLOG(2) << "Write to " << index << " at " << offset << " : " << buf_len; | 1060 DVLOG(2) << "Write to " << index << " at " << offset << " : " << buf_len; |
| 1061 if (index < 0 || index >= kNumStreams) | 1061 if (index < 0 || index >= kNumStreams) |
| 1062 return net::ERR_INVALID_ARGUMENT; | 1062 return net::ERR_INVALID_ARGUMENT; |
| 1063 | 1063 |
| 1064 if (offset < 0 || buf_len < 0) | 1064 if (offset < 0 || buf_len < 0) |
| 1065 return net::ERR_INVALID_ARGUMENT; | 1065 return net::ERR_INVALID_ARGUMENT; |
| 1066 | 1066 |
| 1067 if (!backend_.get()) | 1067 if (!backend_) |
| 1068 return net::ERR_UNEXPECTED; | 1068 return net::ERR_UNEXPECTED; |
| 1069 | 1069 |
| 1070 int max_file_size = backend_->MaxFileSize(); | 1070 int max_file_size = backend_->MaxFileSize(); |
| 1071 | 1071 |
| 1072 // offset or buf_len could be negative numbers. | 1072 // offset or buf_len could be negative numbers. |
| 1073 if (offset > max_file_size || buf_len > max_file_size || | 1073 if (offset > max_file_size || buf_len > max_file_size || |
| 1074 offset + buf_len > max_file_size) { | 1074 offset + buf_len > max_file_size) { |
| 1075 int size = offset + buf_len; | 1075 int size = offset + buf_len; |
| 1076 if (size <= max_file_size) | 1076 if (size <= max_file_size) |
| 1077 size = kint32max; | 1077 size = kint32max; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1165 if (!CreateBlock(size, &address)) | 1165 if (!CreateBlock(size, &address)) |
| 1166 return false; | 1166 return false; |
| 1167 | 1167 |
| 1168 entry_.Data()->data_addr[index] = address.value(); | 1168 entry_.Data()->data_addr[index] = address.value(); |
| 1169 entry_.Store(); | 1169 entry_.Store(); |
| 1170 return true; | 1170 return true; |
| 1171 } | 1171 } |
| 1172 | 1172 |
| 1173 bool EntryImpl::CreateBlock(int size, Addr* address) { | 1173 bool EntryImpl::CreateBlock(int size, Addr* address) { |
| 1174 DCHECK(!address->is_initialized()); | 1174 DCHECK(!address->is_initialized()); |
| 1175 if (!backend_.get()) | 1175 if (!backend_) |
| 1176 return false; | 1176 return false; |
| 1177 | 1177 |
| 1178 FileType file_type = Addr::RequiredFileType(size); | 1178 FileType file_type = Addr::RequiredFileType(size); |
| 1179 if (EXTERNAL == file_type) { | 1179 if (EXTERNAL == file_type) { |
| 1180 if (size > backend_->MaxFileSize()) | 1180 if (size > backend_->MaxFileSize()) |
| 1181 return false; | 1181 return false; |
| 1182 if (!backend_->CreateExternalFile(address)) | 1182 if (!backend_->CreateExternalFile(address)) |
| 1183 return false; | 1183 return false; |
| 1184 } else { | 1184 } else { |
| 1185 int num_blocks = Addr::RequiredBlocks(size, file_type); | 1185 int num_blocks = Addr::RequiredBlocks(size, file_type); |
| 1186 | 1186 |
| 1187 if (!backend_->CreateBlock(file_type, num_blocks, address)) | 1187 if (!backend_->CreateBlock(file_type, num_blocks, address)) |
| 1188 return false; | 1188 return false; |
| 1189 } | 1189 } |
| 1190 return true; | 1190 return true; |
| 1191 } | 1191 } |
| 1192 | 1192 |
| 1193 // Note that this method may end up modifying a block file so upon return the | 1193 // Note that this method may end up modifying a block file so upon return the |
| 1194 // involved block will be free, and could be reused for something else. If there | 1194 // involved block will be free, and could be reused for something else. If there |
| 1195 // is a crash after that point (and maybe before returning to the caller), the | 1195 // is a crash after that point (and maybe before returning to the caller), the |
| 1196 // entry will be left dirty... and at some point it will be discarded; it is | 1196 // entry will be left dirty... and at some point it will be discarded; it is |
| 1197 // important that the entry doesn't keep a reference to this address, or we'll | 1197 // important that the entry doesn't keep a reference to this address, or we'll |
| 1198 // end up deleting the contents of |address| once again. | 1198 // end up deleting the contents of |address| once again. |
| 1199 void EntryImpl::DeleteData(Addr address, int index) { | 1199 void EntryImpl::DeleteData(Addr address, int index) { |
| 1200 DCHECK(backend_.get()); | 1200 DCHECK(backend_); |
| 1201 if (!address.is_initialized()) | 1201 if (!address.is_initialized()) |
| 1202 return; | 1202 return; |
| 1203 if (address.is_separate_file()) { | 1203 if (address.is_separate_file()) { |
| 1204 int failure = !DeleteCacheFile(backend_->GetFileName(address)); | 1204 int failure = !DeleteCacheFile(backend_->GetFileName(address)); |
| 1205 CACHE_UMA(COUNTS, "DeleteFailed", 0, failure); | 1205 CACHE_UMA(COUNTS, "DeleteFailed", 0, failure); |
| 1206 if (failure) { | 1206 if (failure) { |
| 1207 LOG(ERROR) << "Failed to delete " << | 1207 LOG(ERROR) << "Failed to delete " << |
| 1208 backend_->GetFileName(address).value() << " from the cache."; | 1208 backend_->GetFileName(address).value() << " from the cache."; |
| 1209 } | 1209 } |
| 1210 if (files_[index].get()) | 1210 if (files_[index]) |
| 1211 files_[index] = NULL; // Releases the object. | 1211 files_[index] = NULL; // Releases the object. |
| 1212 } else { | 1212 } else { |
| 1213 backend_->DeleteBlock(address, true); | 1213 backend_->DeleteBlock(address, true); |
| 1214 } | 1214 } |
| 1215 } | 1215 } |
| 1216 | 1216 |
| 1217 void EntryImpl::UpdateRank(bool modified) { | 1217 void EntryImpl::UpdateRank(bool modified) { |
| 1218 if (!backend_.get()) | 1218 if (!backend_) |
| 1219 return; | 1219 return; |
| 1220 | 1220 |
| 1221 if (!doomed_) { | 1221 if (!doomed_) { |
| 1222 // Everything is handled by the backend. | 1222 // Everything is handled by the backend. |
| 1223 backend_->UpdateRank(this, modified); | 1223 backend_->UpdateRank(this, modified); |
| 1224 return; | 1224 return; |
| 1225 } | 1225 } |
| 1226 | 1226 |
| 1227 Time current = Time::Now(); | 1227 Time current = Time::Now(); |
| 1228 node_.Data()->last_used = current.ToInternalValue(); | 1228 node_.Data()->last_used = current.ToInternalValue(); |
| 1229 | 1229 |
| 1230 if (modified) | 1230 if (modified) |
| 1231 node_.Data()->last_modified = current.ToInternalValue(); | 1231 node_.Data()->last_modified = current.ToInternalValue(); |
| 1232 } | 1232 } |
| 1233 | 1233 |
| 1234 File* EntryImpl::GetBackingFile(Addr address, int index) { | 1234 File* EntryImpl::GetBackingFile(Addr address, int index) { |
| 1235 if (!backend_.get()) | 1235 if (!backend_) |
| 1236 return NULL; | 1236 return NULL; |
| 1237 | 1237 |
| 1238 File* file; | 1238 File* file; |
| 1239 if (address.is_separate_file()) | 1239 if (address.is_separate_file()) |
| 1240 file = GetExternalFile(address, index); | 1240 file = GetExternalFile(address, index); |
| 1241 else | 1241 else |
| 1242 file = backend_->File(address); | 1242 file = backend_->File(address); |
| 1243 return file; | 1243 return file; |
| 1244 } | 1244 } |
| 1245 | 1245 |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1499 void EntryImpl::SetEntryFlags(uint32 flags) { | 1499 void EntryImpl::SetEntryFlags(uint32 flags) { |
| 1500 entry_.Data()->flags |= flags; | 1500 entry_.Data()->flags |= flags; |
| 1501 entry_.set_modified(); | 1501 entry_.set_modified(); |
| 1502 } | 1502 } |
| 1503 | 1503 |
| 1504 uint32 EntryImpl::GetEntryFlags() { | 1504 uint32 EntryImpl::GetEntryFlags() { |
| 1505 return entry_.Data()->flags; | 1505 return entry_.Data()->flags; |
| 1506 } | 1506 } |
| 1507 | 1507 |
| 1508 void EntryImpl::GetData(int index, char** buffer, Addr* address) { | 1508 void EntryImpl::GetData(int index, char** buffer, Addr* address) { |
| 1509 DCHECK(backend_.get()); | 1509 DCHECK(backend_); |
| 1510 if (user_buffers_[index].get() && user_buffers_[index]->Size() && | 1510 if (user_buffers_[index].get() && user_buffers_[index]->Size() && |
| 1511 !user_buffers_[index]->Start()) { | 1511 !user_buffers_[index]->Start()) { |
| 1512 // The data is already in memory, just copy it and we're done. | 1512 // The data is already in memory, just copy it and we're done. |
| 1513 int data_len = entry_.Data()->data_size[index]; | 1513 int data_len = entry_.Data()->data_size[index]; |
| 1514 if (data_len <= user_buffers_[index]->Size()) { | 1514 if (data_len <= user_buffers_[index]->Size()) { |
| 1515 DCHECK(!user_buffers_[index]->Start()); | 1515 DCHECK(!user_buffers_[index]->Start()); |
| 1516 *buffer = new char[data_len]; | 1516 *buffer = new char[data_len]; |
| 1517 memcpy(*buffer, user_buffers_[index]->Data(), data_len); | 1517 memcpy(*buffer, user_buffers_[index]->Data(), data_len); |
| 1518 return; | 1518 return; |
| 1519 } | 1519 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1541 Trace("%s 0x%p 0x%x 0x%x", msg, reinterpret_cast<void*>(this), | 1541 Trace("%s 0x%p 0x%x 0x%x", msg, reinterpret_cast<void*>(this), |
| 1542 entry_.address().value(), node_.address().value()); | 1542 entry_.address().value(), node_.address().value()); |
| 1543 | 1543 |
| 1544 Trace(" data: 0x%x 0x%x 0x%x", entry_.Data()->data_addr[0], | 1544 Trace(" data: 0x%x 0x%x 0x%x", entry_.Data()->data_addr[0], |
| 1545 entry_.Data()->data_addr[1], entry_.Data()->long_key); | 1545 entry_.Data()->data_addr[1], entry_.Data()->long_key); |
| 1546 | 1546 |
| 1547 Trace(" doomed: %d 0x%x", doomed_, dirty); | 1547 Trace(" doomed: %d 0x%x", doomed_, dirty); |
| 1548 } | 1548 } |
| 1549 | 1549 |
| 1550 } // namespace disk_cache | 1550 } // namespace disk_cache |
| OLD | NEW |