Home | History | Annotate | Download | only in disk_cache
      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 
     15 template<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 
     24 template<typename T> StorageBlock<T>::~StorageBlock() {
     25   if (modified_)
     26     Store();
     27   DeleteData();
     28 }
     29 
     30 template<typename T> void* StorageBlock<T>::buffer() const {
     31   return data_;
     32 }
     33 
     34 template<typename T> size_t StorageBlock<T>::size() const {
     35   if (!extended_)
     36     return sizeof(*data_);
     37   return address_.num_blocks() * sizeof(*data_);
     38 }
     39 
     40 template<typename T> int StorageBlock<T>::offset() const {
     41   return address_.start_block() * address_.BlockSize();
     42 }
     43 
     44 template<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 
     59 template<typename T> void StorageBlock<T>::SetData(T* other) {
     60   DCHECK(!modified_);
     61   DeleteData();
     62   data_ = other;
     63 }
     64 
     65 template<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 
     78 template<typename T> void  StorageBlock<T>::StopSharingData() {
     79   if (!data_ || own_data_)
     80     return;
     81   DCHECK(!modified_);
     82   data_ = NULL;
     83 }
     84 
     85 template<typename T> void StorageBlock<T>::set_modified() {
     86   DCHECK(data_);
     87   modified_ = true;
     88 }
     89 
     90 template<typename T> T* StorageBlock<T>::Data() {
     91   if (!data_)
     92     AllocateData();
     93   return data_;
     94 }
     95 
     96 template<typename T> bool StorageBlock<T>::HasData() const {
     97   return (NULL != data_);
     98 }
     99 
    100 template<typename T> bool StorageBlock<T>::own_data() const {
    101   return own_data_;
    102 }
    103 
    104 template<typename T> const Addr StorageBlock<T>::address() const {
    105   return address_;
    106 }
    107 
    108 template<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 
    123 template<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 
    135 template<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 
    146 template<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