A library for working with phylogenetic and population genetic data.
v0.27.0
utils/containers/interval_tree/node.hpp
Go to the documentation of this file.
1 #ifndef GENESIS_UTILS_CONTAINERS_INTERVAL_TREE_NODE_H_
2 #define GENESIS_UTILS_CONTAINERS_INTERVAL_TREE_NODE_H_
3 
4 /*
5  Genesis - A toolkit for working with phylogenetic data.
6  Copyright (C) 2014-2021 Lucas Czech
7 
8  This program is free software: you can kRedistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program. If not, see <http://www.gnu.org/licenses/>.
20 
21  Contact:
22  Lucas Czech <lczech@carnegiescience.edu>
23  Department of Plant Biology, Carnegie Institution For Science
24  260 Panama Street, Stanford, CA 94305, USA
25 */
26 
27 /*
28  The code below is adapted from https://github.com/5cript/interval-tree
29  which was published under the CC0-1.0 License (Creative Commons Zero v1.0 Universal).
30  We modified the code to fit our needs and formatting, but the functionality is the same.
31  */
32 
40 #include <cassert>
41 #include <cstdio>
42 #include <iostream>
43 #include <iterator>
44 #include <memory>
45 #include <stdexcept>
46 #include <string>
47 #include <type_traits>
48 
52 
53 namespace genesis {
54 namespace utils {
55 
56 // =================================================================================================
57 // Typedefs
58 // =================================================================================================
59 
65 enum class RedBackColor
66 {
67  kInvalid,
68  kRed,
69  kBlack,
71 };
72 
73 // =================================================================================================
74 // Interval Node
75 // =================================================================================================
76 
86 template <
87  typename DataType = EmptyIntervalData,
88  typename NumericalType = DefaultIntervalNumericalType,
89  typename IntervalKind = IntervalClosed
90 >
91 class IntervalTreeNode
92 {
93 public:
94 
95  // -------------------------------------------------------------------------
96  // Member Types
97  // -------------------------------------------------------------------------
98 
99  using data_type = DataType;
100  using numerical_type = NumericalType;
101  using interval_kind = IntervalKind;
102 
106 
107  // using value_type = NumericalType;
109 
110  // Make the tree and the const and non-const iterators friends.
114 
115  // -------------------------------------------------------------------------
116  // Constructors and Rule of Five
117  // -------------------------------------------------------------------------
118 
119 public:
120 
123  {}
124 
126  : interval_{ std::move(interval) }
127  , max_{ interval.high() }
128  , parent_{ parent }
129  , left_{}
130  , right_{}
131  , color_{ RedBackColor::kInvalid }
132  {}
133 
134  ~IntervalTreeNode() = default;
135 
136  IntervalTreeNode( IntervalTreeNode const& ) = default;
137  IntervalTreeNode( IntervalTreeNode&& ) = default;
138 
139  IntervalTreeNode& operator= ( IntervalTreeNode const& ) = default;
141 
142  // -------------------------------------------------------------------------
143  // Operators
144  // -------------------------------------------------------------------------
145 
146  interval_type const& interval() const
147  {
148  return interval_;
149  }
150 
152  {
153  return max_;
154  }
155 
156  bool is_left() const noexcept
157  {
158  return this == parent_->left_;
159  }
160 
161  bool is_right() const noexcept
162  {
163  return this == parent_->right_;
164  }
165 
166  bool is_root() const noexcept
167  {
168  return !parent_;
169  }
170 
175  {
176  return color_;
177  }
178 
182  IntervalTreeNode const* parent() const
183  {
184  return parent_;
185  }
186 
190  IntervalTreeNode const* left() const
191  {
192  return left_;
193  }
194 
198  IntervalTreeNode const* right() const
199  {
200  return right_;
201  }
202 
209  size_t height() const
210  {
211  size_t counter{0};
212  for( auto* p = parent_; p != nullptr; p = p->parent_ ) {
213  ++counter;
214  }
215  return counter;
216  }
217 
222  {
223  return interval_.low();
224  }
225 
230  {
231  return interval_.high();
232  }
233 
234 private:
235 
236  void set_interval( interval_type const& ival )
237  {
238  interval_ = ival;
239  }
240 
241  void set_interval( interval_type && ival )
242  {
243  interval_ = std::move( ival );
244  }
245 
246  // void kill() const noexcept
247  // {
248  // auto* parent = parent_;
249  // if (is_left())
250  // {
251  // delete parent_->left_;
252  // parent->left_ = nullptr;
253  // }
254  // else
255  // {
256  // delete parent_->right_;
257  // parent->right_ = nullptr;
258  // }
259  // }
260 
261 private:
262 
263  // Store the actual interval that this node represents, as well as the max of all
264  // intervals high() values, as needed by the Interval Tree data structure.
265  interval_type interval_;
266  numerical_type max_;
267 
268  // Our relatives.
269  IntervalTreeNode* parent_;
270  IntervalTreeNode* left_;
271  IntervalTreeNode* right_;
272 
273  // We use a Red-Black tree as our balanced underlying data structure.
274  RedBackColor color_;
275 };
276 
277 } // namespace utils
278 } // namespace genesis
279 
280 #endif // include guard
genesis::utils::Interval
Type to store an interval (range) between two numbers, as used in the IntervalTree.
Definition: fwd.hpp:42
genesis::utils::DefaultIntervalNumericalType
int DefaultIntervalNumericalType
Default numerical type to use in an Interval.
Definition: interval.hpp:61
functions.hpp
genesis::utils::RedBackColor::kRed
@ kRed
genesis::utils::IntervalTreeNode::data_type
DataType data_type
Definition: utils/containers/interval_tree/node.hpp:99
genesis::utils::IntervalTreeNode::node_type
IntervalTreeNode< DataType, NumericalType, IntervalKind > node_type
Definition: utils/containers/interval_tree/node.hpp:104
fwd.hpp
genesis::utils::IntervalTreeNode::is_right
bool is_right() const noexcept
Definition: utils/containers/interval_tree/node.hpp:161
genesis::utils::RedBackColor::kKDoubleBlack
@ kKDoubleBlack
genesis::utils::IntervalTreeIterator
Iterate the Intervals stored in an IntervalTree.
Definition: fwd.hpp:51
genesis::utils::IntervalTreeNode
Node in an IntervalTree.
Definition: fwd.hpp:48
genesis::utils::IntervalTreeNode::is_left
bool is_left() const noexcept
Definition: utils/containers/interval_tree/node.hpp:156
genesis::utils::RedBackColor::kInvalid
@ kInvalid
genesis::utils::Interval::high
numerical_type high() const
Return the upper bound of the interval.
Definition: interval.hpp:472
genesis::utils::IntervalTreeNode::interval
interval_type const & interval() const
Definition: utils/containers/interval_tree/node.hpp:146
genesis::utils::IntervalTreeNode::~IntervalTreeNode
~IntervalTreeNode()=default
genesis::utils::Interval::low
numerical_type low() const
Return the lower bound of the interval.
Definition: interval.hpp:464
genesis
Container namespace for all symbols of genesis in order to keep them separate when used as a library.
Definition: placement/formats/edge_color.cpp:42
genesis::utils::IntervalTreeNode::right
IntervalTreeNode const * right() const
Definition: utils/containers/interval_tree/node.hpp:198
genesis::utils::IntervalTreeNode::low
numerical_type low() const
Return the lower bound of the interval of this node.
Definition: utils/containers/interval_tree/node.hpp:221
genesis::utils::RedBackColor
RedBackColor
Definition for Red-Black Tree coloring.
Definition: utils/containers/interval_tree/node.hpp:65
genesis::utils::IntervalTreeNode::interval_type
Interval< DataType, NumericalType, IntervalKind > interval_type
Definition: utils/containers/interval_tree/node.hpp:103
genesis::utils::IntervalTreeNode::left
IntervalTreeNode const * left() const
Definition: utils/containers/interval_tree/node.hpp:190
genesis::utils::IntervalTreeNode::IntervalTreeNode
IntervalTreeNode(IntervalTreeNode *parent, interval_type &&interval)
Definition: utils/containers/interval_tree/node.hpp:125
genesis::utils::IntervalTreeNode::parent
IntervalTreeNode const * parent() const
Definition: utils/containers/interval_tree/node.hpp:182
interval.hpp
genesis::utils::RedBackColor::kBlack
@ kBlack
genesis::utils::IntervalTreeNode::IntervalTreeNode
IntervalTreeNode(IntervalTreeNode *parent, interval_type const &interval)
Definition: utils/containers/interval_tree/node.hpp:121
genesis::utils::IntervalTreeNode::high
numerical_type high() const
Return the upper bound of the interval of this node.
Definition: utils/containers/interval_tree/node.hpp:229
genesis::utils::IntervalTreeNode::height
size_t height() const
Return the height of the node in the tree.
Definition: utils/containers/interval_tree/node.hpp:209
genesis::utils::IntervalTreeNode::numerical_type
NumericalType numerical_type
Definition: utils/containers/interval_tree/node.hpp:100
genesis::utils::IntervalTreeNode::interval_kind
IntervalKind interval_kind
Definition: utils/containers/interval_tree/node.hpp:101
genesis::utils::IntervalTree
Interval tree that enables storing and querying intervals, each containing some data.
Definition: fwd.hpp:45
genesis::utils::IntervalTreeNode::color
RedBackColor color() const
Definition: utils/containers/interval_tree/node.hpp:174
genesis::utils::IntervalTreeNode::is_root
bool is_root() const noexcept
Definition: utils/containers/interval_tree/node.hpp:166
genesis::utils::IntervalTreeNode::operator=
IntervalTreeNode & operator=(IntervalTreeNode const &)=default
genesis::utils::IntervalTreeNode::max
numerical_type max() const
Definition: utils/containers/interval_tree/node.hpp:151