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 |