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
12namespace disk_cache {
13
14namespace {
15
16bool 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
23bool IsReadType(unsigned type) {
24  return type == SimpleEntryOperation::TYPE_READ ||
25         type == SimpleEntryOperation::TYPE_READ_SPARSE;
26}
27
28bool IsSparseType(unsigned type) {
29  return type == SimpleEntryOperation::TYPE_READ_SPARSE ||
30         type == SimpleEntryOperation::TYPE_WRITE_SPARSE;
31}
32
33}
34
35SimpleEntryOperation::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
52SimpleEntryOperation::~SimpleEntryOperation() {}
53
54// static
55SimpleEntryOperation 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
77SimpleEntryOperation 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
99SimpleEntryOperation 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
118SimpleEntryOperation 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
143SimpleEntryOperation 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
169SimpleEntryOperation 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
192SimpleEntryOperation 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
215SimpleEntryOperation 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
238SimpleEntryOperation 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
268bool 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
304void SimpleEntryOperation::ReleaseReferences() {
305  callback_ = CompletionCallback();
306  buf_ = NULL;
307  entry_ = NULL;
308}
309
310SimpleEntryOperation::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