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 |