diff options
Diffstat (limited to 'chromium/net/disk_cache/flash/segment.cc')
-rw-r--r-- | chromium/net/disk_cache/flash/segment.cc | 122 |
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 |