1 // Copyright (c) 2006-2008 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 #ifndef NET_DISK_CACHE_STORAGE_BLOCK_INL_H_ 6 #define NET_DISK_CACHE_STORAGE_BLOCK_INL_H_ 7 8 #include "net/disk_cache/storage_block.h" 9 10 #include "base/logging.h" 11 #include "net/disk_cache/trace.h" 12 13 namespace disk_cache { 14 StorageBlock(MappedFile * file,Addr address)15template<typename T> StorageBlock<T>::StorageBlock(MappedFile* file, 16 Addr address) 17 : data_(NULL), file_(file), address_(address), modified_(false), 18 own_data_(false), extended_(false) { 19 if (address.num_blocks() > 1) 20 extended_ = true; 21 DCHECK(!address.is_initialized() || sizeof(*data_) == address.BlockSize()); 22 } 23 ~StorageBlock()24template<typename T> StorageBlock<T>::~StorageBlock() { 25 if (modified_) 26 Store(); 27 DeleteData(); 28 } 29 buffer()30template<typename T> void* StorageBlock<T>::buffer() const { 31 return data_; 32 } 33 size()34template<typename T> size_t StorageBlock<T>::size() const { 35 if (!extended_) 36 return sizeof(*data_); 37 return address_.num_blocks() * sizeof(*data_); 38 } 39 offset()40template<typename T> int StorageBlock<T>::offset() const { 41 return address_.start_block() * address_.BlockSize(); 42 } 43 LazyInit(MappedFile * file,Addr address)44template<typename T> bool StorageBlock<T>::LazyInit(MappedFile* file, 45 Addr address) { 46 if (file_ || address_.is_initialized()) { 47 NOTREACHED(); 48 return false; 49 } 50 file_ = file; 51 address_.set_value(address.value()); 52 if (address.num_blocks() > 1) 53 extended_ = true; 54 55 DCHECK(sizeof(*data_) == address.BlockSize()); 56 return true; 57 } 58 SetData(T * other)59template<typename T> void StorageBlock<T>::SetData(T* other) { 60 DCHECK(!modified_); 61 DeleteData(); 62 data_ = other; 63 } 64 Discard()65template<typename T> void StorageBlock<T>::Discard() { 66 if (!data_) 67 return; 68 if (!own_data_) { 69 NOTREACHED(); 70 return; 71 } 72 DeleteData(); 73 data_ = NULL; 74 modified_ = false; 75 extended_ = false; 76 } 77 StopSharingData()78template<typename T> void StorageBlock<T>::StopSharingData() { 79 if (!data_ || own_data_) 80 return; 81 DCHECK(!modified_); 82 data_ = NULL; 83 } 84 set_modified()85template<typename T> void StorageBlock<T>::set_modified() { 86 DCHECK(data_); 87 modified_ = true; 88 } 89 Data()90template<typename T> T* StorageBlock<T>::Data() { 91 if (!data_) 92 AllocateData(); 93 return data_; 94 } 95 HasData()96template<typename T> bool StorageBlock<T>::HasData() const { 97 return (NULL != data_); 98 } 99 own_data()100template<typename T> bool StorageBlock<T>::own_data() const { 101 return own_data_; 102 } 103 address()104template<typename T> const Addr StorageBlock<T>::address() const { 105 return address_; 106 } 107 Load()108template<typename T> bool StorageBlock<T>::Load() { 109 if (file_) { 110 if (!data_) 111 AllocateData(); 112 113 if (file_->Load(this)) { 114 modified_ = false; 115 return true; 116 } 117 } 118 LOG(WARNING) << "Failed data load."; 119 Trace("Failed data load."); 120 return false; 121 } 122 Store()123template<typename T> bool StorageBlock<T>::Store() { 124 if (file_ && data_) { 125 if (file_->Store(this)) { 126 modified_ = false; 127 return true; 128 } 129 } 130 LOG(ERROR) << "Failed data store."; 131 Trace("Failed data store."); 132 return false; 133 } 134 AllocateData()135template<typename T> void StorageBlock<T>::AllocateData() { 136 DCHECK(!data_); 137 if (!extended_) { 138 data_ = new T; 139 } else { 140 void* buffer = new char[address_.num_blocks() * sizeof(*data_)]; 141 data_ = new(buffer) T; 142 } 143 own_data_ = true; 144 } 145 DeleteData()146template<typename T> void StorageBlock<T>::DeleteData() { 147 if (own_data_) { 148 if (!extended_) { 149 delete data_; 150 } else { 151 data_->~T(); 152 delete[] reinterpret_cast<char*>(data_); 153 } 154 own_data_ = false; 155 } 156 } 157 158 } // namespace disk_cache 159 160 #endif // NET_DISK_CACHE_STORAGE_BLOCK_INL_H_ 161