summaryrefslogtreecommitdiffstats
path: root/net/disk_cache/mem_entry_impl.cc
diff options
context:
space:
mode:
authorscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-25 23:48:05 +0000
committerscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-25 23:48:05 +0000
commit05d94e79f64a6562ea646e5b3f2e9c6e7b1cc011 (patch)
treec864cb5adf9385d1796cb121029421bcdcb93050 /net/disk_cache/mem_entry_impl.cc
parent92d9cade98d356a2f12be8c633f8de1e750b876b (diff)
downloadchromium_src-05d94e79f64a6562ea646e5b3f2e9c6e7b1cc011.zip
chromium_src-05d94e79f64a6562ea646e5b3f2e9c6e7b1cc011.tar.gz
chromium_src-05d94e79f64a6562ea646e5b3f2e9c6e7b1cc011.tar.bz2
Revert "Implementation for memory only sparse caching" r19270.
TBR=rvargas TEST=none BUG=none Review URL: http://codereview.chromium.org/149041 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19308 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/disk_cache/mem_entry_impl.cc')
-rw-r--r--net/disk_cache/mem_entry_impl.cc310
1 files changed, 33 insertions, 277 deletions
diff --git a/net/disk_cache/mem_entry_impl.cc b/net/disk_cache/mem_entry_impl.cc
index bf6359d..4905785 100644
--- a/net/disk_cache/mem_entry_impl.cc
+++ b/net/disk_cache/mem_entry_impl.cc
@@ -11,28 +11,6 @@
using base::Time;
-namespace {
-
-const int kSparseData = 1;
-
-// Maximum size of a sparse entry is 2 to the power of this number.
-const int kMaxSparseEntryBits = 12;
-
-// Sparse entry has maximum size of 4KB.
-const int kMaxSparseEntrySize = 1 << kMaxSparseEntryBits;
-
-// Convert global offset to child index.
-inline int ToChildIndex(int64 offset) {
- return static_cast<int>(offset >> kMaxSparseEntryBits);
-}
-
-// Convert global offset to offset in child entry.
-inline int ToChildOffset(int64 offset) {
- return static_cast<int>(offset & (kMaxSparseEntrySize - 1));
-}
-
-} // nemespace
-
namespace disk_cache {
MemEntryImpl::MemEntryImpl(MemBackendImpl* backend) {
@@ -40,8 +18,6 @@ MemEntryImpl::MemEntryImpl(MemBackendImpl* backend) {
backend_ = backend;
ref_count_ = 0;
parent_ = NULL;
- child_id_ = 0;
- child_first_pos_ = 0;
next_ = NULL;
prev_ = NULL;
for (int i = 0; i < NUM_STREAMS; i++)
@@ -58,14 +34,25 @@ bool MemEntryImpl::CreateEntry(const std::string& key) {
key_ = key;
last_modified_ = Time::Now();
last_used_ = Time::Now();
+ type_ = kParentEntry;
Open();
backend_->ModifyStorageSize(0, static_cast<int32>(key.size()));
return true;
}
+bool MemEntryImpl::CreateChildEntry(MemEntryImpl* parent) {
+ parent_ = parent;
+ last_modified_ = Time::Now();
+ last_used_ = Time::Now();
+ type_ = kChildEntry;
+ // Insert this to the backend's ranking list.
+ backend_->InsertIntoRankingList(this);
+ return true;
+}
+
void MemEntryImpl::Close() {
// Only a parent entry can be closed.
- DCHECK(type() == kParentEntry);
+ DCHECK(type_ == kParentEntry);
ref_count_--;
DCHECK(ref_count_ >= 0);
if (!ref_count_ && doomed_)
@@ -74,16 +61,14 @@ void MemEntryImpl::Close() {
void MemEntryImpl::Open() {
// Only a parent entry can be opened.
- // TODO(hclam): make sure it's correct to not apply the concept of ref
- // counting to child entry.
- DCHECK(type() == kParentEntry);
+ DCHECK(type_ == kParentEntry);
ref_count_++;
DCHECK(ref_count_ >= 0);
DCHECK(!doomed_);
}
bool MemEntryImpl::InUse() {
- if (type() == kParentEntry) {
+ if (type_ == kParentEntry) {
return ref_count_ > 0;
} else {
// A child entry is always not in use. The consequence is that a child entry
@@ -96,11 +81,11 @@ bool MemEntryImpl::InUse() {
void MemEntryImpl::Doom() {
if (doomed_)
return;
- if (type() == kParentEntry) {
+ if (type_ == kParentEntry) {
// Perform internal doom from the backend if this is a parent entry.
backend_->InternalDoomEntry(this);
} else {
- // Manually detach from the backend and perform internal doom.
+ // Manually detach from the parent entry and perform internal doom.
backend_->RemoveFromRankingList(this);
InternalDoom();
}
@@ -109,23 +94,10 @@ void MemEntryImpl::Doom() {
void MemEntryImpl::InternalDoom() {
doomed_ = true;
if (!ref_count_) {
- if (type() == kParentEntry) {
- // If this is a parent entry, we need to doom all the child entries.
- if (children_.get()) {
- EntryMap children;
- children.swap(*children_);
- for (EntryMap::iterator i = children.begin();
- i != children.end(); ++i) {
- // Since a pointer to this object is also saved in the map, avoid
- // dooming it.
- if (i->second != this)
- i->second->Doom();
- }
- DCHECK(children_->size() == 0);
- }
+ if (type_ == kParentEntry) {
+ // TODO(hclam): doom all child entries associated with this entry.
} else {
- // If this is a child entry, detach it from the parent.
- parent_->DetachChild(child_id_);
+ // TODO(hclam): detach this child entry from the parent entry.
}
delete this;
}
@@ -133,7 +105,7 @@ void MemEntryImpl::InternalDoom() {
std::string MemEntryImpl::GetKey() const {
// A child entry doesn't have key so this method should not be called.
- DCHECK(type() == kParentEntry);
+ DCHECK(type_ == kParentEntry);
return key_;
}
@@ -148,12 +120,16 @@ Time MemEntryImpl::GetLastModified() const {
int32 MemEntryImpl::GetDataSize(int index) const {
if (index < 0 || index >= NUM_STREAMS)
return 0;
+
+ // TODO(hclam): handle the case when this is a parent entry and has associated
+ // child entries.
return data_size_[index];
}
int MemEntryImpl::ReadData(int index, int offset, net::IOBuffer* buf,
int buf_len, net::CompletionCallback* completion_callback) {
- DCHECK(type() == kParentEntry || index == kSparseData);
+ // This method can only be called with a parent entry.
+ DCHECK(type_ == kParentEntry);
if (index < 0 || index >= NUM_STREAMS)
return net::ERR_INVALID_ARGUMENT;
@@ -176,7 +152,8 @@ int MemEntryImpl::ReadData(int index, int offset, net::IOBuffer* buf,
int MemEntryImpl::WriteData(int index, int offset, net::IOBuffer* buf,
int buf_len, net::CompletionCallback* completion_callback, bool truncate) {
- DCHECK(type() == kParentEntry || index == kSparseData);
+ // This method can only be called with a parent entry.
+ DCHECK(type_ == kParentEntry);
if (index < 0 || index >= NUM_STREAMS)
return net::ERR_INVALID_ARGUMENT;
@@ -189,6 +166,9 @@ int MemEntryImpl::WriteData(int index, int offset, net::IOBuffer* buf,
// offset of buf_len could be negative numbers.
if (offset > max_file_size || buf_len > max_file_size ||
offset + buf_len > max_file_size) {
+ int size = offset + buf_len;
+ if (size <= max_file_size)
+ size = kint32max;
return net::ERR_FAILED;
}
@@ -218,160 +198,16 @@ int MemEntryImpl::WriteData(int index, int offset, net::IOBuffer* buf,
int MemEntryImpl::ReadSparseData(int64 offset, net::IOBuffer* buf, int buf_len,
net::CompletionCallback* completion_callback) {
- DCHECK(type() == kParentEntry);
-
- if (!InitSparseInfo())
- return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
-
- if (offset < 0 || buf_len < 0 || !buf_len)
- return net::ERR_INVALID_ARGUMENT;
-
- // We will keep using this buffer and adjust the offset in this buffer.
- scoped_refptr<net::ReusedIOBuffer> io_buf = new net::ReusedIOBuffer(buf,
- buf_len);
-
- // Counts the number of bytes read.
- int bytes_read = 0;
-
- // Iterate until we have read enough.
- while (bytes_read < buf_len) {
- MemEntryImpl* child = OpenChild(offset + bytes_read, false);
-
- // No child present for that offset.
- if (!child)
- break;
-
- // We then need to prepare the child offset and len.
- int child_offset = ToChildOffset(offset + bytes_read);
-
- // If we are trying to read from a position that the child entry has no data
- // we should stop.
- if (child_offset < child->child_first_pos_)
- break;
- int ret = child->ReadData(kSparseData, child_offset, io_buf,
- buf_len - bytes_read, NULL);
-
- // If we encounter an error in one entry, return immediately.
- if (ret < 0)
- return ret;
- else if (ret == 0)
- break;
-
- // Increment the counter by number of bytes read in the child entry.
- bytes_read += ret;
- // And also adjust the buffer's offset.
- if (bytes_read < buf_len)
- io_buf->SetOffset(bytes_read);
- }
-
- UpdateRank(false);
-
- return bytes_read;
+ return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
}
int MemEntryImpl::WriteSparseData(int64 offset, net::IOBuffer* buf, int buf_len,
net::CompletionCallback* completion_callback) {
- DCHECK(type() == kParentEntry);
-
- if (!InitSparseInfo())
- return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
-
- if (offset < 0 || buf_len < 0)
- return net::ERR_INVALID_ARGUMENT;
-
- scoped_refptr<net::ReusedIOBuffer> io_buf = new net::ReusedIOBuffer(buf,
- buf_len);
- // Counter for amount of bytes written.
- int bytes_written = 0;
-
- // This loop walks through child entries continuously starting from |offset|
- // and writes blocks of data (of maximum size kMaxSparseEntrySize) into each
- // child entry until all |buf_len| bytes are written. The write operation can
- // start in the middle of an entry.
- while (bytes_written < buf_len) {
- MemEntryImpl* child = OpenChild(offset + bytes_written, true);
- int child_offset = ToChildOffset(offset + bytes_written);
-
- // Find the right amount to write, this evaluates the remaining bytes to
- // write and remaining capacity of this child entry.
- int write_len = std::min(buf_len - bytes_written,
- kMaxSparseEntrySize - child_offset);
-
- // Keep a record of the last byte position (exclusive) in the child.
- int data_size = child->GetDataSize(kSparseData);
-
- // Always writes to the child entry. This operation may overwrite data
- // previously written.
- // TODO(hclam): if there is data in the entry and this write is not
- // continuous we may want to discard this write.
- int ret = child->WriteData(kSparseData, child_offset, io_buf, write_len,
- NULL, true);
- if (ret < 0)
- return ret;
- else if (ret == 0)
- break;
-
- // Keep a record of the first byte position in the child if the write was
- // not aligned nor continuous. This is to enable witting to the middle
- // of an entry and still keep track of data off the aligned edge.
- if (data_size != child_offset)
- child->child_first_pos_ = child_offset;
-
- // Increment the counter.
- bytes_written += ret;
-
- // And adjust the offset in the IO buffer.
- if (bytes_written < buf_len)
- io_buf->SetOffset(bytes_written);
- }
-
- UpdateRank(true);
-
- return bytes_written;
+ return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
}
int MemEntryImpl::GetAvailableRange(int64 offset, int len, int64* start) {
- DCHECK(type() == kParentEntry);
- DCHECK(start);
-
- if (!InitSparseInfo())
- return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
-
- if (offset < 0 || len < 0 || !start)
- return net::ERR_INVALID_ARGUMENT;
-
- MemEntryImpl* current_child = NULL;
-
- // Find the first child and record the number of empty bytes.
- int empty = FindNextChild(offset, len, &current_child);
- if (current_child) {
- *start = offset + empty;
- len -= empty;
-
- // Counts the number of continuous bytes.
- int continuous = 0;
-
- // This loop scan for continuous bytes.
- while (len && current_child) {
- // Number of bytes available in this child.
- int data_size = current_child->GetDataSize(kSparseData) -
- ToChildOffset(*start + continuous);
- if (data_size > len)
- data_size = len;
-
- // We have found more continuous bytes so increment the count. Also
- // decrement the length we should scan.
- continuous += data_size;
- len -= data_size;
-
- // If the next child is discontinuous, break the loop.
- if (FindNextChild(*start + continuous, len, &current_child))
- break;
- }
- return continuous;
- }
- *start = offset;
- return 0;
+ return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
}
void MemEntryImpl::PrepareTarget(int index, int offset, int buf_len) {
@@ -402,84 +238,4 @@ void MemEntryImpl::UpdateRank(bool modified) {
backend_->UpdateRank(this);
}
-bool MemEntryImpl::InitSparseInfo() {
- DCHECK(type() == kParentEntry);
-
- if (!children_.get()) {
- // If we already have some data in sparse stream but we are being
- // initialized as a sparse entry, we should fail.
- if (GetDataSize(kSparseData))
- return false;
- children_.reset(new EntryMap());
-
- // The parent entry stores data for the first block, so save this object to
- // index 0.
- (*children_)[0] = this;
- }
- return true;
-}
-
-bool MemEntryImpl::InitChildEntry(MemEntryImpl* parent, int child_id) {
- DCHECK(!parent_);
- DCHECK(!child_id_);
- parent_ = parent;
- child_id_ = child_id;
- last_modified_ = Time::Now();
- last_used_ = Time::Now();
- // Insert this to the backend's ranking list.
- backend_->InsertIntoRankingList(this);
- return true;
-}
-
-MemEntryImpl* MemEntryImpl::OpenChild(int64 offset, bool create) {
- DCHECK(type() == kParentEntry);
- int index = ToChildIndex(offset);
- EntryMap::iterator i = children_->find(index);
- if (i != children_->end()) {
- return i->second;
- } else if (create) {
- MemEntryImpl* child = new MemEntryImpl(backend_);
- child->InitChildEntry(this, index);
- (*children_)[index] = child;
- return child;
- }
- return NULL;
-}
-
-int MemEntryImpl::FindNextChild(int64 offset, int len, MemEntryImpl** child) {
- DCHECK(child);
- *child = NULL;
- int scanned_len = 0;
-
- // This loop tries to find the first existing child.
- while (scanned_len < len) {
- // This points to the current offset in the child.
- int current_child_offset = ToChildOffset(offset + scanned_len);
- MemEntryImpl* current_child = OpenChild(offset + scanned_len, false);
- if (current_child) {
- int child_first_pos = current_child->child_first_pos_;
-
- // This points to the first byte that we should be reading from, we need
- // to take care of the filled region and the current offset in the child.
- int first_pos = std::max(current_child_offset, child_first_pos);
-
- // If the first byte position we should read from doesn't exceed the
- // filled region, we have found the first child.
- if (first_pos < current_child->GetDataSize(kSparseData)) {
- *child = current_child;
-
- // We need to advance the scanned length.
- scanned_len += first_pos - current_child_offset;
- break;
- }
- }
- scanned_len += kMaxSparseEntrySize - current_child_offset;
- }
- return scanned_len;
-}
-
-void MemEntryImpl::DetachChild(int child_id) {
- children_->erase(child_id);
-}
-
} // namespace disk_cache