mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-12-01 01:36:09 +03:00
210 lines
4.9 KiB
C
210 lines
4.9 KiB
C
|
// 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 <stddef.h>
|
||
|
#include <stdint.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_t 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_t StorageBlock<T>::CalculateHash() const {
|
||
|
return base::Hash(data_, offsetof(T, self_hash));
|
||
|
}
|
||
|
|
||
|
} // namespace disk_cache
|
||
|
|
||
|
#endif // NET_DISK_CACHE_BLOCKFILE_STORAGE_BLOCK_INL_H_
|