| Index: net/disk_cache/v3/sparse_control_v3.cc
|
| ===================================================================
|
| --- net/disk_cache/v3/sparse_control_v3.cc (revision 0)
|
| +++ net/disk_cache/v3/sparse_control_v3.cc (working copy)
|
| @@ -140,6 +140,8 @@
|
| FROM_HERE, base::Bind(&ChildrenDeleter::DeleteChildren, this));
|
| }
|
|
|
| +// -----------------------------------------------------------------------
|
| +
|
| // Returns the NetLog event type corresponding to a SparseOperation.
|
| net::NetLog::EventType GetSparseEventType(
|
| disk_cache::SparseControl::SparseOperation operation) {
|
| @@ -210,27 +212,6 @@
|
| WriteSparseData();
|
| }
|
|
|
| -int SparseControl::Init() {
|
| - DCHECK(!init_);
|
| -
|
| - // We should not have sparse data for the exposed entry.
|
| - if (entry_->GetDataSize(kSparseData))
|
| - return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
|
| -
|
| - // Now see if there is something where we store our data.
|
| - int rv = net::OK;
|
| - int data_len = entry_->GetDataSize(kSparseIndex);
|
| - if (!data_len) {
|
| - rv = CreateSparseEntry();
|
| - } else {
|
| - rv = OpenSparseEntry(data_len);
|
| - }
|
| -
|
| - if (rv == net::OK)
|
| - init_ = true;
|
| - return rv;
|
| -}
|
| -
|
| bool SparseControl::CouldBeSparse() const {
|
| DCHECK(!init_);
|
|
|
| @@ -367,6 +348,29 @@
|
| }
|
| }
|
|
|
| +// -----------------------------------------------------------------------
|
| +
|
| +int SparseControl::Init() {
|
| + DCHECK(!init_);
|
| +
|
| + // We should not have sparse data for the exposed entry.
|
| + if (entry_->GetDataSize(kSparseData))
|
| + return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
|
| +
|
| + // Now see if there is something where we store our data.
|
| + int rv = net::OK;
|
| + int data_len = entry_->GetDataSize(kSparseIndex);
|
| + if (!data_len) {
|
| + rv = CreateSparseEntry();
|
| + } else {
|
| + rv = OpenSparseEntry(data_len);
|
| + }
|
| +
|
| + if (rv == net::OK)
|
| + init_ = true;
|
| + return rv;
|
| +}
|
| +
|
| // We are going to start using this entry to store sparse data, so we have to
|
| // initialize our control info.
|
| int SparseControl::CreateSparseEntry() {
|
| @@ -505,24 +509,6 @@
|
| child_ = NULL;
|
| }
|
|
|
| -std::string SparseControl::GenerateChildKey() {
|
| - return GenerateChildName(entry_->GetKey(), sparse_header_.signature,
|
| - offset_ >> 20);
|
| -}
|
| -
|
| -// We are deleting the child because something went wrong.
|
| -bool SparseControl::KillChildAndContinue(const std::string& key, bool fatal) {
|
| - SetChildBit(false);
|
| - child_->DoomImpl();
|
| - child_->Release();
|
| - child_ = NULL;
|
| - if (fatal) {
|
| - result_ = net::ERR_CACHE_READ_FAILURE;
|
| - return false;
|
| - }
|
| - return ContinueWithoutChild(key);
|
| -}
|
| -
|
| // We were not able to open this child; see what we can do.
|
| bool SparseControl::ContinueWithoutChild(const std::string& key) {
|
| if (kReadOperation == operation_)
|
| @@ -544,6 +530,121 @@
|
| return true;
|
| }
|
|
|
| +void SparseControl::WriteSparseData() {
|
| + scoped_refptr<net::IOBuffer> buf(new net::WrappedIOBuffer(
|
| + reinterpret_cast<const char*>(children_map_.GetMap())));
|
| +
|
| + int len = children_map_.ArraySize() * 4;
|
| + int rv = entry_->WriteData(kSparseIndex, sizeof(sparse_header_), buf, len,
|
| + CompletionCallback(), false);
|
| + if (rv != len) {
|
| + DLOG(ERROR) << "Unable to save sparse map";
|
| + }
|
| +}
|
| +
|
| +bool SparseControl::DoChildIO() {
|
| + finished_ = true;
|
| + if (!buf_len_ || result_ < 0)
|
| + return false;
|
| +
|
| + if (!OpenChild())
|
| + return false;
|
| +
|
| + if (!VerifyRange())
|
| + return false;
|
| +
|
| + // We have more work to do. Let's not trigger a callback to the caller.
|
| + finished_ = false;
|
| + CompletionCallback callback;
|
| + if (!user_callback_.is_null()) {
|
| + callback =
|
| + base::Bind(&SparseControl::OnChildIOCompleted, base::Unretained(this));
|
| + }
|
| +
|
| + int rv = 0;
|
| + switch (operation_) {
|
| + case kReadOperation:
|
| + if (entry_->net_log().IsLoggingAllEvents()) {
|
| + entry_->net_log().BeginEvent(
|
| + net::NetLog::TYPE_SPARSE_READ_CHILD_DATA,
|
| + CreateNetLogSparseReadWriteCallback(child_->net_log().source(),
|
| + child_len_));
|
| + }
|
| + rv = child_->ReadDataImpl(kSparseData, child_offset_, user_buf_,
|
| + child_len_, callback);
|
| + break;
|
| + case kWriteOperation:
|
| + if (entry_->net_log().IsLoggingAllEvents()) {
|
| + entry_->net_log().BeginEvent(
|
| + net::NetLog::TYPE_SPARSE_WRITE_CHILD_DATA,
|
| + CreateNetLogSparseReadWriteCallback(child_->net_log().source(),
|
| + child_len_));
|
| + }
|
| + rv = child_->WriteDataImpl(kSparseData, child_offset_, user_buf_,
|
| + child_len_, callback, false);
|
| + break;
|
| + case kGetRangeOperation:
|
| + rv = DoGetAvailableRange();
|
| + break;
|
| + default:
|
| + NOTREACHED();
|
| + }
|
| +
|
| + if (rv == net::ERR_IO_PENDING) {
|
| + if (!pending_) {
|
| + pending_ = true;
|
| + // The child will protect himself against closing the entry while IO is in
|
| + // progress. However, this entry can still be closed, and that would not
|
| + // be a good thing for us, so we increase the refcount until we're
|
| + // finished doing sparse stuff.
|
| + entry_->AddRef(); // Balanced in DoUserCallback.
|
| + }
|
| + return false;
|
| + }
|
| + if (!rv)
|
| + return false;
|
| +
|
| + DoChildIOCompleted(rv);
|
| + return true;
|
| +}
|
| +
|
| +void SparseControl::DoChildIOCompleted(int result) {
|
| + LogChildOperationEnd(entry_->net_log(), operation_, result);
|
| + if (result < 0) {
|
| + // We fail the whole operation if we encounter an error.
|
| + result_ = result;
|
| + return;
|
| + }
|
| +
|
| + UpdateRange(result);
|
| +
|
| + result_ += result;
|
| + offset_ += result;
|
| + buf_len_ -= result;
|
| +
|
| + // We'll be reusing the user provided buffer for the next chunk.
|
| + if (buf_len_ && user_buf_)
|
| + user_buf_->DidConsume(result);
|
| +}
|
| +
|
| +std::string SparseControl::GenerateChildKey() {
|
| + return GenerateChildName(entry_->GetKey(), sparse_header_.signature,
|
| + offset_ >> 20);
|
| +}
|
| +
|
| +// We are deleting the child because something went wrong.
|
| +bool SparseControl::KillChildAndContinue(const std::string& key, bool fatal) {
|
| + SetChildBit(false);
|
| + child_->DoomImpl();
|
| + child_->Release();
|
| + child_ = NULL;
|
| + if (fatal) {
|
| + result_ = net::ERR_CACHE_READ_FAILURE;
|
| + return false;
|
| + }
|
| + return ContinueWithoutChild(key);
|
| +}
|
| +
|
| bool SparseControl::ChildPresent() {
|
| int child_bit = static_cast<int>(offset_ >> 20);
|
| if (children_map_.Size() <= child_bit)
|
| @@ -562,18 +663,6 @@
|
| children_map_.Set(child_bit, value);
|
| }
|
|
|
| -void SparseControl::WriteSparseData() {
|
| - scoped_refptr<net::IOBuffer> buf(new net::WrappedIOBuffer(
|
| - reinterpret_cast<const char*>(children_map_.GetMap())));
|
| -
|
| - int len = children_map_.ArraySize() * 4;
|
| - int rv = entry_->WriteData(kSparseIndex, sizeof(sparse_header_), buf, len,
|
| - CompletionCallback(), false);
|
| - if (rv != len) {
|
| - DLOG(ERROR) << "Unable to save sparse map";
|
| - }
|
| -}
|
| -
|
| bool SparseControl::VerifyRange() {
|
| DCHECK_GE(result_, 0);
|
|
|
| @@ -678,93 +767,6 @@
|
| SetChildBit(true);
|
| }
|
|
|
| -void SparseControl::DoChildrenIO() {
|
| - while (DoChildIO()) continue;
|
| -
|
| - // Range operations are finished synchronously, often without setting
|
| - // |finished_| to true.
|
| - if (kGetRangeOperation == operation_ &&
|
| - entry_->net_log().IsLoggingAllEvents()) {
|
| - entry_->net_log().EndEvent(
|
| - net::NetLog::TYPE_SPARSE_GET_RANGE,
|
| - CreateNetLogGetAvailableRangeResultCallback(offset_, result_));
|
| - }
|
| - if (finished_) {
|
| - if (kGetRangeOperation != operation_ &&
|
| - entry_->net_log().IsLoggingAllEvents()) {
|
| - entry_->net_log().EndEvent(GetSparseEventType(operation_));
|
| - }
|
| - if (pending_)
|
| - DoUserCallback(); // Don't touch this object after this point.
|
| - }
|
| -}
|
| -
|
| -bool SparseControl::DoChildIO() {
|
| - finished_ = true;
|
| - if (!buf_len_ || result_ < 0)
|
| - return false;
|
| -
|
| - if (!OpenChild())
|
| - return false;
|
| -
|
| - if (!VerifyRange())
|
| - return false;
|
| -
|
| - // We have more work to do. Let's not trigger a callback to the caller.
|
| - finished_ = false;
|
| - CompletionCallback callback;
|
| - if (!user_callback_.is_null()) {
|
| - callback =
|
| - base::Bind(&SparseControl::OnChildIOCompleted, base::Unretained(this));
|
| - }
|
| -
|
| - int rv = 0;
|
| - switch (operation_) {
|
| - case kReadOperation:
|
| - if (entry_->net_log().IsLoggingAllEvents()) {
|
| - entry_->net_log().BeginEvent(
|
| - net::NetLog::TYPE_SPARSE_READ_CHILD_DATA,
|
| - CreateNetLogSparseReadWriteCallback(child_->net_log().source(),
|
| - child_len_));
|
| - }
|
| - rv = child_->ReadDataImpl(kSparseData, child_offset_, user_buf_,
|
| - child_len_, callback);
|
| - break;
|
| - case kWriteOperation:
|
| - if (entry_->net_log().IsLoggingAllEvents()) {
|
| - entry_->net_log().BeginEvent(
|
| - net::NetLog::TYPE_SPARSE_WRITE_CHILD_DATA,
|
| - CreateNetLogSparseReadWriteCallback(child_->net_log().source(),
|
| - child_len_));
|
| - }
|
| - rv = child_->WriteDataImpl(kSparseData, child_offset_, user_buf_,
|
| - child_len_, callback, false);
|
| - break;
|
| - case kGetRangeOperation:
|
| - rv = DoGetAvailableRange();
|
| - break;
|
| - default:
|
| - NOTREACHED();
|
| - }
|
| -
|
| - if (rv == net::ERR_IO_PENDING) {
|
| - if (!pending_) {
|
| - pending_ = true;
|
| - // The child will protect himself against closing the entry while IO is in
|
| - // progress. However, this entry can still be closed, and that would not
|
| - // be a good thing for us, so we increase the refcount until we're
|
| - // finished doing sparse stuff.
|
| - entry_->AddRef(); // Balanced in DoUserCallback.
|
| - }
|
| - return false;
|
| - }
|
| - if (!rv)
|
| - return false;
|
| -
|
| - DoChildIOCompleted(rv);
|
| - return true;
|
| -}
|
| -
|
| int SparseControl::DoGetAvailableRange() {
|
| if (!child_)
|
| return child_len_; // Move on to the next child.
|
| @@ -812,23 +814,29 @@
|
| return 0;
|
| }
|
|
|
| -void SparseControl::DoChildIOCompleted(int result) {
|
| - LogChildOperationEnd(entry_->net_log(), operation_, result);
|
| - if (result < 0) {
|
| - // We fail the whole operation if we encounter an error.
|
| - result_ = result;
|
| - return;
|
| - }
|
| +void SparseControl::DoUserCallback() {
|
| + DCHECK(!user_callback_.is_null());
|
| + CompletionCallback cb = user_callback_;
|
| + user_callback_.Reset();
|
| + user_buf_ = NULL;
|
| + pending_ = false;
|
| + operation_ = kNoOperation;
|
| + int rv = result_;
|
| + entry_->Release(); // Don't touch object after this line.
|
| + cb.Run(rv);
|
| +}
|
|
|
| - UpdateRange(result);
|
| +void SparseControl::DoAbortCallbacks() {
|
| + for (size_t i = 0; i < abort_callbacks_.size(); i++) {
|
| + // Releasing all references to entry_ may result in the destruction of this
|
| + // object so we should not be touching it after the last Release().
|
| + CompletionCallback cb = abort_callbacks_[i];
|
| + if (i == abort_callbacks_.size() - 1)
|
| + abort_callbacks_.clear();
|
|
|
| - result_ += result;
|
| - offset_ += result;
|
| - buf_len_ -= result;
|
| -
|
| - // We'll be reusing the user provided buffer for the next chunk.
|
| - if (buf_len_ && user_buf_)
|
| - user_buf_->DidConsume(result);
|
| + entry_->Release(); // Don't touch object after this line.
|
| + cb.Run(net::OK);
|
| + }
|
| }
|
|
|
| void SparseControl::OnChildIOCompleted(int result) {
|
| @@ -858,29 +866,4 @@
|
| DoChildrenIO();
|
| }
|
|
|
| -void SparseControl::DoUserCallback() {
|
| - DCHECK(!user_callback_.is_null());
|
| - CompletionCallback cb = user_callback_;
|
| - user_callback_.Reset();
|
| - user_buf_ = NULL;
|
| - pending_ = false;
|
| - operation_ = kNoOperation;
|
| - int rv = result_;
|
| - entry_->Release(); // Don't touch object after this line.
|
| - cb.Run(rv);
|
| -}
|
| -
|
| -void SparseControl::DoAbortCallbacks() {
|
| - for (size_t i = 0; i < abort_callbacks_.size(); i++) {
|
| - // Releasing all references to entry_ may result in the destruction of this
|
| - // object so we should not be touching it after the last Release().
|
| - CompletionCallback cb = abort_callbacks_[i];
|
| - if (i == abort_callbacks_.size() - 1)
|
| - abort_callbacks_.clear();
|
| -
|
| - entry_->Release(); // Don't touch object after this line.
|
| - cb.Run(net::OK);
|
| - }
|
| -}
|
| -
|
| } // namespace disk_cache
|
|
|