Yggdrasill  0.2
ziptree.hpp
1 #ifndef YGG_ZIPTREE_H
2 #define YGG_ZIPTREE_H
3 
4 #include "bst.hpp"
5 #include "options.hpp"
6 #include "size_holder.hpp"
7 #include "tree_iterator.hpp"
8 #include "util.hpp"
9 
10 #ifdef YGG_STORE_SEQUENCE
11 #include "benchmark_sequence.hpp"
12 #endif
13 
14 #include <cmath>
15 #include <functional>
16 
17 namespace ygg {
18 
19 // Forward
20 template <class Node, class Options = DefaultOptions, class Tag = int>
22 
23 namespace ztree_internal {
25 
26 template <class Tree, bool enable>
27 struct dbg_verify_size_helper
28 {
29  void operator()(const Tree & t, size_t node_count);
30 };
31 
32 template <class Node, class Options, bool use_hash, bool store>
33 class ZTreeRankGenerator;
34 
35 template <class Node, class Options>
36 class ZTreeRankGenerator<Node, Options, true, false> {
37 public:
38  ZTreeRankGenerator();
39  static void update_rank(Node & node) noexcept;
40  static int get_rank(const Node & node) noexcept;
41 };
42 
43 template <class Node, class Options>
44 class ZTreeRankGenerator<Node, Options, true, true> {
45 public:
46  ZTreeRankGenerator();
47  static void update_rank(Node & node) noexcept;
48  static size_t get_rank(const Node & node) noexcept;
49 
50 private:
51  template <class, class, class>
52  friend class ZTreeNodeBase;
53  typename Options::ztree_rank_type::type rank;
54 };
55 
56 template <class Node, class Options>
57 class ZTreeRankGenerator<Node, Options, false, true> {
58 public:
59  ZTreeRankGenerator();
60  template <class URBG>
61  ZTreeRankGenerator(URBG && g);
62  static void update_rank(Node & node) noexcept;
63  static size_t get_rank(const Node & node) noexcept;
64 
65 private:
66  template <class, class, class>
67  friend class ZTreeNodeBase;
68  typename Options::ztree_rank_type::type rank;
69 };
70 
71 template <class Node, class Options>
72 class ZTreeRankGenerator<Node, Options, false, false> {
73  // Build a static assertion that always fails, but
74  // only if this specialization is ever used. Thus, it must depend on
75  // the template parameters.
76  static_assert(!std::is_class<Node>::value || std::is_class<Node>::value,
77  "If rank-by-hash is not used, ranks must be stored.");
78 };
80 } // namespace ztree_internal
81 
97 template <class Node, class Options, class Tag>
98 class ZTreeNodeBase : public bst::BSTNodeBase<Node, Tag> {
99 public:
100  // Debugging methods
101  size_t get_depth() const noexcept;
102 
103 protected:
115  void
116  update_rank() noexcept
117  {
118  ztree_internal::ZTreeRankGenerator<
119  Node, Options, Options::ztree_use_hash,
120  Options::ztree_store_rank>::update_rank(*static_cast<Node *>(this));
121  }
122 
123 private:
124  template <class, class, bool, bool>
125  friend class ztree_internal::ZTreeRankGenerator;
126 
127  ztree_internal::ZTreeRankGenerator<Node, Options, Options::ztree_use_hash,
128  Options::ztree_store_rank>
129  _zt_rank;
130 };
131 
132 template <class Node>
134 public:
135  // clang-format off
136  /*
137  * Callbacks for Zipping
138  */
139  void init_zipping(Node * to_be_deleted) const noexcept {(void)to_be_deleted;};
140  void delete_without_zipping(Node * to_be_deleted) const noexcept {(void)to_be_deleted;};
141  void before_zip_from_left(Node * left_head) const noexcept {(void)left_head;};
142  void before_zip_from_right(Node * right_head) const noexcept {(void)right_head;};
143  void zipping_ended_left_without_tree(Node * prev_left_head) const noexcept {(void)prev_left_head;};
144  void zipping_ended_right_without_tree(Node * prev_right_head) const noexcept {(void)prev_right_head;};
145  void before_zip_tree_from_left(Node * left_head) const noexcept {(void)left_head;};
146  void before_zip_tree_from_right(Node * right_head) const noexcept {(void)right_head;};
147  void zipping_done(Node * head, Node * tail) const noexcept {(void)head; (void)tail;}
148 
149  /*
150  * Callbacks for Unzipping
151  */
152  void init_unzipping(Node * to_be_inserted) const noexcept {(void) to_be_inserted;};
153  void unzip_to_left(Node * n) const noexcept {(void)n;}
154  void unzip_to_right(Node * n) const noexcept {(void)n;}
155  void unzip_done(Node * unzip_root, Node * left_spine_end, Node * right_spine_end) const noexcept
156  {
157  (void) unzip_root;
158  (void) left_spine_end;
159  (void) right_spine_end;
160  }
161  // clang-format on
162 };
163 
189 template <
190  class Node, class NodeTraits, class Options = DefaultOptions,
191  class Tag = int, class Compare = ygg::utilities::flexible_less,
192  class RankGetter = ztree_internal::ZTreeRankGenerator<
193  Node, Options, Options::ztree_use_hash, Options::ztree_store_rank>>
194 class ZTree : public bst::BinarySearchTree<Node, Options, Tag, Compare> {
195 public:
199 
203  ZTree() noexcept;
204 
205  static_assert(std::is_base_of<NB, Node>::value,
206  "Node class not properly derived from node base!");
207 
216  ZTree(MyClass && other) noexcept;
217 
226  MyClass & operator=(MyClass && other) noexcept;
227 
228  /*
229  * Pull in classes from base tree
230  */
231  template <bool reverse>
232  using iterator = typename TB::template iterator<reverse>;
233  template <bool reverse>
234  using const_iterator = typename TB::template const_iterator<reverse>;
235 
250  void insert(Node & node) noexcept;
251  void insert(Node & node, Node & hint) noexcept;
252 
260  void remove(Node & node) CMP_NOEXCEPT(node);
261 
283  template <class Comparable>
284  utilities::select_type_t<size_t, Node *, Options::stl_erase>
285  erase(const Comparable & c) CMP_NOEXCEPT(c);
286 
301  template <bool reverse>
302  utilities::select_type_t<const iterator<reverse>, Node *, Options::stl_erase>
303  erase(const iterator<reverse> & it) CMP_NOEXCEPT(*it);
304 
305  // Debugging methods
306  void dbg_verify() const;
307  void dbg_print_rank_stats() const;
308 
317  void dump_to_dot(const std::string & filename) const;
318 
319 private:
320  void unzip(Node & oldn, Node & newn) noexcept;
321  void zip(Node & old_root) noexcept;
322 
323  // Debugging methods
324  void dbg_verify_consistency(Node * sub_root, Node * lower_bound,
325  Node * upper_bound) const;
326  void dbg_verify_size() const;
327 
328  template <class NodeNameGetter>
329  void dump_to_dot_base(const std::string & filename,
330  NodeNameGetter name_getter) const;
331 
332  template <class NodeNameGetter>
333  void output_node_base(const Node * node, std::ofstream & out,
334  NodeNameGetter name_getter) const;
335 
336 #ifdef YGG_STORE_SEQUENCE
337  typename ygg::utilities::template BenchmarkSequenceStorage<
338  typename Options::SequenceInterface::KeyT>
339  bss;
340 #endif
341 };
342 
343 } // namespace ygg
344 
345 #ifndef YGG_ZIPTREE_CPP
346 #include "ziptree.cpp"
347 #endif
348 
349 #endif
Definition: bst.hpp:123
Definition: bst.hpp:78
The Zip Tree.
Definition: ziptree.hpp:194
Definition: ziptree.hpp:133
Base class (template) to supply your node class with metainformation.
Definition: ziptree.hpp:21
Definition: rbtree.hpp:18