Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "base/logging.h" | |
| 6 #include "net/base/io_buffer.h" | |
| 7 #include "net/base/net_errors.h" | |
| 8 #include "net/disk_cache/flash/cache_entry.h" | |
| 9 #include "net/disk_cache/flash/format.h" | |
| 10 #include "net/disk_cache/flash/log_structured_store.h" | |
| 11 | |
| 12 namespace disk_cache { | |
| 13 | |
| 14 CacheEntry::CacheEntry(LogStructuredStore* store) | |
| 15 : store_(store), | |
| 16 id_(-1), | |
| 17 init_(false), | |
| 18 closed_(false), | |
| 19 modified_(false) { | |
| 20 DCHECK(store); | |
| 21 for (int i = 0; i < kFlashCacheEntryNumStreams; ++i) | |
| 22 streams_[i].insync = true; | |
| 23 } | |
| 24 | |
| 25 CacheEntry::CacheEntry(LogStructuredStore* store, int32 id) | |
| 26 : store_(store), | |
| 27 id_(id), | |
| 28 init_(false), | |
| 29 closed_(false), | |
| 30 modified_(false) { | |
| 31 DCHECK(store); | |
| 32 } | |
| 33 | |
| 34 CacheEntry::~CacheEntry() { | |
| 35 DCHECK(!init_ || closed_); | |
| 36 } | |
| 37 | |
| 38 bool CacheEntry::Init() { | |
| 39 DCHECK(!init_); | |
| 40 | |
| 41 if (!OnDisk()) { | |
| 42 init_ = true; | |
| 43 return true; | |
| 44 } | |
| 45 | |
| 46 int32 stream_sizes[kFlashCacheEntryNumStreams]; | |
| 47 COMPILE_ASSERT(sizeof(stream_sizes) == kFlashCacheEntryHeaderSize, | |
| 48 invalid_cache_entry_header_size); | |
| 49 | |
| 50 if (!store_->OpenEntry(id_) || | |
| 51 !store_->ReadData(id_, stream_sizes, kFlashCacheEntryHeaderSize, 0)) | |
|
rvargas (doing something else)
2012/11/28 03:12:56
needs braces
agayev
2012/11/29 16:14:43
Done.
| |
| 52 return false; | |
| 53 | |
| 54 for (int i = 0, offset = kFlashCacheEntryHeaderSize; | |
| 55 i < kFlashCacheEntryNumStreams; ++i) { | |
| 56 streams_[i].offset = offset; | |
| 57 streams_[i].data.resize(stream_sizes[i]); | |
| 58 offset += stream_sizes[i]; | |
| 59 } | |
| 60 | |
| 61 init_ = true; | |
| 62 return true; | |
| 63 } | |
| 64 | |
| 65 bool CacheEntry::Close() { | |
| 66 DCHECK(init_ && !closed_); | |
| 67 if (OnDisk()) | |
| 68 store_->CloseEntry(id_); | |
| 69 | |
| 70 if (!modified_) { | |
| 71 closed_ = true; | |
| 72 return true; | |
| 73 } | |
| 74 | |
| 75 if (!Save()) | |
| 76 return false; | |
| 77 | |
| 78 closed_ = true; | |
| 79 return true; | |
| 80 } | |
| 81 | |
| 82 int32 CacheEntry::id() const { | |
| 83 DCHECK(init_); | |
| 84 return id_; | |
| 85 } | |
| 86 | |
| 87 int32 CacheEntry::GetDataSize(int index) const { | |
| 88 DCHECK(init_&& ValidStream(index)); | |
|
rvargas (doing something else)
2012/11/28 03:12:56
you should be careful here... it is not clear to m
agayev
2012/11/29 16:14:43
Done.
| |
| 89 return streams_[index].data.size(); | |
| 90 } | |
| 91 | |
| 92 int CacheEntry::ReadData(int index, int offset, net::IOBuffer* buf, | |
| 93 int buf_len) { | |
| 94 DCHECK(init_ && ValidStream(index)); | |
|
rvargas (doing something else)
2012/11/28 03:12:56
same here
agayev
2012/11/29 16:14:43
Done.
| |
| 95 const int stream_size = static_cast<int>(streams_[index].data.size()); | |
|
rvargas (doing something else)
2012/11/28 03:12:56
drop the const and call GetDataSize
agayev
2012/11/29 16:14:43
Done. Why drop const?
rvargas (doing something else)
2012/11/29 20:32:36
Because it is a local variable that just stores th
| |
| 96 | |
| 97 if (offset >= stream_size || offset < 0 || buf_len == 0) | |
| 98 return 0; | |
| 99 if (offset + buf_len > stream_size) | |
| 100 buf_len = stream_size - offset; | |
| 101 | |
| 102 if (OnDisk() && !LazyRead(index)) | |
| 103 return net::ERR_FAILED; | |
| 104 | |
| 105 memcpy(buf->data(), &streams_[index].data[offset], buf_len); | |
|
rvargas (doing something else)
2012/11/28 03:12:56
And extra copy here doesn't look right. What's the
agayev
2012/11/29 16:14:43
Right now we are not buffering in the Segment laye
rvargas (doing something else)
2012/11/29 20:32:36
Well... it is an extra buffer because what we real
| |
| 106 return buf_len; | |
| 107 } | |
| 108 | |
| 109 int CacheEntry::WriteData(int index, int offset, net::IOBuffer* buf, | |
| 110 int buf_len) { | |
| 111 DCHECK(init_ && !closed_ && ValidStream(index)); | |
| 112 DCHECK(offset >= 0 && buf_len >= 0); | |
|
rvargas (doing something else)
2012/11/28 03:12:56
same caveat about who's the caller
agayev
2012/11/29 16:14:43
Done.
rvargas (doing something else)
2012/12/05 00:21:01
done? does this come from the "user" ?
agayev
2012/12/05 16:53:19
Yes it does. HttpCache may call WriteData with an
| |
| 113 if (offset + buf_len == 0) { // Truncate to 0. | |
| 114 streams_[index].data.clear(); | |
| 115 streams_[index].insync = true; | |
| 116 } else if (offset == 0) { // Overwrite and truncate if necessary. | |
| 117 streams_[index].data.resize(buf_len); | |
| 118 streams_[index].insync = true; | |
| 119 memcpy(&streams_[index].data[offset], buf->data(), buf_len); | |
| 120 } else { // Append. | |
| 121 DCHECK(offset == static_cast<int>(streams_[index].data.size())); | |
| 122 streams_[index].data.resize(offset + buf_len); | |
| 123 if (!LazyRead(index)) | |
|
rvargas (doing something else)
2012/11/28 03:12:56
what for?
agayev
2012/11/29 16:14:43
The idea is to not to read a stream unless it is n
rvargas (doing something else)
2012/11/29 20:32:36
But we don't have to read the first part in order
| |
| 124 return net::ERR_FAILED; | |
| 125 memcpy(&streams_[index].data[offset], buf->data(), buf_len); | |
| 126 } | |
| 127 modified_ = true; | |
| 128 return buf_len; | |
| 129 } | |
| 130 | |
| 131 bool CacheEntry::OnDisk() const { | |
| 132 return id_ != -1; | |
| 133 } | |
| 134 | |
| 135 bool CacheEntry::ValidStream(int stream_index) const { | |
| 136 DCHECK(init_); | |
|
rvargas (doing something else)
2012/11/28 03:12:56
I'd remove the dchecks for init that you have when
agayev
2012/11/29 16:14:43
Done.
| |
| 137 return stream_index >= 0 && stream_index < kFlashCacheEntryNumStreams; | |
| 138 } | |
| 139 | |
| 140 int32 CacheEntry::Size() const { | |
| 141 DCHECK(init_); | |
| 142 int32 size = kFlashCacheEntryHeaderSize; | |
| 143 for (int i = 0; i < kFlashCacheEntryNumStreams; ++i) | |
| 144 size += streams_[i].data.size(); | |
|
rvargas (doing something else)
2012/11/28 03:12:56
GetDataSize
agayev
2012/11/29 16:14:43
Done.
| |
| 145 DCHECK(size > 0 && size <= kFlashSegmentFreeSpace); | |
| 146 return size; | |
| 147 } | |
| 148 | |
| 149 bool CacheEntry::Save() { | |
| 150 DCHECK(init_ && !closed_); | |
| 151 int32 stream_sizes[kFlashCacheEntryNumStreams]; | |
| 152 COMPILE_ASSERT(sizeof(stream_sizes) == kFlashCacheEntryHeaderSize, | |
| 153 invalid_cache_entry_header_size); | |
| 154 | |
| 155 for (int i = 0; i < kFlashCacheEntryNumStreams; ++i) { | |
| 156 if (!LazyRead(i)) | |
|
rvargas (doing something else)
2012/11/28 03:12:56
why?
agayev
2012/11/29 16:14:43
Say we open an existing entry and update stream 1
rvargas (doing something else)
2012/11/29 20:32:36
but that use case doesn't work with the rest of th
| |
| 157 return false; | |
| 158 stream_sizes[i] = streams_[i].data.size(); | |
| 159 } | |
| 160 | |
| 161 if (!store_->CreateEntry(Size(), &id_)) | |
| 162 return false; | |
| 163 if (!store_->WriteData(stream_sizes, kFlashCacheEntryHeaderSize)) | |
| 164 return false; | |
| 165 for (int i = 0; i < kFlashCacheEntryNumStreams; ++i) | |
| 166 if (!store_->WriteData(&streams_[i].data[0], streams_[i].data.size())) | |
| 167 return false; | |
| 168 store_->CloseEntry(id_); | |
| 169 return true; | |
| 170 } | |
| 171 | |
| 172 bool CacheEntry::LazyRead(int index) { | |
| 173 DCHECK(init_ && ValidStream(index)); | |
| 174 Stream& stream = streams_[index]; | |
| 175 if (!stream.insync) | |
| 176 stream.insync = store_->ReadData(id_, &stream.data[0], stream.data.size(), | |
| 177 stream.offset); | |
| 178 return stream.insync; | |
| 179 } | |
| 180 | |
| 181 } // namespace disk_cache | |
| OLD | NEW |