15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <algorithm> 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/disk_cache/flash/format.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/disk_cache/flash/segment.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/disk_cache/flash/storage.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace disk_cache { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Segment::Segment(int32 index, bool read_only, Storage* storage) 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : index_(index), 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_users_(0), 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_only_(read_only), 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_(false), 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage_(storage), 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset_(index * kFlashSegmentSize), 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) summary_offset_(offset_ + kFlashSegmentSize - kFlashSummarySize), 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_offset_(offset_) { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(storage); 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(storage->size() % kFlashSegmentSize == 0); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Segment::~Segment() { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!init_ || read_only_); 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (num_users_ != 0) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(WARNING) << "Users exist, but we don't care? " << num_users_; 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Segment::HaveOffset(int32 offset) const { 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(init_); 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return std::binary_search(offsets_.begin(), offsets_.end(), offset); 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Segment::AddUser() { 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(init_); 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++num_users_; 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Segment::ReleaseUser() { 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(init_); 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) --num_users_; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Segment::HasNoUsers() const { 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(init_); 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return num_users_ == 0; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Segment::Init() { 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!init_); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (offset_ < 0 || offset_ + kFlashSegmentSize > storage_->size()) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read_only_) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_ = true; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 summary[kFlashMaxEntryCount + 1]; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!storage_->Read(summary, kFlashSummarySize, summary_offset_)) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t entry_count = summary[0]; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(entry_count, kFlashMaxEntryCount); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<int32> tmp(summary + 1, summary + 1 + entry_count); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offsets_.swap(tmp); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_ = true; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Segment::WriteData(const void* buffer, int32 size) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(init_ && !read_only_); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(write_offset_ + size <= summary_offset_); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!storage_->Write(buffer, size, write_offset_)) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_offset_ += size; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Segment::StoreOffset(int32 offset) { 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(init_ && !read_only_); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(offsets_.size() < kFlashMaxEntryCount); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offsets_.push_back(offset); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Segment::ReadData(void* buffer, int32 size, int32 offset) const { 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(init_); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(offset >= offset_ && offset + size <= offset_ + kFlashSegmentSize); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return storage_->Read(buffer, size, offset); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Segment::Close() { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(init_); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_only_) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(offsets_.size() <= kFlashMaxEntryCount); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 summary[kFlashMaxEntryCount + 1]; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(summary, 0, kFlashSummarySize); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) summary[0] = offsets_.size(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::copy(offsets_.begin(), offsets_.end(), summary + 1); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!storage_->Write(summary, kFlashSummarySize, summary_offset_)) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_only_ = true; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Segment::CanHold(int32 size) const { 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(init_); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return offsets_.size() < kFlashMaxEntryCount && 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_offset_ + size <= summary_offset_; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace disk_cache 123