• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
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_BLOCKFILE_STORAGE_BLOCK_INL_H_
6 #define NET_DISK_CACHE_BLOCKFILE_STORAGE_BLOCK_INL_H_
7 
8 #include "net/disk_cache/blockfile/storage_block.h"
9 
10 #include <stddef.h>
11 #include <stdint.h>
12 
13 #include "base/hash/hash.h"
14 #include "base/logging.h"
15 #include "base/notreached.h"
16 
17 namespace disk_cache {
18 
19 template <typename T>
StorageBlock(MappedFile * file,Addr address)20 StorageBlock<T>::StorageBlock(MappedFile* file, Addr address)
21     : file_(file), address_(address) {
22   if (address.num_blocks() > 1)
23     extended_ = true;
24   DCHECK(!address.is_initialized() || sizeof(*data_) == address.BlockSize())
25       << address.value();
26 }
27 
~StorageBlock()28 template<typename T> StorageBlock<T>::~StorageBlock() {
29   if (modified_)
30     Store();
31   DeleteData();
32 }
33 
34 template <typename T>
CopyFrom(StorageBlock<T> * other)35 void StorageBlock<T>::CopyFrom(StorageBlock<T>* other) {
36   DCHECK(!modified_);
37   DCHECK(!other->modified_);
38   Discard();
39   *Data() = *other->Data();
40   file_ = other->file_;
41   address_ = other->address_;
42   extended_ = other->extended_;
43 }
44 
buffer()45 template<typename T> void* StorageBlock<T>::buffer() const {
46   return data_;
47 }
48 
size()49 template<typename T> size_t StorageBlock<T>::size() const {
50   if (!extended_)
51     return sizeof(*data_);
52   return address_.num_blocks() * sizeof(*data_);
53 }
54 
offset()55 template<typename T> int StorageBlock<T>::offset() const {
56   return address_.start_block() * address_.BlockSize();
57 }
58 
LazyInit(MappedFile * file,Addr address)59 template<typename T> bool StorageBlock<T>::LazyInit(MappedFile* file,
60                                                     Addr address) {
61   if (file_ || address_.is_initialized()) {
62     NOTREACHED();
63     return false;
64   }
65   file_ = file;
66   address_.set_value(address.value());
67   if (address.num_blocks() > 1)
68     extended_ = true;
69 
70   DCHECK(sizeof(*data_) == address.BlockSize());
71   return true;
72 }
73 
SetData(T * other)74 template<typename T> void StorageBlock<T>::SetData(T* other) {
75   DCHECK(!modified_);
76   DeleteData();
77   data_ = other;
78 }
79 
Discard()80 template<typename T> void  StorageBlock<T>::Discard() {
81   if (!data_)
82     return;
83   if (!own_data_) {
84     NOTREACHED();
85     return;
86   }
87   DeleteData();
88   data_ = nullptr;
89   modified_ = false;
90   extended_ = false;
91 }
92 
StopSharingData()93 template<typename T> void  StorageBlock<T>::StopSharingData() {
94   if (!data_ || own_data_)
95     return;
96   DCHECK(!modified_);
97   data_ = nullptr;
98 }
99 
set_modified()100 template<typename T> void StorageBlock<T>::set_modified() {
101   DCHECK(data_);
102   modified_ = true;
103 }
104 
clear_modified()105 template<typename T> void StorageBlock<T>::clear_modified() {
106   modified_ = false;
107 }
108 
Data()109 template<typename T> T* StorageBlock<T>::Data() {
110   if (!data_)
111     AllocateData();
112   return data_;
113 }
114 
HasData()115 template<typename T> bool StorageBlock<T>::HasData() const {
116   return (nullptr != data_);
117 }
118 
VerifyHash()119 template<typename T> bool StorageBlock<T>::VerifyHash() const {
120   uint32_t hash = CalculateHash();
121   return (!data_->self_hash || data_->self_hash == hash);
122 }
123 
own_data()124 template<typename T> bool StorageBlock<T>::own_data() const {
125   return own_data_;
126 }
127 
address()128 template<typename T> const Addr StorageBlock<T>::address() const {
129   return address_;
130 }
131 
Load()132 template<typename T> bool StorageBlock<T>::Load() {
133   if (file_) {
134     if (!data_)
135       AllocateData();
136 
137     if (file_->Load(this)) {
138       modified_ = false;
139       return true;
140     }
141   }
142   LOG(WARNING) << "Failed data load.";
143   return false;
144 }
145 
Store()146 template<typename T> bool StorageBlock<T>::Store() {
147   if (file_ && data_) {
148     data_->self_hash = CalculateHash();
149     if (file_->Store(this)) {
150       modified_ = false;
151       return true;
152     }
153   }
154   LOG(ERROR) << "Failed data store.";
155   return false;
156 }
157 
Load(FileIOCallback * callback,bool * completed)158 template<typename T> bool StorageBlock<T>::Load(FileIOCallback* callback,
159                                                 bool* completed) {
160   if (file_) {
161     if (!data_)
162       AllocateData();
163 
164     if (file_->Load(this, callback, completed)) {
165       modified_ = false;
166       return true;
167     }
168   }
169   LOG(WARNING) << "Failed data load.";
170   return false;
171 }
172 
Store(FileIOCallback * callback,bool * completed)173 template<typename T> bool StorageBlock<T>::Store(FileIOCallback* callback,
174                                                  bool* completed) {
175   if (file_ && data_) {
176     data_->self_hash = CalculateHash();
177     if (file_->Store(this, callback, completed)) {
178       modified_ = false;
179       return true;
180     }
181   }
182   LOG(ERROR) << "Failed data store.";
183   return false;
184 }
185 
AllocateData()186 template<typename T> void StorageBlock<T>::AllocateData() {
187   DCHECK(!data_);
188   if (!extended_) {
189     data_ = new T;
190   } else {
191     void* buffer = new char[address_.num_blocks() * sizeof(*data_)];
192     data_ = new(buffer) T;
193   }
194   own_data_ = true;
195 }
196 
DeleteData()197 template<typename T> void StorageBlock<T>::DeleteData() {
198   if (own_data_) {
199     if (!extended_) {
200       data_.ClearAndDelete();
201     } else {
202       data_->~T();
203       delete[] reinterpret_cast<char*>(data_.ExtractAsDangling().get());
204     }
205     own_data_ = false;
206   }
207 }
208 
209 template <typename T>
CalculateHash()210 uint32_t StorageBlock<T>::CalculateHash() const {
211   return base::PersistentHash(data_, offsetof(T, self_hash));
212 }
213 
214 }  // namespace disk_cache
215 
216 #endif  // NET_DISK_CACHE_BLOCKFILE_STORAGE_BLOCK_INL_H_
217