TPIE

2362a60
internal_store.h
1 // -*- mode: c++; tab-width: 4; indent-tabs-mode: t; eval: (progn (c-set-style "stroustrup") (c-set-offset 'innamespace 0)); -*-
2 // vi:set ts=4 sts=4 sw=4 noet :
3 // Copyright 2014 The TPIE development team
4 //
5 // This file is part of TPIE.
6 //
7 // TPIE is free software: you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License as published by the
9 // Free Software Foundation, either version 3 of the License, or (at your
10 // option) any later version.
11 //
12 // TPIE is distributed in the hope that it will be useful, but WITHOUT ANY
13 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 // License for more details.
16 //
17 // You should have received a copy of the GNU Lesser General Public License
18 // along with TPIE. If not, see <http://www.gnu.org/licenses/>
19 
20 #ifndef _TPIE_BTREE_INTERNAL_STORE_H_
21 #define _TPIE_BTREE_INTERNAL_STORE_H_
22 
23 #include <tpie/portability.h>
24 #include <tpie/btree/base.h>
25 #include <tpie/tpie_assert.h>
26 #include <tpie/memory.h>
27 #include <cstddef>
28 
29 namespace tpie {
30 namespace bbits {
31 
41 template <typename T,
42  typename A,
43  std::size_t a_,
44  std::size_t b_>
45 class internal_store {
46 public:
47  static const size_t a = a_?a_:2;
48  static const size_t b = b_?b_:4;
49 
53  typedef T value_type;
54 
58  typedef A augment_type;
59 
60 
61  typedef size_t size_type;
62 
63 
64  internal_store(const internal_store & o) = delete;
65  internal_store & operator=(const internal_store & o) = delete;
66 
68  : m_root(o.m_root)
69  , m_height(o.m_height)
70  , m_size(o.m_size)
71  , m_metadata(o.m_metadata)
72  , m_bucket(o.m_bucket) {
73  o.m_root = nullptr;
74  o.m_size = 0;
75  o.m_height = 0;
76  }
77 
78  internal_store & operator=(internal_store && o) {
79  std::swap(m_root, o.m_root);
80  std::swap(m_height, o.m_height);
81  std::swap(m_size, o.m_size);
82  std::swap(m_metadata, o.m_metadata);
83  std::swap(m_bucket, o.m_bucket);
84  return *this;
85  }
86 
87 private:
91  explicit internal_store(memory_bucket_ref bucket):
92  m_root(nullptr), m_height(0), m_size(0), m_bucket(bucket) {}
93 
94 
95  struct internal_content {
96  void * ptr;
97  A augment;
98  };
99 
100  struct internal {
101  size_t count;
102  internal_content values[b];
103  };
104 
105  struct leaf {
106  size_t count;
107  T values[b];
108  };
109 
110  typedef internal * internal_type;
111  typedef leaf * leaf_type;
112 
113  void dispose(void * node, size_t depth) {
114  if (depth + 1 == m_height) {
115  tpie_delete(static_cast<leaf *>(node));
116  if (m_bucket) m_bucket->count -= sizeof(leaf);
117  return;
118  }
119  internal * in = static_cast<internal*>(node);
120  for (size_t i=0; i != in->count; ++i)
121  dispose(in->values[i].ptr, depth + 1);
122  tpie_delete(in);
123  if (m_bucket) m_bucket->count -= sizeof(internal);
124  }
125 
126  ~internal_store() {
127  if (!m_root || !m_height) return;
128  dispose(m_root, 0);
129  m_root = nullptr;
130  }
131 
132  static constexpr size_t min_internal_size() {return a;}
133  static constexpr size_t max_internal_size() {return b;}
134 
135  static constexpr size_t min_leaf_size() {return a;}
136  static constexpr size_t max_leaf_size() {return b;}
137 
138  void move(internal_type src, size_t src_i,
139  internal_type dst, size_t dst_i) {
140  dst->values[dst_i] = src->values[src_i];
141  }
142 
143  void move(leaf_type src, size_t src_i,
144  leaf_type dst, size_t dst_i) {
145  dst->values[dst_i] = src->values[src_i];
146  }
147 
148  void set(leaf_type dst, size_t dst_i, T c) {
149  dst->values[dst_i] = c;
150  }
151 
152  void set(internal_type node, size_t i, internal_type c) {
153  node->values[i].ptr = c;
154  }
155 
156  void set(internal_type node, size_t i, leaf_type c) {
157  node->values[i].ptr = c;
158  }
159 
160  const T & get(leaf_type l, size_t i) const {
161  return l->values[i];
162  }
163 
164  size_t count(internal_type node) const {
165  return node->count;
166  }
167 
168  size_t count_child_leaf(internal_type node, size_t i) const {
169  return static_cast<leaf_type>(node->values[i].ptr)->count;
170  }
171 
172  size_t count_child_internal(internal_type node, size_t i) const {
173  return static_cast<internal_type>(node->values[i].ptr)->count;
174  }
175 
176  size_t count(leaf_type node) const {
177  return node->count;
178  }
179 
180  void set_count(internal_type node, size_t i) {
181  node->count = i;
182  }
183 
184  void set_count(leaf_type node, size_t i) {
185  node->count = i;
186  }
187 
188  leaf_type create_leaf() {
189  auto l = tpie_new<leaf>();
190  if (m_bucket) m_bucket->count += sizeof(leaf);
191  return l;
192  }
193  leaf_type create(leaf_type) {return create_leaf();}
194 
195  internal_type create_internal() {
196  auto i = tpie_new<internal>();
197  if (m_bucket) m_bucket->count += sizeof(internal);
198  return i;
199  }
200 
201  internal_type create(internal_type) {return create_internal();}
202 
203  void destroy(internal_type node) {
204  if (m_bucket && node) m_bucket->count -= sizeof(internal);
205  tpie_delete(node);
206  }
207 
208  void destroy(leaf_type node) {
209  if (m_bucket && node) m_bucket->count -= sizeof(leaf);
210  tpie_delete(node);
211  }
212 
213  void set_root(internal_type node) {m_root = node;}
214  void set_root(leaf_type node) {m_root = node;}
215 
216  internal_type get_root_internal() const {
217  return static_cast<internal_type>(m_root);
218  }
219 
220  leaf_type get_root_leaf() const {
221  return static_cast<leaf_type>(m_root);
222  }
223 
224  internal_type get_child_internal(internal_type node, size_t i) const {
225  return static_cast<internal_type>(node->values[i].ptr);
226  }
227 
228  leaf_type get_child_leaf(internal_type node, size_t i) const {
229  return static_cast<leaf_type>(node->values[i].ptr);
230  }
231 
232  size_t index(void * child, internal_type node) const {
233  for (size_t i=0; i < node->count; ++i)
234  if (node->values[i].ptr == child) return i;
235  tp_assert(false, "Not found");
236  tpie_unreachable();
237  }
238 
239  void set_augment(void * l, internal_type p, augment_type ag) {
240  size_t idx=index(l, p);
241  p->values[idx].augment = ag;
242  }
243 
244  const augment_type & augment(internal_type p, size_t i) const {
245  return p->values[i].augment;
246  }
247 
248  size_t height() const throw() {
249  return m_height;
250  }
251 
252  void set_height(size_t height) throw() {
253  m_height = height;
254  }
255 
256  size_t size() const throw() {
257  return m_size;
258  }
259 
260  void set_size(size_t size) throw() {
261  m_size = size;
262  }
263 
264  void flush() {}
265  void finalize_build() {}
266 
267  void set_metadata(const std::string & data) {
268  m_metadata = data;
269  }
270 
271  std::string get_metadata() {
272  return m_metadata;
273  }
274 
275  void * m_root;
276  size_t m_height;
277  size_t m_size;
278  std::string m_metadata;
279  memory_bucket_ref m_bucket;
280 
281  template <typename>
282  friend class ::tpie::btree_node;
283 
284  template <typename>
285  friend class ::tpie::btree_iterator;
286 
287  template <typename, typename>
288  friend class bbits::tree;
289 
290  template <typename, typename>
291  friend class bbits::tree_state;
292 
293  template<typename, typename>
294  friend class bbits::builder;
295 
296 
297 };
298 
299 } //namespace bbits
300 } //namespace tpie
301 #endif /*_TPIE_BTREE_INTERNAL_STORE_H_*/
A augment_type
Type of augmentation stored.
Defines the tp_assert macro.
Memory management subsystem.
Storage used for an internal btree.
Definition: base.h:211
This file contains a few deprecated definitions for legacy code.
Class storring a reference to a memory bucket.
Definition: memory.h:366
T value_type
Type of value of items stored.
void tpie_delete(T *p)
Delete an object allocated with tpie_new.
Definition: memory.h:301
#define tp_assert(condition, message)
Definition: tpie_assert.h:48