15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#ifndef NET_DISK_CACHE_BLOCKFILE_STORAGE_BLOCK_INL_H_ 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define NET_DISK_CACHE_BLOCKFILE_STORAGE_BLOCK_INL_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/disk_cache/blockfile/storage_block.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/hash.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/disk_cache/blockfile/trace.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace disk_cache { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> StorageBlock<T>::StorageBlock(MappedFile* file, 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Addr address) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : data_(NULL), file_(file), address_(address), modified_(false), 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) own_data_(false), extended_(false) { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (address.num_blocks() > 1) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extended_ = true; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!address.is_initialized() || sizeof(*data_) == address.BlockSize()); 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> StorageBlock<T>::~StorageBlock() { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (modified_) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Store(); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteData(); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> void* StorageBlock<T>::buffer() const { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return data_; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> size_t StorageBlock<T>::size() const { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extended_) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sizeof(*data_); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return address_.num_blocks() * sizeof(*data_); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> int StorageBlock<T>::offset() const { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return address_.start_block() * address_.BlockSize(); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> bool StorageBlock<T>::LazyInit(MappedFile* file, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Addr address) { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (file_ || address_.is_initialized()) { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_ = file; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address_.set_value(address.value()); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (address.num_blocks() > 1) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extended_ = true; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(sizeof(*data_) == address.BlockSize()); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> void StorageBlock<T>::SetData(T* other) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!modified_); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteData(); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_ = other; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> void StorageBlock<T>::Discard() { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data_) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!own_data_) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteData(); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_ = NULL; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) modified_ = false; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extended_ = false; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> void StorageBlock<T>::StopSharingData() { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data_ || own_data_) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!modified_); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_ = NULL; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> void StorageBlock<T>::set_modified() { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(data_); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) modified_ = true; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> void StorageBlock<T>::clear_modified() { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) modified_ = false; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> T* StorageBlock<T>::Data() { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data_) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AllocateData(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return data_; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> bool StorageBlock<T>::HasData() const { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL != data_); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> bool StorageBlock<T>::VerifyHash() const { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 hash = CalculateHash(); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (!data_->self_hash || data_->self_hash == hash); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> bool StorageBlock<T>::own_data() const { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return own_data_; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> const Addr StorageBlock<T>::address() const { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return address_; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> bool StorageBlock<T>::Load() { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (file_) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data_) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AllocateData(); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (file_->Load(this)) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) modified_ = false; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Failed data load."; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Trace("Failed data load."); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> bool StorageBlock<T>::Store() { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (file_ && data_) { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_->self_hash = CalculateHash(); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (file_->Store(this)) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) modified_ = false; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed data store."; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Trace("Failed data store."); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)template<typename T> bool StorageBlock<T>::Load(FileIOCallback* callback, 14758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool* completed) { 14858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (file_) { 14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!data_) 15058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) AllocateData(); 15158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (file_->Load(this, callback, completed)) { 15358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) modified_ = false; 15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 15558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 15758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) LOG(WARNING) << "Failed data load."; 15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Trace("Failed data load."); 15958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 16058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)template<typename T> bool StorageBlock<T>::Store(FileIOCallback* callback, 16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool* completed) { 16458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (file_ && data_) { 16558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) data_->self_hash = CalculateHash(); 16658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (file_->Store(this, callback, completed)) { 16758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) modified_ = false; 16858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 16958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 17058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 17158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) LOG(ERROR) << "Failed data store."; 17258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Trace("Failed data store."); 17358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> void StorageBlock<T>::AllocateData() { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!data_); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extended_) { 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_ = new T; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* buffer = new char[address_.num_blocks() * sizeof(*data_)]; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_ = new(buffer) T; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) own_data_ = true; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> void StorageBlock<T>::DeleteData() { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (own_data_) { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extended_) { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete data_; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_->~T(); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete[] reinterpret_cast<char*>(data_); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) own_data_ = false; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> uint32 StorageBlock<T>::CalculateHash() const { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::Hash(reinterpret_cast<char*>(data_), offsetof(T, self_hash)); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace disk_cache 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif // NET_DISK_CACHE_BLOCKFILE_STORAGE_BLOCK_INL_H_ 206