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 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 23 bool IsReadType(unsigned type) { 24 return type == SimpleEntryOperation::TYPE_READ || 25 type == SimpleEntryOperation::TYPE_READ_SPARSE; 26 } 27 28 bool IsSparseType(unsigned type) { 29 return type == SimpleEntryOperation::TYPE_READ_SPARSE || 30 type == SimpleEntryOperation::TYPE_WRITE_SPARSE; 31 } 32 33 } 34 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 52 SimpleEntryOperation::~SimpleEntryOperation() {} 53 54 // static 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 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 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 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 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 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 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 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 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 268 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 304 void SimpleEntryOperation::ReleaseReferences() { 305 callback_ = CompletionCallback(); 306 buf_ = NULL; 307 entry_ = NULL; 308 } 309 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