summaryrefslogtreecommitdiffstats
path: root/chromium/net/disk_cache/blockfile/storage_block-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/disk_cache/blockfile/storage_block-inl.h')
-rw-r--r--chromium/net/disk_cache/blockfile/storage_block-inl.h205
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_