1 // Copyright 2013 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 "net/disk_cache/simple/simple_entry_operation.h"
6
7 #include "base/logging.h"
8 #include "net/base/io_buffer.h"
9 #include "net/disk_cache/disk_cache.h"
10 #include "net/disk_cache/simple/simple_entry_impl.h"
11
12 namespace disk_cache {
13
14 namespace {
15
IsReadWriteType(unsigned int type)16 bool IsReadWriteType(unsigned int type) {
17 return type == SimpleEntryOperation::TYPE_READ ||
18 type == SimpleEntryOperation::TYPE_WRITE ||
19 type == SimpleEntryOperation::TYPE_READ_SPARSE ||
20 type == SimpleEntryOperation::TYPE_WRITE_SPARSE;
21 }
22
IsReadType(unsigned type)23 bool IsReadType(unsigned type) {
24 return type == SimpleEntryOperation::TYPE_READ ||
25 type == SimpleEntryOperation::TYPE_READ_SPARSE;
26 }
27
IsSparseType(unsigned type)28 bool IsSparseType(unsigned type) {
29 return type == SimpleEntryOperation::TYPE_READ_SPARSE ||
30 type == SimpleEntryOperation::TYPE_WRITE_SPARSE;
31 }
32
33 }
34
SimpleEntryOperation(const SimpleEntryOperation & other)35 SimpleEntryOperation::SimpleEntryOperation(const SimpleEntryOperation& other)
36 : entry_(other.entry_.get()),
37 buf_(other.buf_),
38 callback_(other.callback_),
39 out_entry_(other.out_entry_),
40 offset_(other.offset_),
41 sparse_offset_(other.sparse_offset_),
42 length_(other.length_),
43 out_start_(other.out_start_),
44 type_(other.type_),
45 have_index_(other.have_index_),
46 index_(other.index_),
47 truncate_(other.truncate_),
48 optimistic_(other.optimistic_),
49 alone_in_queue_(other.alone_in_queue_) {
50 }
51
~SimpleEntryOperation()52 SimpleEntryOperation::~SimpleEntryOperation() {}
53
54 // static
OpenOperation(SimpleEntryImpl * entry,bool have_index,const CompletionCallback & callback,Entry ** out_entry)55 SimpleEntryOperation SimpleEntryOperation::OpenOperation(
56 SimpleEntryImpl* entry,
57 bool have_index,
58 const CompletionCallback& callback,
59 Entry** out_entry) {
60 return SimpleEntryOperation(entry,
61 NULL,
62 callback,
63 out_entry,
64 0,
65 0,
66 0,
67 NULL,
68 TYPE_OPEN,
69 have_index,
70 0,
71 false,
72 false,
73 false);
74 }
75
76 // static
CreateOperation(SimpleEntryImpl * entry,bool have_index,const CompletionCallback & callback,Entry ** out_entry)77 SimpleEntryOperation SimpleEntryOperation::CreateOperation(
78 SimpleEntryImpl* entry,
79 bool have_index,
80 const CompletionCallback& callback,
81 Entry** out_entry) {
82 return SimpleEntryOperation(entry,
83 NULL,
84 callback,
85 out_entry,
86 0,
87 0,
88 0,
89 NULL,
90 TYPE_CREATE,
91 have_index,
92 0,
93 false,
94 false,
95 false);
96 }
97
98 // static
CloseOperation(SimpleEntryImpl * entry)99 SimpleEntryOperation SimpleEntryOperation::CloseOperation(
100 SimpleEntryImpl* entry) {
101 return SimpleEntryOperation(entry,
102 NULL,
103 CompletionCallback(),
104 NULL,
105 0,
106 0,
107 0,
108 NULL,
109 TYPE_CLOSE,
110 false,
111 0,
112 false,
113 false,
114 false);
115 }
116
117 // static
ReadOperation(SimpleEntryImpl * entry,int index,int offset,int length,net::IOBuffer * buf,const CompletionCallback & callback,bool alone_in_queue)118 SimpleEntryOperation SimpleEntryOperation::ReadOperation(
119 SimpleEntryImpl* entry,
120 int index,
121 int offset,
122 int length,
123 net::IOBuffer* buf,
124 const CompletionCallback& callback,
125 bool alone_in_queue) {
126 return SimpleEntryOperation(entry,
127 buf,
128 callback,
129 NULL,
130 offset,
131 0,
132 length,
133 NULL,
134 TYPE_READ,
135 false,
136 index,
137 false,
138 false,
139 alone_in_queue);
140 }
141
142 // static
WriteOperation(SimpleEntryImpl * entry,int index,int offset,int length,net::IOBuffer * buf,bool truncate,bool optimistic,const CompletionCallback & callback)143 SimpleEntryOperation SimpleEntryOperation::WriteOperation(
144 SimpleEntryImpl* entry,
145 int index,
146 int offset,
147 int length,
148 net::IOBuffer* buf,
149 bool truncate,
150 bool optimistic,
151 const CompletionCallback& callback) {
152 return SimpleEntryOperation(entry,
153 buf,
154 callback,
155 NULL,
156 offset,
157 0,
158 length,
159 NULL,
160 TYPE_WRITE,
161 false,
162 index,
163 truncate,
164 optimistic,
165 false);
166 }
167
168 // static
ReadSparseOperation(SimpleEntryImpl * entry,int64 sparse_offset,int length,net::IOBuffer * buf,const CompletionCallback & callback)169 SimpleEntryOperation SimpleEntryOperation::ReadSparseOperation(
170 SimpleEntryImpl* entry,
171 int64 sparse_offset,
172 int length,
173 net::IOBuffer* buf,
174 const CompletionCallback& callback) {
175 return SimpleEntryOperation(entry,
176 buf,
177 callback,
178 NULL,
179 0,
180 sparse_offset,
181 length,
182 NULL,
183 TYPE_READ_SPARSE,
184 false,
185 0,
186 false,
187 false,
188 false);
189 }
190
191 // static
WriteSparseOperation(SimpleEntryImpl * entry,int64 sparse_offset,int length,net::IOBuffer * buf,const CompletionCallback & callback)192 SimpleEntryOperation SimpleEntryOperation::WriteSparseOperation(
193 SimpleEntryImpl* entry,
194 int64 sparse_offset,
195 int length,
196 net::IOBuffer* buf,
197 const CompletionCallback& callback) {
198 return SimpleEntryOperation(entry,
199 buf,
200 callback,
201 NULL,
202 0,
203 sparse_offset,
204 length,
205 NULL,
206 TYPE_WRITE_SPARSE,
207 false,
208 0,
209 false,
210 false,
211 false);
212 }
213
214 // static
GetAvailableRangeOperation(SimpleEntryImpl * entry,int64 sparse_offset,int length,int64 * out_start,const CompletionCallback & callback)215 SimpleEntryOperation SimpleEntryOperation::GetAvailableRangeOperation(
216 SimpleEntryImpl* entry,
217 int64 sparse_offset,
218 int length,
219 int64* out_start,
220 const CompletionCallback& callback) {
221 return SimpleEntryOperation(entry,
222 NULL,
223 callback,
224 NULL,
225 0,
226 sparse_offset,
227 length,
228 out_start,
229 TYPE_GET_AVAILABLE_RANGE,
230 false,
231 0,
232 false,
233 false,
234 false);
235 }
236
237 // static
DoomOperation(SimpleEntryImpl * entry,const CompletionCallback & callback)238 SimpleEntryOperation SimpleEntryOperation::DoomOperation(
239 SimpleEntryImpl* entry,
240 const CompletionCallback& callback) {
241 net::IOBuffer* const buf = NULL;
242 Entry** const out_entry = NULL;
243 const int offset = 0;
244 const int64 sparse_offset = 0;
245 const int length = 0;
246 int64* const out_start = NULL;
247 const bool have_index = false;
248 const int index = 0;
249 const bool truncate = false;
250 const bool optimistic = false;
251 const bool alone_in_queue = false;
252 return SimpleEntryOperation(entry,
253 buf,
254 callback,
255 out_entry,
256 offset,
257 sparse_offset,
258 length,
259 out_start,
260 TYPE_DOOM,
261 have_index,
262 index,
263 truncate,
264 optimistic,
265 alone_in_queue);
266 }
267
ConflictsWith(const SimpleEntryOperation & other_op) const268 bool SimpleEntryOperation::ConflictsWith(
269 const SimpleEntryOperation& other_op) const {
270 EntryOperationType other_type = other_op.type();
271
272 // Non-read/write operations conflict with everything.
273 if (!IsReadWriteType(type_) || !IsReadWriteType(other_type))
274 return true;
275
276 // Reads (sparse or otherwise) conflict with nothing.
277 if (IsReadType(type_) && IsReadType(other_type))
278 return false;
279
280 // Sparse and non-sparse operations do not conflict with each other.
281 if (IsSparseType(type_) != IsSparseType(other_type)) {
282 return false;
283 }
284
285 // There must be two read/write operations, at least one must be a write, and
286 // they must be either both non-sparse or both sparse. Compare the streams
287 // and offsets to see whether they overlap.
288
289 if (IsSparseType(type_)) {
290 int64 end = sparse_offset_ + length_;
291 int64 other_op_end = other_op.sparse_offset() + other_op.length();
292 return sparse_offset_ < other_op_end && other_op.sparse_offset() < end;
293 }
294
295 if (index_ != other_op.index_)
296 return false;
297 int end = (type_ == TYPE_WRITE && truncate_) ? INT_MAX : offset_ + length_;
298 int other_op_end = (other_op.type() == TYPE_WRITE && other_op.truncate())
299 ? INT_MAX
300 : other_op.offset() + other_op.length();
301 return offset_ < other_op_end && other_op.offset() < end;
302 }
303
ReleaseReferences()304 void SimpleEntryOperation::ReleaseReferences() {
305 callback_ = CompletionCallback();
306 buf_ = NULL;
307 entry_ = NULL;
308 }
309
SimpleEntryOperation(SimpleEntryImpl * entry,net::IOBuffer * buf,const CompletionCallback & callback,Entry ** out_entry,int offset,int64 sparse_offset,int length,int64 * out_start,EntryOperationType type,bool have_index,int index,bool truncate,bool optimistic,bool alone_in_queue)310 SimpleEntryOperation::SimpleEntryOperation(SimpleEntryImpl* entry,
311 net::IOBuffer* buf,
312 const CompletionCallback& callback,
313 Entry** out_entry,
314 int offset,
315 int64 sparse_offset,
316 int length,
317 int64* out_start,
318 EntryOperationType type,
319 bool have_index,
320 int index,
321 bool truncate,
322 bool optimistic,
323 bool alone_in_queue)
324 : entry_(entry),
325 buf_(buf),
326 callback_(callback),
327 out_entry_(out_entry),
328 offset_(offset),
329 sparse_offset_(sparse_offset),
330 length_(length),
331 out_start_(out_start),
332 type_(type),
333 have_index_(have_index),
334 index_(index),
335 truncate_(truncate),
336 optimistic_(optimistic),
337 alone_in_queue_(alone_in_queue) {
338 }
339
340 } // namespace disk_cache
341