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