diff options
Diffstat (limited to 'chromium/net/disk_cache/blockfile/storage_block-inl.h')
-rw-r--r-- | chromium/net/disk_cache/blockfile/storage_block-inl.h | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/chromium/net/disk_cache/blockfile/storage_block-inl.h b/chromium/net/disk_cache/blockfile/storage_block-inl.h new file mode 100644 index 00000000000..f919c128c40 --- /dev/null +++ b/chromium/net/disk_cache/blockfile/storage_block-inl.h @@ -0,0 +1,205 @@ +// 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. + +#ifndef NET_DISK_CACHE_BLOCKFILE_STORAGE_BLOCK_INL_H_ +#define NET_DISK_CACHE_BLOCKFILE_STORAGE_BLOCK_INL_H_ + +#include "net/disk_cache/blockfile/storage_block.h" + +#include "base/hash.h" +#include "base/logging.h" +#include "net/disk_cache/blockfile/trace.h" + +namespace disk_cache { + +template<typename T> StorageBlock<T>::StorageBlock(MappedFile* file, + Addr address) + : data_(NULL), file_(file), address_(address), modified_(false), + own_data_(false), extended_(false) { + if (address.num_blocks() > 1) + extended_ = true; + DCHECK(!address.is_initialized() || sizeof(*data_) == address.BlockSize()); +} + +template<typename T> StorageBlock<T>::~StorageBlock() { + if (modified_) + Store(); + DeleteData(); +} + +template<typename T> void* StorageBlock<T>::buffer() const { + return data_; +} + +template<typename T> size_t StorageBlock<T>::size() const { + if (!extended_) + return sizeof(*data_); + return address_.num_blocks() * sizeof(*data_); +} + +template<typename T> int StorageBlock<T>::offset() const { + return address_.start_block() * address_.BlockSize(); +} + +template<typename T> bool StorageBlock<T>::LazyInit(MappedFile* file, + Addr address) { + if (file_ || address_.is_initialized()) { + NOTREACHED(); + return false; + } + file_ = file; + address_.set_value(address.value()); + if (address.num_blocks() > 1) + extended_ = true; + + DCHECK(sizeof(*data_) == address.BlockSize()); + return true; +} + +template<typename T> void StorageBlock<T>::SetData(T* other) { + DCHECK(!modified_); + DeleteData(); + data_ = other; +} + +template<typename T> void StorageBlock<T>::Discard() { + if (!data_) + return; + if (!own_data_) { + NOTREACHED(); + return; + } + DeleteData(); + data_ = NULL; + modified_ = false; + extended_ = false; +} + +template<typename T> void StorageBlock<T>::StopSharingData() { + if (!data_ || own_data_) + return; + DCHECK(!modified_); + data_ = NULL; +} + +template<typename T> void StorageBlock<T>::set_modified() { + DCHECK(data_); + modified_ = true; +} + +template<typename T> void StorageBlock<T>::clear_modified() { + modified_ = false; +} + +template<typename T> T* StorageBlock<T>::Data() { + if (!data_) + AllocateData(); + return data_; +} + +template<typename T> bool StorageBlock<T>::HasData() const { + return (NULL != data_); +} + +template<typename T> bool StorageBlock<T>::VerifyHash() const { + uint32 hash = CalculateHash(); + return (!data_->self_hash || data_->self_hash == hash); +} + +template<typename T> bool StorageBlock<T>::own_data() const { + return own_data_; +} + +template<typename T> const Addr StorageBlock<T>::address() const { + return address_; +} + +template<typename T> bool StorageBlock<T>::Load() { + if (file_) { + if (!data_) + AllocateData(); + + if (file_->Load(this)) { + modified_ = false; + return true; + } + } + LOG(WARNING) << "Failed data load."; + Trace("Failed data load."); + return false; +} + +template<typename T> bool StorageBlock<T>::Store() { + if (file_ && data_) { + data_->self_hash = CalculateHash(); + if (file_->Store(this)) { + modified_ = false; + return true; + } + } + LOG(ERROR) << "Failed data store."; + Trace("Failed data store."); + return false; +} + +template<typename T> bool StorageBlock<T>::Load(FileIOCallback* callback, + bool* completed) { + if (file_) { + if (!data_) + AllocateData(); + + if (file_->Load(this, callback, completed)) { + modified_ = false; + return true; + } + } + LOG(WARNING) << "Failed data load."; + Trace("Failed data load."); + return false; +} + +template<typename T> bool StorageBlock<T>::Store(FileIOCallback* callback, + bool* completed) { + if (file_ && data_) { + data_->self_hash = CalculateHash(); + if (file_->Store(this, callback, completed)) { + modified_ = false; + return true; + } + } + LOG(ERROR) << "Failed data store."; + Trace("Failed data store."); + return false; +} + +template<typename T> void StorageBlock<T>::AllocateData() { + DCHECK(!data_); + if (!extended_) { + data_ = new T; + } else { + void* buffer = new char[address_.num_blocks() * sizeof(*data_)]; + data_ = new(buffer) T; + } + own_data_ = true; +} + +template<typename T> void StorageBlock<T>::DeleteData() { + if (own_data_) { + if (!extended_) { + delete data_; + } else { + data_->~T(); + delete[] reinterpret_cast<char*>(data_); + } + own_data_ = false; + } +} + +template<typename T> uint32 StorageBlock<T>::CalculateHash() const { + return base::Hash(reinterpret_cast<char*>(data_), offsetof(T, self_hash)); +} + +} // namespace disk_cache + +#endif // NET_DISK_CACHE_BLOCKFILE_STORAGE_BLOCK_INL_H_ |