summaryrefslogtreecommitdiff
path: root/chromium/net/disk_cache/flash/segment.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/disk_cache/flash/segment.cc')
-rw-r--r--chromium/net/disk_cache/flash/segment.cc122
1 files changed, 122 insertions, 0 deletions
diff --git a/chromium/net/disk_cache/flash/segment.cc b/chromium/net/disk_cache/flash/segment.cc
new file mode 100644
index 00000000000..3457497a22f
--- /dev/null
+++ b/chromium/net/disk_cache/flash/segment.cc
@@ -0,0 +1,122 @@
+// Copyright (c) 2012 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 <algorithm>
+
+#include "base/logging.h"
+#include "net/disk_cache/flash/format.h"
+#include "net/disk_cache/flash/segment.h"
+#include "net/disk_cache/flash/storage.h"
+
+namespace disk_cache {
+
+Segment::Segment(int32 index, bool read_only, Storage* storage)
+ : index_(index),
+ num_users_(0),
+ read_only_(read_only),
+ init_(false),
+ storage_(storage),
+ offset_(index * kFlashSegmentSize),
+ summary_offset_(offset_ + kFlashSegmentSize - kFlashSummarySize),
+ write_offset_(offset_) {
+ DCHECK(storage);
+ DCHECK(storage->size() % kFlashSegmentSize == 0);
+}
+
+Segment::~Segment() {
+ DCHECK(!init_ || read_only_);
+ if (num_users_ != 0)
+ LOG(WARNING) << "Users exist, but we don't care? " << num_users_;
+}
+
+bool Segment::HaveOffset(int32 offset) const {
+ DCHECK(init_);
+ return std::binary_search(offsets_.begin(), offsets_.end(), offset);
+}
+
+void Segment::AddUser() {
+ DCHECK(init_);
+ ++num_users_;
+}
+
+void Segment::ReleaseUser() {
+ DCHECK(init_);
+ --num_users_;
+}
+
+bool Segment::HasNoUsers() const {
+ DCHECK(init_);
+ return num_users_ == 0;
+}
+
+bool Segment::Init() {
+ DCHECK(!init_);
+
+ if (offset_ < 0 || offset_ + kFlashSegmentSize > storage_->size())
+ return false;
+
+ if (!read_only_) {
+ init_ = true;
+ return true;
+ }
+
+ int32 summary[kFlashMaxEntryCount + 1];
+ if (!storage_->Read(summary, kFlashSummarySize, summary_offset_))
+ return false;
+
+ size_t entry_count = summary[0];
+ DCHECK_LE(entry_count, kFlashMaxEntryCount);
+
+ std::vector<int32> tmp(summary + 1, summary + 1 + entry_count);
+ offsets_.swap(tmp);
+ init_ = true;
+ return true;
+}
+
+bool Segment::WriteData(const void* buffer, int32 size) {
+ DCHECK(init_ && !read_only_);
+ DCHECK(write_offset_ + size <= summary_offset_);
+ if (!storage_->Write(buffer, size, write_offset_))
+ return false;
+ write_offset_ += size;
+ return true;
+}
+
+void Segment::StoreOffset(int32 offset) {
+ DCHECK(init_ && !read_only_);
+ DCHECK(offsets_.size() < kFlashMaxEntryCount);
+ offsets_.push_back(offset);
+}
+
+bool Segment::ReadData(void* buffer, int32 size, int32 offset) const {
+ DCHECK(init_);
+ DCHECK(offset >= offset_ && offset + size <= offset_ + kFlashSegmentSize);
+ return storage_->Read(buffer, size, offset);
+}
+
+bool Segment::Close() {
+ DCHECK(init_);
+ if (read_only_)
+ return true;
+
+ DCHECK(offsets_.size() <= kFlashMaxEntryCount);
+
+ int32 summary[kFlashMaxEntryCount + 1];
+ memset(summary, 0, kFlashSummarySize);
+ summary[0] = offsets_.size();
+ std::copy(offsets_.begin(), offsets_.end(), summary + 1);
+ if (!storage_->Write(summary, kFlashSummarySize, summary_offset_))
+ return false;
+
+ read_only_ = true;
+ return true;
+}
+
+bool Segment::CanHold(int32 size) const {
+ DCHECK(init_);
+ return offsets_.size() < kFlashMaxEntryCount &&
+ write_offset_ + size <= summary_offset_;
+}
+
+} // namespace disk_cache