// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "net/disk_cache/simple/simple_entry_operation.h" #include #include "base/logging.h" #include "net/base/io_buffer.h" #include "net/disk_cache/disk_cache.h" #include "net/disk_cache/simple/simple_entry_impl.h" namespace disk_cache { namespace { bool IsReadWriteType(unsigned int type) { return type == SimpleEntryOperation::TYPE_READ || type == SimpleEntryOperation::TYPE_WRITE || type == SimpleEntryOperation::TYPE_READ_SPARSE || type == SimpleEntryOperation::TYPE_WRITE_SPARSE; } bool IsReadType(unsigned type) { return type == SimpleEntryOperation::TYPE_READ || type == SimpleEntryOperation::TYPE_READ_SPARSE; } bool IsSparseType(unsigned type) { return type == SimpleEntryOperation::TYPE_READ_SPARSE || type == SimpleEntryOperation::TYPE_WRITE_SPARSE; } } // anonymous namespace SimpleEntryOperation::SimpleEntryOperation(const SimpleEntryOperation& other) : entry_(other.entry_.get()), buf_(other.buf_), callback_(other.callback_), out_entry_(other.out_entry_), offset_(other.offset_), sparse_offset_(other.sparse_offset_), length_(other.length_), out_start_(other.out_start_), type_(other.type_), have_index_(other.have_index_), index_(other.index_), truncate_(other.truncate_), optimistic_(other.optimistic_), alone_in_queue_(other.alone_in_queue_) { } SimpleEntryOperation::~SimpleEntryOperation() = default; // static SimpleEntryOperation SimpleEntryOperation::OpenOperation( SimpleEntryImpl* entry, bool have_index, const CompletionCallback& callback, Entry** out_entry) { return SimpleEntryOperation(entry, NULL, callback, out_entry, 0, 0, 0, NULL, TYPE_OPEN, have_index, 0, false, false, false); } // static SimpleEntryOperation SimpleEntryOperation::CreateOperation( SimpleEntryImpl* entry, bool have_index, const CompletionCallback& callback, Entry** out_entry) { return SimpleEntryOperation(entry, NULL, callback, out_entry, 0, 0, 0, NULL, TYPE_CREATE, have_index, 0, false, false, false); } // static SimpleEntryOperation SimpleEntryOperation::CloseOperation( SimpleEntryImpl* entry) { return SimpleEntryOperation(entry, NULL, CompletionCallback(), NULL, 0, 0, 0, NULL, TYPE_CLOSE, false, 0, false, false, false); } // static SimpleEntryOperation SimpleEntryOperation::ReadOperation( SimpleEntryImpl* entry, int index, int offset, int length, net::IOBuffer* buf, const CompletionCallback& callback, bool alone_in_queue) { return SimpleEntryOperation(entry, buf, callback, NULL, offset, 0, length, NULL, TYPE_READ, false, index, false, false, alone_in_queue); } // static SimpleEntryOperation SimpleEntryOperation::WriteOperation( SimpleEntryImpl* entry, int index, int offset, int length, net::IOBuffer* buf, bool truncate, bool optimistic, const CompletionCallback& callback) { return SimpleEntryOperation(entry, buf, callback, NULL, offset, 0, length, NULL, TYPE_WRITE, false, index, truncate, optimistic, false); } // static SimpleEntryOperation SimpleEntryOperation::ReadSparseOperation( SimpleEntryImpl* entry, int64_t sparse_offset, int length, net::IOBuffer* buf, const CompletionCallback& callback) { return SimpleEntryOperation(entry, buf, callback, NULL, 0, sparse_offset, length, NULL, TYPE_READ_SPARSE, false, 0, false, false, false); } // static SimpleEntryOperation SimpleEntryOperation::WriteSparseOperation( SimpleEntryImpl* entry, int64_t sparse_offset, int length, net::IOBuffer* buf, const CompletionCallback& callback) { return SimpleEntryOperation(entry, buf, callback, NULL, 0, sparse_offset, length, NULL, TYPE_WRITE_SPARSE, false, 0, false, false, false); } // static SimpleEntryOperation SimpleEntryOperation::GetAvailableRangeOperation( SimpleEntryImpl* entry, int64_t sparse_offset, int length, int64_t* out_start, const CompletionCallback& callback) { return SimpleEntryOperation(entry, NULL, callback, NULL, 0, sparse_offset, length, out_start, TYPE_GET_AVAILABLE_RANGE, false, 0, false, false, false); } // static SimpleEntryOperation SimpleEntryOperation::DoomOperation( SimpleEntryImpl* entry, const CompletionCallback& callback) { net::IOBuffer* const buf = NULL; Entry** const out_entry = NULL; const int offset = 0; const int64_t sparse_offset = 0; const int length = 0; int64_t* const out_start = NULL; const bool have_index = false; const int index = 0; const bool truncate = false; const bool optimistic = false; const bool alone_in_queue = false; return SimpleEntryOperation(entry, buf, callback, out_entry, offset, sparse_offset, length, out_start, TYPE_DOOM, have_index, index, truncate, optimistic, alone_in_queue); } bool SimpleEntryOperation::ConflictsWith( const SimpleEntryOperation& other_op) const { EntryOperationType other_type = other_op.type(); // Non-read/write operations conflict with everything. if (!IsReadWriteType(type_) || !IsReadWriteType(other_type)) return true; // Reads (sparse or otherwise) conflict with nothing. if (IsReadType(type_) && IsReadType(other_type)) return false; // Sparse and non-sparse operations do not conflict with each other. if (IsSparseType(type_) != IsSparseType(other_type)) { return false; } // There must be two read/write operations, at least one must be a write, and // they must be either both non-sparse or both sparse. Compare the streams // and offsets to see whether they overlap. if (IsSparseType(type_)) { int64_t end = sparse_offset_ + length_; int64_t other_op_end = other_op.sparse_offset() + other_op.length(); return sparse_offset_ < other_op_end && other_op.sparse_offset() < end; } if (index_ != other_op.index_) return false; int end = (type_ == TYPE_WRITE && truncate_) ? INT_MAX : offset_ + length_; int other_op_end = (other_op.type() == TYPE_WRITE && other_op.truncate()) ? INT_MAX : other_op.offset() + other_op.length(); return offset_ < other_op_end && other_op.offset() < end; } void SimpleEntryOperation::ReleaseReferences() { callback_ = CompletionCallback(); buf_ = NULL; entry_ = NULL; } SimpleEntryOperation::SimpleEntryOperation(SimpleEntryImpl* entry, net::IOBuffer* buf, const CompletionCallback& callback, Entry** out_entry, int offset, int64_t sparse_offset, int length, int64_t* out_start, EntryOperationType type, bool have_index, int index, bool truncate, bool optimistic, bool alone_in_queue) : entry_(entry), buf_(buf), callback_(callback), out_entry_(out_entry), offset_(offset), sparse_offset_(sparse_offset), length_(length), out_start_(out_start), type_(type), have_index_(have_index), index_(index), truncate_(truncate), optimistic_(optimistic), alone_in_queue_(alone_in_queue) {} } // namespace disk_cache