STL Memory Versioning
vs_tree.h
Go to the documentation of this file.
1 #ifndef _VS_TREE_H
2 #define _VS_TREE_H
3 
4 #include <functional>
5 #include <initializer_list>
6 #include <iterator>
7 #include <stack>
8 #include <iostream>
9 #include <sstream>
10 
11 #include "versioned.h"
12 #include "revision.h"
13 #include "strategy.h"
14 
15 namespace vs
16 {
17  template<typename _Key, typename _Comp>
18  class vs_tree_strategy;
19 
20  /* internal class */
21 
25  template<typename _Key, typename _Comp = std::less<_Key>>
27  {
28  public:
29 
31  typedef int size_type;
32 
33  _Key value;
35  _Ptr_type left = nullptr;
36  _Ptr_type right = nullptr;
37 
38  /* ------------------ Constructors ----------------------*/
39 
40  _vs_tree_node(const _Key& _value)
41  : value(_value){ }
42 
44  : value(_node.value), height(_node.height) { }
45 
46  /* ------------------- Balancing ----------------------*/
47 
49  {
50  size_type lh = (left ? left->height + 1 : 0);
51  size_type rh = (right ? right->height + 1 : 0);
52 
53  height = (lh > rh ? lh : rh);
54  }
55 
56  size_type
58  {
59  size_type lh = (left ? left->height + 1 : 0);
60  size_type rh = (right ? right->height + 1 : 0);
61 
62  return lh - rh;
63  }
64 
65  _Ptr_type
67  {
69 
70  switch (node_delta_height())
71  {
72  case 2:
73  if (left->node_delta_height() < 0)
74  left = left->turnleft();
75 
76  return turnright();
77 
78  case -2:
79  if (right->node_delta_height() > 0)
80  right = right->turnright();
81  return turnleft();
82 
83  default:
84  return this;
85  }
86  }
87 
88  _Ptr_type
90  _Ptr_type child = right;
91  right = child->left;
92  child->left = this;
94  child->refresh_node_height();
95  return child;
96  }
97 
98  _Ptr_type
100  _Ptr_type child = left;
101  left = child->right;
102  child->right = this;
104  child->refresh_node_height();
105  return child;
106  }
107 
111  _Ptr_type
112  node_insert(const _Key& _value, _Comp comp = _Comp{})
113  {
114  if (comp(_value, this->value))
115  {
116  if (left)
117  {
118  left = left->node_insert(_value);
119  }
120  else
121  {
122  left = new _vs_tree_node(_value);
123  }
124  }
125  else
126  {
127  if (right)
128  {
129  right = right->node_insert(_value);
130  }
131  else
132  {
133  right = new _vs_tree_node(_value);
134  }
135  }
136 
137  return rebalance();
138  }
139 
140  };
141 
142  template<typename _Key, typename _Comp = std::less<_Key>>
144  {
145  public:
146 
148 
149  typedef _Key value_type;
150  typedef _Key& reference;
151  typedef _Key* pointer;
152 
153  typedef std::forward_iterator_tag iterator_category;
154  typedef ptrdiff_t difference_type;
155 
157 
159  : parents(), node() { }
160 
161  explicit
163  : parents(), node(__x) { }
164 
165  reference
167  { return node->value; }
168 
169  pointer
171  { return &(node->value); }
172 
173  /* ------------------ Post/Pre-increment ----------------------*/
174  _Self&
176  {
177  dfs_increment();
178  return *this;
179  }
180 
181  _Self
183  {
184  _Self __tmp = *this;
185  dfs_increment();
186  return __tmp;
187  }
188 
189  // _Self&
190  // operator--()
191  // {
192  // dfs_decrement();
193  // return *this;
194  // }
195 
196  // _Self
197  // operator--(int)
198  // {
199  // _Self __tmp = *this;
200  // dfs_decrement();
201  // return __tmp;
202  // }
203 
204  friend bool
205  operator==(const _Self& __x, const _Self& __y)
206  { return __x.node == __y.node; }
207 
208  friend bool
209  operator!=(const _Self& __x, const _Self& __y)
210  { return __x.node != __y.node; }
211 
212  /* dirty hack, but i do not want to store and refresh parents */
213  std::stack<_Ptr_type> parents;
215 
216  private:
217 
218  void
219  dfs_increment()
220  {
221  if (node->left)
222  {
223  parents.push(node);
224  node = node->left;
225  }
226  else if (node->right)
227  {
228  parents.push(node);
229  node = node->right;
230  }
231  else
232  {
233  while (!parents.empty())
234  {
235  bool came_with_right = (parents.top()->right == node ? true : false);
236  node = parents.top();
237  if (came_with_right)
238  {
239  parents.pop();
240  continue;
241  }
242 
243  if (node->right)
244  {
245  node = node->right;
246  break;
247  }
248  else
249  parents.pop();
250  }
251 
252  if (parents.empty())
253  {
254  /* end() iterator, reached top and cannot advance right */
255  node = nullptr;
256  }
257  }
258  }
259  };
260 
265  template<typename _Key, typename _Comp = std::less<_Key>>
266  class _vs_tree
267  {
268  public:
269 
270  /* public typedefs */
274 
275  /* needed for concept */
276  typedef _Key value_type;
277 
278  private:
279 
280  _Ptr_type head = nullptr;
281  /* _ because of typedef's declaration conflicts */
282  size_type _height = 0;
283  size_type _size = 0;
284 
291  void
292  copy_subtree(_Ptr_type dst, _Ptr_type src)
293  {
294  if (src->left)
295  {
296  dst->left = new _vs_tree_node(*(src->left));
297  copy_subtree(dst->left, src->left);
298  }
299  if (src->right)
300  {
301  dst->right = new _vs_tree_node(*(src->right));
302  copy_subtree(dst->right, src->right);
303  }
304  }
305 
312  void
313  delete_subtree(_Ptr_type node)
314  {
315  if (node->left)
316  delete_subtree(node->left);
317 
318  if (node->right)
319  delete_subtree(node->right);
320 
321  delete node;
322  }
323 
324  public:
325  /* ------------------ Constructors ----------------------*/
326 
327  _vs_tree() = default;
328 
329  _vs_tree(const _vs_tree& _tree)
330  {
331  if (_tree.head) {
332  this->head = new _vs_tree_node(*(_tree.head));
333  copy_subtree(this->head, _tree.head);
334  }
335 
336  }
337 
339  {
340  std::cout << "deleting " << this << std::endl;
341  if (head)
342  delete_subtree(head);
343 
344  head = nullptr;
345  }
346 
347  /* ------------------ Accessors ----------------------*/
348 
349  iterator
351  {
352  return iterator(this->head);
353  }
354  iterator
355  end()
356  {
357  return iterator(nullptr);
358  }
359 
360  iterator
361  begin() const
362  {
363  return iterator(this->head);
364  }
365  iterator
366  end() const
367  {
368  return iterator(nullptr);
369  }
370 
371  const _Key&
372  top()
373  {
374  return *begin();
375  }
376 
380  iterator
381  find(const _Key& _x) const
382  {
383  return find_subtree(_x, head);
384  }
385 
386  iterator
387  find_subtree(const _Key& _x, const _Ptr_type& node, _Comp comp = _Comp{}) const
388  {
389  if (node->value == _x)
390  return iterator(node);
391 
392  if (comp(_x, node->value))
393  {
394  if (node->left)
395  return find_subtree(_x, node->left);
396  else
397  return end();
398  }
399  else
400  {
401  if (node->right)
402  return find_subtree(_x, node->right);
403  else
404  return end();
405  }
406  }
407 
408  size_type
409  height() const
410  { return _height; }
411 
412  size_type
413  size() const
414  { return _size; }
415 
416  /* ------------------ Operators ----------------------*/
417 
418  void
419  push(const _Key& _value)
420  {
421  if (head)
422  head = head->node_insert(_value);
423  else
424  head = new _vs_tree_node<_Key, _Comp>(_value);
425 
426  _height = head->height + 1;
427  _size++;
428  }
429 
430  // void
431  // pop()
432  // {
433  // if (head)
434  // {
435  // head->node_delete();
436  // _height = head.height + 1;
437  // _size--;
438  // }
439  // }
440 
441  };
442 
443  /* TODO: add param _Strategy */
444 
452  template<typename _Key, typename _Comp = std::less<_Key>, typename _Strategy = vs_tree_strategy<_Key, _Comp>>
453  class vs_tree
454  {
455 
456  static_assert(vs::IsMergeStrategy<_Strategy, _vs_tree<_Key, _Comp>>,
457  "Provided invalid strategy class in template");
458 
459  public:
460  /* public typedefs */
461 
465 
466  private:
467 
468  _Versioned _v_t;
469 
470  public:
471 
472  /* ------------------ Constructors ----------------------*/
477  explicit
478  vs_tree(const _Comp& __comp = _Comp())
479  : _v_t(_vs_tree<_Key, _Comp>()) { }
480 
489  vs_tree(std::initializer_list<_Key> __l,
490  const _Comp& __comp = _Comp())
491  : _v_t(_vs_tree<_Key, _Comp>())
492  {
493  _v_t.Set(_v_t.Get(),
494  [&](_vs_tree<_Key, _Comp>& _tree){
495  for (auto& i: __l){
496  _tree.push(i);
497  }
498  return true;
499  });
500  }
501 
507  vs_tree(const vs_tree& __vs_tree)
508  : _v_t(__vs_tree._v_t.Get()) { }
509 
510  //* @brief tree move constructor
511 
512  //* @brief Builds a tree from a range.
513 
514 
515  /* ------------------ Accessors ----------------------*/
516 
523  iterator
524  begin() const
525  { return _v_t.Get().begin(); }
526 
533  iterator
534  end() const
535  { return _v_t.Get().end(); }
536 
540  size_type
541  size() const noexcept
542  { return _v_t.Get().size(); }
543 
547  size_type
548  height() const noexcept
549  { return _v_t.Get().height(); }
550 
554  iterator
555  find(const _Key& __x) const
556  { return _v_t.Get().find(__x); }
557 
558  /* ------------------ Operators ----------------------*/
559 
560  /* XXX: move insert */
561 
566  void
567  push(const _Key& __x)
568  {
569  _v_t.Set(_v_t.Get(), [&](_vs_tree<_Key, _Comp>& _tree){_tree.push(__x); return true;});
570  }
571  // = (copy)
572  // = {}
573  };
574 
582  template<typename _Key, typename _Comp>
584  {
585  public:
586 
587  void
589  {
590  for (auto& i: src)
591  {
592  auto found = dst.find(i);
593  if (found != dst.end())
594  merge_same_element(dst, *found, i);
595  else
596  dst.push(i);
597  }
598  }
599 
600  void
601  merge_same_element(_vs_tree<_Key, _Comp>& dst, _Key& dstk, _Key& srck)
602  {
603  /* pretend we didnt saw new elements */
604  }
605 
606  };
607 
608  template<typename _Key, typename _Comp>
609  std::ostream& operator << (std::ostream& os, vs_tree<_Key,_Comp> const& value) {
610  vs_tree<_Key,_Comp> temp = value;
611 
612  std::ostringstream o;
613  o << "{ ";
614  for (auto& i: temp) {
615  o << i << ", ";
616  }
617  o << " }";
618 
619  os << o.str();
620  return os;
621  }
622 }
623 
624 #endif
Wrapper to make any class Versioned.
Definition: versioned.h:53
const T & Get() const
Get the current value of the object in the current Revision.
Definition: versioned.h:186
bool Set(const T &v, const std::function< bool(T &)> &updater=nullptr)
Set new value of the object.
Definition: versioned.h:205
serves as stl-like interface from node to vs_tree; handles allocations in construction and destructio...
Definition: vs_tree.h:267
_vs_tree(const _vs_tree &_tree)
Definition: vs_tree.h:329
_vs_tree_node< _Key, _Comp >::_Ptr_type _Ptr_type
Definition: vs_tree.h:272
_vs_tree_node< _Key, _Comp >::size_type size_type
Definition: vs_tree.h:273
const _Key & top()
Definition: vs_tree.h:372
_vs_tree_iterator< _Key, _Comp > iterator
Definition: vs_tree.h:271
iterator end() const
Definition: vs_tree.h:366
size_type height() const
Definition: vs_tree.h:409
void push(const _Key &_value)
Definition: vs_tree.h:419
iterator begin()
Definition: vs_tree.h:350
_Key value_type
Definition: vs_tree.h:276
iterator end()
Definition: vs_tree.h:355
iterator begin() const
Definition: vs_tree.h:361
_vs_tree()=default
iterator find_subtree(const _Key &_x, const _Ptr_type &node, _Comp comp=_Comp{}) const
Definition: vs_tree.h:387
size_type size() const
Definition: vs_tree.h:413
iterator find(const _Key &_x) const
simple recursive implementation of find
Definition: vs_tree.h:381
simpliest determenistic merge strategy.
Definition: vs_tree.h:584
void merge_same_element(_vs_tree< _Key, _Comp > &dst, _Key &dstk, _Key &srck)
Definition: vs_tree.h:601
void merge(_vs_tree< _Key, _Comp > &dst, _vs_tree< _Key, _Comp > &src)
Definition: vs_tree.h:588
A versioned AVL-tree with deep copy constructor in internal classes.
Definition: vs_tree.h:454
vs_tree(std::initializer_list< _Key > __l, const _Comp &__comp=_Comp())
Builds a vs_tree from an initializer_list.
Definition: vs_tree.h:489
iterator end() const
end constant iterator
Definition: vs_tree.h:534
_vs_tree< _Key, _Comp >::iterator iterator
Definition: vs_tree.h:463
Versioned< _vs_tree< _Key, _Comp >, _Strategy > _Versioned
Definition: vs_tree.h:457
void push(const _Key &__x)
Attempts to insert an element into the vs_tree.
Definition: vs_tree.h:567
iterator find(const _Key &__x) const
find element in tree
Definition: vs_tree.h:555
size_type size() const noexcept
size of underlying tree
Definition: vs_tree.h:541
_vs_tree< _Key, _Comp >::size_type size_type
Definition: vs_tree.h:464
size_type height() const noexcept
height of underlying tree
Definition: vs_tree.h:548
iterator begin() const
begin constant iterator
Definition: vs_tree.h:524
vs_tree(const vs_tree &__vs_tree)
vs_tree copy constructor
Definition: vs_tree.h:507
vs_tree(const _Comp &__comp=_Comp())
Creates a vs_tree with no elements.
Definition: vs_tree.h:478
Definition: strategy.h:6
std::ostream & operator<<(std::ostream &os, vs_tree< _Key, _Comp > const &value)
Definition: vs_tree.h:609
concept IsMergeStrategy
Concept for compile-time type checking passed user strategies.
Definition: strategy.h:12
Implementation of the class Revision.
friend bool operator!=(const _Self &__x, const _Self &__y)
Definition: vs_tree.h:209
_vs_tree_iterator(_Ptr_type __x)
Definition: vs_tree.h:162
_vs_tree_iterator< _Key, _Comp > _Self
Definition: vs_tree.h:156
_vs_tree_node< _Key, _Comp >::_Ptr_type _Ptr_type
Definition: vs_tree.h:147
std::forward_iterator_tag iterator_category
Definition: vs_tree.h:153
ptrdiff_t difference_type
Definition: vs_tree.h:154
pointer operator->()
Definition: vs_tree.h:170
_Self & operator++()
Definition: vs_tree.h:175
friend bool operator==(const _Self &__x, const _Self &__y)
Definition: vs_tree.h:205
std::stack< _Ptr_type > parents
Definition: vs_tree.h:213
reference operator*()
Definition: vs_tree.h:166
_Self operator++(int)
Definition: vs_tree.h:182
Manages all balancing logic and correlating allocations;.
Definition: vs_tree.h:27
void refresh_node_height()
Definition: vs_tree.h:48
_Ptr_type right
Definition: vs_tree.h:36
_Ptr_type node_insert(const _Key &_value, _Comp comp=_Comp{})
Fall down recursively, insert and rebalance on the way up.
Definition: vs_tree.h:112
size_type node_delta_height()
Definition: vs_tree.h:57
_Ptr_type turnleft()
Definition: vs_tree.h:89
size_type height
Definition: vs_tree.h:34
_vs_tree_node(const _vs_tree_node &_node)
Definition: vs_tree.h:43
_Ptr_type rebalance()
Definition: vs_tree.h:66
_vs_tree_node< _Key, _Comp > * _Ptr_type
Definition: vs_tree.h:30
_Ptr_type turnright()
Definition: vs_tree.h:99
_Ptr_type left
Definition: vs_tree.h:35
_vs_tree_node(const _Key &_value)
Definition: vs_tree.h:40
Implementation of the Versioned classes and interface.