| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include <algorithm> | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "net/disk_cache/flash/format.h" | |
| 9 #include "net/disk_cache/flash/segment.h" | |
| 10 #include "net/disk_cache/flash/storage.h" | |
| 11 | |
| 12 namespace disk_cache { | |
| 13 | |
| 14 Segment::Segment(int32 index, bool read_only, Storage* storage) | |
| 15 : index_(index), | |
| 16 num_users_(0), | |
| 17 read_only_(read_only), | |
| 18 init_(false), | |
| 19 storage_(storage), | |
| 20 offset_(index * kFlashSegmentSize), | |
| 21 summary_offset_(offset_ + kFlashSegmentSize - kFlashSummarySize), | |
| 22 write_offset_(offset_) { | |
| 23 DCHECK(storage); | |
| 24 DCHECK(storage->size() % kFlashSegmentSize == 0); | |
| 25 } | |
| 26 | |
| 27 Segment::~Segment() { | |
| 28 DCHECK(!init_ || read_only_); | |
| 29 if (num_users_ != 0) | |
| 30 LOG(WARNING) << "Users exist, but we don't care? " << num_users_; | |
| 31 } | |
| 32 | |
| 33 bool Segment::HaveOffset(int32 offset) const { | |
| 34 DCHECK(init_); | |
| 35 return std::binary_search(offsets_.begin(), offsets_.end(), offset); | |
| 36 } | |
| 37 | |
| 38 void Segment::AddUser() { | |
| 39 DCHECK(init_); | |
| 40 ++num_users_; | |
| 41 } | |
| 42 | |
| 43 void Segment::ReleaseUser() { | |
| 44 DCHECK(init_); | |
| 45 --num_users_; | |
| 46 } | |
| 47 | |
| 48 bool Segment::HasNoUsers() const { | |
| 49 DCHECK(init_); | |
| 50 return num_users_ == 0; | |
| 51 } | |
| 52 | |
| 53 bool Segment::Init() { | |
| 54 DCHECK(!init_); | |
| 55 | |
| 56 if (offset_ < 0 || offset_ + kFlashSegmentSize > storage_->size()) | |
| 57 return false; | |
| 58 | |
| 59 if (!read_only_) { | |
| 60 init_ = true; | |
| 61 return true; | |
| 62 } | |
| 63 | |
| 64 int32 summary[kFlashMaxEntryCount + 1]; | |
| 65 if (!storage_->Read(summary, kFlashSummarySize, summary_offset_)) | |
| 66 return false; | |
| 67 | |
| 68 size_t entry_count = summary[0]; | |
| 69 DCHECK_LE(entry_count, kFlashMaxEntryCount); | |
| 70 | |
| 71 std::vector<int32> tmp(summary + 1, summary + 1 + entry_count); | |
| 72 offsets_.swap(tmp); | |
| 73 init_ = true; | |
| 74 return true; | |
| 75 } | |
| 76 | |
| 77 bool Segment::WriteData(const void* buffer, int32 size) { | |
| 78 DCHECK(init_ && !read_only_); | |
| 79 DCHECK(write_offset_ + size <= summary_offset_); | |
| 80 if (!storage_->Write(buffer, size, write_offset_)) | |
| 81 return false; | |
| 82 write_offset_ += size; | |
| 83 return true; | |
| 84 } | |
| 85 | |
| 86 void Segment::StoreOffset(int32 offset) { | |
| 87 DCHECK(init_ && !read_only_); | |
| 88 DCHECK(offsets_.size() < kFlashMaxEntryCount); | |
| 89 offsets_.push_back(offset); | |
| 90 } | |
| 91 | |
| 92 bool Segment::ReadData(void* buffer, int32 size, int32 offset) const { | |
| 93 DCHECK(init_); | |
| 94 DCHECK(offset >= offset_ && offset + size <= offset_ + kFlashSegmentSize); | |
| 95 return storage_->Read(buffer, size, offset); | |
| 96 } | |
| 97 | |
| 98 bool Segment::Close() { | |
| 99 DCHECK(init_); | |
| 100 if (read_only_) | |
| 101 return true; | |
| 102 | |
| 103 DCHECK(offsets_.size() <= kFlashMaxEntryCount); | |
| 104 | |
| 105 int32 summary[kFlashMaxEntryCount + 1]; | |
| 106 memset(summary, 0, kFlashSummarySize); | |
| 107 summary[0] = offsets_.size(); | |
| 108 std::copy(offsets_.begin(), offsets_.end(), summary + 1); | |
| 109 if (!storage_->Write(summary, kFlashSummarySize, summary_offset_)) | |
| 110 return false; | |
| 111 | |
| 112 read_only_ = true; | |
| 113 return true; | |
| 114 } | |
| 115 | |
| 116 bool Segment::CanHold(int32 size) const { | |
| 117 DCHECK(init_); | |
| 118 return offsets_.size() < kFlashMaxEntryCount && | |
| 119 write_offset_ + size <= summary_offset_; | |
| 120 } | |
| 121 | |
| 122 } // namespace disk_cache | |
| OLD | NEW |