TPIE

2362a60
node.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_NODE_H_
21 #define _TPIE_BTREE_NODE_H_
22 
23 #include <tpie/portability.h>
24 #include <tpie/tpie_assert.h>
25 #include <tpie/btree/base.h>
26 #include <boost/iterator/iterator_facade.hpp>
27 #include <vector>
28 
29 namespace tpie {
30 
36 template <typename S>
37 class btree_node {
38 public:
39  typedef S state_type;
40 
41 
45  typedef typename S::key_type key_type;
46 
50  typedef typename S::augment_type augment_type;
51 
55  typedef typename S::value_type value_type;
56 
57 
58  typedef typename S::store_type store_type;
59 
65  bool has_parent() const {
66  if (m_is_leaf)
67  return !m_path.empty();
68  else
69  return m_path.size() > 1;
70  }
71 
77  void parent() {
78  if (m_is_leaf)
79  m_is_leaf = false;
80  else
81  m_path.pop_back();
82  }
83 
89  void child(size_t i) {
90  tp_assert(!m_is_leaf, "Is leaf");
91  tp_assert(i < count(), "Invalid i");
92  if (m_path.size() + 1 == m_state->store().height()) {
93  m_is_leaf = true;
94  m_leaf = m_state->store().get_child_leaf(m_path.back(), i);
95  } else
96  m_path.push_back(m_state->store().get_child_internal(m_path.back(), i));
97  }
98 
105  btree_node n=*this;
106  n.parent();
107  return n;
108  }
109 
115  btree_node get_child(size_t i) const {
116  btree_node n=*this;
117  n.child(i);
118  return n;
119  }
120 
124  bool is_leaf() const {
125  return m_is_leaf;
126  }
127 
133  const augment_type & get_augmentation(size_t i) const {
134  return state_type::user_augment(m_state->store().augment(m_path.back(), i));
135  }
136 
140  key_type min_key(size_t i) const {
141  if (m_is_leaf)
142  return m_state->min_key(m_leaf, i);
143  else
144  return m_state->min_key(m_path.back(), i);
145  }
146 
152  const value_type & value(size_t i) const {
153  tp_assert(m_is_leaf, "Not leaf");
154  return m_state->store().get(m_leaf, i);
155  }
156 
160  size_t count() const {
161  if (m_is_leaf)
162  return m_state->store().count(m_leaf);
163  else
164  return m_state->store().count(m_path.back());
165  }
166 
172  size_t index() const {
173  if (m_is_leaf)
174  return m_state->store().index(m_leaf, m_path.back());
175  return m_state->store().index(m_path.back(), m_path[m_path.size()-2]);
176  }
177 
178  btree_node(): m_state(nullptr) {}
179 private:
180 
181  const typename state_type::combined_augment & get_combined_augmentation(size_t i) const {
182  return m_state->store().augment(m_path.back(), i);
183  }
184 
185 
186  typedef typename store_type::leaf_type leaf_type;
187  typedef typename store_type::internal_type internal_type;
188 
189  btree_node(const state_type * state, leaf_type root)
190  : m_state(state), m_leaf(root), m_is_leaf(true) {
191  }
192 
193  btree_node(const state_type * state, internal_type root)
194  : m_state(state), m_is_leaf(false) {
195  m_path.push_back(root);
196  }
197 
198  btree_node(const state_type * state, std::vector<internal_type> path, leaf_type leaf)
199  : m_state(state), m_path(path), m_leaf(leaf), m_is_leaf(true) {
200  }
201 
202  const state_type * m_state;
203  std::vector<internal_type> m_path;
204  leaf_type m_leaf;
205  bool m_is_leaf;
206 
207  template <typename, typename>
208  friend class bbits::tree_state;
209 
210  template <typename, typename>
211  friend class bbits::tree;
212 
213  template <typename, typename>
214  friend class bbits::builder;
215 
216  template <typename>
217  friend class btree_iterator;
218 };
219 
220 template <typename S>
221 class btree_iterator: public boost::iterator_facade<
222  btree_iterator<S>,
223  typename S::value_type const,
224  boost::bidirectional_traversal_tag> {
225 
226 public:
227  // Do not declare value type as private!
228  // It is a required iterator typedef.
229  typedef typename S::value_type value_type;
230 
231 private:
232  typedef S state_type;
233  typedef typename S::store_type store_type;
234  typedef typename store_type::internal_type internal_type;
235  typedef typename store_type::leaf_type leaf_type;
236  typedef typename S::key_type key_type;
237 
238  const state_type * m_state;
239  std::vector<internal_type> m_path;
240  size_t m_index;
241  leaf_type m_leaf;
242 
243  template <typename, typename>
244  friend class bbits::tree;
245 
246  btree_iterator(const state_type * state): m_state(state) {}
247 
248  void goto_item(const std::vector<internal_type> & p, leaf_type l, size_t i) {
249  m_path = p;
250  m_leaf = l;
251  m_index = i;
252  }
253 
254 
255  void goto_begin() {
256  m_path.clear();
257  if (m_state->store().height() < 2) {
258  m_leaf = m_state->store().get_root_leaf();
259  m_index = 0;
260  return;
261  }
262  internal_type n = m_state->store().get_root_internal();
263  for (size_t i=2;; ++i) {
264  m_path.push_back(n);
265  if (i == m_state->store().height()) {
266  m_leaf = m_state->store().get_child_leaf(n, 0);
267  m_index = 0;
268  return;
269  }
270  n = m_state->store().get_child_internal(n, 0);
271  }
272  }
273 
274  void goto_end() {
275  m_path.clear();
276 
277  if(m_state->store().height() == 0) {
278  m_leaf = m_state->store().get_root_leaf();
279  m_index = 0;
280  return;
281  }
282 
283  if (m_state->store().height() == 1) {
284  m_leaf = m_state->store().get_root_leaf();
285  m_index = m_state->store().count(m_leaf);
286  return;
287  }
288  internal_type n = m_state->store().get_root_internal();
289  for (size_t i=2;; ++i) {
290  m_path.push_back(n);
291  if (i == m_state->store().height()) {
292  m_leaf = m_state->store().get_child_leaf(n, m_state->store().count(n)-1);
293  m_index = m_state->store().count(m_leaf);
294  return;
295  }
296  n = m_state->store().get_child_internal(n, m_state->store().count(n)-1);
297  }
298  }
299 
300 
301 public:
302  btree_iterator(): m_index(0), m_leaf() {}
303 
304  const value_type & dereference() const {
305  return m_state->store().get(m_leaf, m_index);
306  }
307 
308  bool equal(const btree_iterator & o) const {
309  return m_index == o.m_index && m_leaf == o.m_leaf;
310  }
311 
312  size_t index() const {return m_index;}
313 
314  btree_node<S> get_leaf() const {
315  return btree_node<S>(m_state, m_path, m_leaf);
316  }
317 
318  void decrement() {
319  if (m_index > 0) {
320  --m_index;
321  return;
322  }
323 
324  size_t i=m_state->store().index(m_leaf, m_path.back());
325  size_t x=0;
326  while (i == 0) {
327  internal_type n = m_path.back();
328  m_path.pop_back();
329  i = m_state->store().index(n, m_path.back());
330  ++x;
331  }
332  --i;
333 
334  while (x != 0) {
335  m_path.push_back(m_state->store().get_child_internal(m_path.back(), i));
336  i = m_state->store().count(m_path.back())-1;
337  --x;
338  }
339 
340  m_leaf = m_state->store().get_child_leaf(m_path.back(), i);
341  m_index = m_state->store().count(m_leaf)-1;
342  }
343 
344  void increment() {
345  m_index++;
346  if (m_index < m_state->store().count(m_leaf)) return;
347  if (m_path.empty()) return; //We are at the end
348 
349  size_t i=m_state->store().index(m_leaf, m_path.back());
350  size_t x=0;
351  while (i +1 == m_state->store().count(m_path.back())) {
352  internal_type n = m_path.back();
353  m_path.pop_back();
354  if (m_path.empty()) {
355  goto_end();
356  return;
357  }
358  i = m_state->store().index(n, m_path.back());
359  ++x;
360  }
361  ++i;
362  while (x != 0) {
363  m_path.push_back(m_state->store().get_child_internal(m_path.back(), i));
364  i = 0;
365  --x;
366  }
367  m_leaf = m_state->store().get_child_leaf(m_path.back(), i);
368  m_index = 0;
369  }
370 
371 };
372 
373 
374 } //namespace tpie
375 #endif //_TPIE_BTREE_NODE_H_
Defines the tp_assert macro.
btree_node get_child(size_t i) const
Return the ith child node.
Definition: node.h:115
S::augment_type augment_type
Type of the augment of a set of nodes/values.
Definition: node.h:50
bool has_parent() const
Check if this node has a parent.
Definition: node.h:65
This file contains a few deprecated definitions for legacy code.
void child(size_t i)
Move to the ith child.
Definition: node.h:89
key_type min_key(size_t i) const
Return the minimal key of the i'th child.
Definition: node.h:140
const value_type & value(size_t i) const
Return the i'th value.
Definition: node.h:152
size_t index() const
Return the index of this node in its parent.
Definition: node.h:172
const augment_type & get_augmentation(size_t i) const
Return the augmented data of the ith child.
Definition: node.h:133
Type that is useful for navigating a btree.
Definition: base.h:178
#define tp_assert(condition, message)
Definition: tpie_assert.h:48
S::key_type key_type
Type of the key of a value.
Definition: node.h:45
btree_node get_parent() const
Return the parent node.
Definition: node.h:104
void parent()
Move to the parent node.
Definition: node.h:77
S::value_type value_type
Type of values.
Definition: node.h:55
bool is_leaf() const
Return true if this is a leaf node.
Definition: node.h:124
size_t count() const
Return the number of children or values.
Definition: node.h:160