1 #ifndef GENESIS_UTILS_CONTAINERS_INTERVAL_TREE_H_
2 #define GENESIS_UTILS_CONTAINERS_INTERVAL_TREE_H_
48 #include <type_traits>
74 typename DataType = EmptyIntervalData,
76 typename IntervalKind = IntervalClosed
131 if (other.root_ !=
nullptr) {
132 root_ = copy_tree_( other.root_,
nullptr );
158 return root_ ==
nullptr;
166 return {root_,
this};
174 return {root_,
this};
185 throw std::runtime_error(
"Cannot call lowest() on empty IntervalTree" );
187 return minimum_( root_ )->
low();
198 throw std::runtime_error(
"Cannot call highest() on empty IntervalTree" );
221 while (iter->left_) {
231 return iterator{ get_begin_node_(),
this };
236 return {
nullptr,
this};
269 template <
typename CompareFunctionT>
272 if (root_ ==
nullptr) {
275 return iterator{ find_(root_, ival, compare),
this };
284 template <
typename CompareFunctionT>
287 if (root_ ==
nullptr) {
330 template <
typename FunctionT,
typename CompareFunctionT>
333 FunctionT
const& on_find,
334 CompareFunctionT
const& compare
336 if (root_ ==
nullptr) {
339 find_all_<self_type, iterator>(
this, root_, ival, on_find, compare);
345 template <
typename FunctionT,
typename CompareFunctionT>
348 FunctionT
const& on_find,
349 CompareFunctionT
const& compare
351 if (root_ ==
nullptr) {
354 find_all_<self_type, const_iterator>(
this, root_, ival, on_find, compare);
360 template <
typename FunctionT>
375 template <
typename FunctionT>
398 template <
typename CompareFunctionT>
402 CompareFunctionT
const& compare
404 if (root_ ==
nullptr) {
407 return iterator{find_ex_(from.node_, ival, compare),
this};
410 template <
typename CompareFunctionT>
414 CompareFunctionT
const& compare
416 if (root_ ==
nullptr) {
419 return iterator{find_ex_(from.node_, ival, compare),
this};
462 if (root_ ==
nullptr) {
466 return iterator{overlap_find_<true>(root_, ival),
this};
468 return iterator{overlap_find_<false>(root_, ival),
this};
474 if (root_ ==
nullptr) {
513 template <
typename FunctionT>
516 FunctionT
const& on_find,
517 bool exclusive =
false
519 if (root_ ==
nullptr) {
523 overlap_find_all_<self_type, true, iterator, FunctionT>(
524 this, root_, ival, on_find
527 overlap_find_all_<self_type, false, iterator, FunctionT>(
528 this, root_, ival, on_find
533 template <
typename FunctionT>
536 FunctionT
const& on_find,
537 bool exclusive =
false
539 if (root_ ==
nullptr) {
543 overlap_find_all_<self_type, true, const_iterator, FunctionT>(
544 this, root_, ival, on_find
547 overlap_find_all_<self_type, false, const_iterator, FunctionT>(
548 this, root_, ival, on_find
556 template <
typename FunctionT>
559 FunctionT
const& on_find
568 template <
typename FunctionT>
571 FunctionT
const& on_find
591 bool exclusive =
false
593 if (root_ ==
nullptr) {
596 return iterator{overlap_find_ex_(from.node_, ival, exclusive),
this};
602 bool exclusive =
false
604 if (root_ ==
nullptr) {
607 return const_iterator {overlap_find_ex_(from.node_, ival, exclusive),
this};
649 if (z->interval_.
low() < x->interval_.
low()) {
660 }
else if (z->interval_.
low() < y->interval_.
low()) {
725 if( iter ==
end() ) {
728 if( iter ==
end() ) {
732 if( iter !=
end() ) {
734 auto merged =
join( iter->interval(), ival, std::move( data ));
749 throw std::out_of_range(
"Cannot erase end iterator");
756 if (!iter.node_->left_ || !iter.node_->right_) {
759 y = successor_(iter.node_);
770 x->parent_ = y->parent_;
773 auto* x_parent = y->parent_;
777 y->parent_->left_ = x;
779 y->parent_->right_ = x;
782 if (y != iter.node_) {
783 iter.node_->interval_ = y->interval_;
784 iter.node_->max_ = y->max_;
785 recalculate_max_(iter.node_);
790 erase_fixup_(x, x_parent, y->
is_left());
824 for (
auto i =
begin(), e =
end(); i != e; ++i) {
825 fresh.insert_overlap(*i);
841 auto min = std::begin(*this)->interval().low();
842 auto max = root_->max_;
843 return punch({min, max});
860 auto i = std::begin(*
this);
861 if (ival.
low() < i->interval().low()) {
862 result.insert({ival.
low(), i->interval().low()});
865 for(
auto e =
end(); i != e; ++i ){
866 auto next = i; ++next;
868 result.insert({i->interval().high(), next->interval().low()});
875 result.insert({i->interval().high(), ival.
high()});
889 clear_( node->left_ );
892 clear_( node->right_ );
904 cpy->color_ =
root->color_;
905 cpy->max_ =
root->max_;
906 cpy->left_ = copy_tree_(
root->left_, cpy);
907 cpy->right_ = copy_tree_(
root->right_, cpy);
915 template <
typename ComparatorFunctionT>
919 if( compare(ptr->interval(), ival)) {
922 return find_ex_(ptr, ival, compare);
927 template <
typename ComparatorFunctionT>
931 if (ptr->left_ && ival.high() <= ptr->left_->max()) {
933 if (!ptr->right_ || ival.low() > ptr->right_->max()) {
934 return find_(ptr->left_, ival, compare);
937 auto* res = find_(ptr->left_, ival, compare);
938 if (res !=
nullptr) {
943 if (ptr->right_ && ival.high() <= ptr->right_->max()) {
944 if (!ptr->left_ || ival.low() > ptr->left_->max()) {
945 return find_(ptr->right_, ival, compare);
948 auto* res = find_(ptr->right_, ival, compare);
949 if (res !=
nullptr) {
956 template <
typename ThisType,
typename IteratorT,
typename FunctionT,
typename ComparatorFunctionT>
957 static bool find_all_(
958 typename std::conditional<std::is_same<IteratorT, iterator>::value, ThisType, ThisType
const>::type*
self,
961 FunctionT
const& on_find,
962 ComparatorFunctionT
const& compare
964 if (compare(ptr->interval(), ival)) {
965 if (!on_find(IteratorT{ptr,
self})) {
969 if (ptr->left_ && ival.high() <= ptr->left_->max()) {
971 if (!ptr->right_ || ival.low() > ptr->right_->max()) {
972 return find_all_<ThisType, IteratorT>(
self, ptr->left_, ival, on_find, compare);
975 if (!find_all_<ThisType, IteratorT>(
self, ptr->left_, ival, on_find, compare)) {
979 if (ptr->right_ && ival.high() <= ptr->right_->max()) {
980 if (!ptr->left_ || ival.low() > ptr->left_->max()) {
981 return find_all_<ThisType, IteratorT>(
self, ptr->right_, ival, on_find, compare);
984 if (!find_all_<ThisType, IteratorT>(
self, ptr->right_, ival, on_find, compare)) {
995 template <
bool Exclusive>
999 if (ptr->interval().overlaps_exclusive(ival)) {
1003 if (ptr->interval().overlaps(ival)){
1007 return overlap_find_ex_<Exclusive>(ptr, ival);
1011 template <
bool Exclusive>
1014 if (ptr->left_ && ptr->left_->max() >= ival.low()) {
1017 if (!ptr->right_ || ival.low() > ptr->right_->max()) {
1018 return overlap_find_<Exclusive>(ptr->left_, ival);
1021 auto* res = overlap_find_<Exclusive>(ptr->left_, ival);
1022 if (res !=
nullptr) {
1027 if (ptr->right_ && ptr->right_->max() >= ival.low()) {
1028 if (!ptr->left_ || ival.low() > ptr->left_->max()) {
1029 return overlap_find_<Exclusive>(ptr->right_, ival);
1032 auto* res = overlap_find_<Exclusive>(ptr->right_, ival);
1033 if (res !=
nullptr) {
1040 template <
typename ThisType,
bool Exclusive,
typename IteratorT,
typename FunctionT>
1041 static bool overlap_find_all_(
1042 typename std::conditional<
1043 std::is_same<IteratorT, iterator>::value, ThisType, ThisType
const
1047 FunctionT
const& on_find
1050 if (ptr->interval().overlaps_exclusive(ival)) {
1051 if (!on_find(IteratorT{ptr,
self})) {
1056 if (ptr->interval().overlaps(ival)) {
1057 if (!on_find(IteratorT{ptr,
self})) {
1062 if (ptr->left_ && ptr->left_->max() >= ival.low()) {
1065 if (!ptr->right_ || ival.low() > ptr->right_->max()) {
1066 return overlap_find_all_<ThisType, Exclusive, IteratorT, FunctionT>(
1067 self, ptr->left_, ival, on_find
1071 if( !overlap_find_all_<ThisType, Exclusive, IteratorT, FunctionT>(
1072 self, ptr->left_, ival, on_find
1078 if (ptr->right_ && ptr->right_->max() >= ival.low()) {
1079 if (!ptr->left_ || ival.low() > ptr->right_->max()) {
1080 return overlap_find_all_<ThisType, Exclusive, IteratorT, FunctionT>(
1081 self, ptr->right_, ival, on_find
1085 if( !overlap_find_all_<ThisType, Exclusive, IteratorT, FunctionT>(
1086 self, ptr->right_, ival, on_find
1102 return minimum_(node->right_);
1104 auto* y = node->parent_;
1105 while (y && node == y->right_) {
1114 auto p = desc->parent_;
1115 for (; p && p != par.node_; p = p->parent_) {}
1116 return p !=
nullptr;
1130 void recalculate_max_(
node_type* reacalculation_root)
1132 auto* p = reacalculation_root;
1133 while (p && p->max_ <= reacalculation_root->max_) {
1134 if (p->left_ && p->left_->max_ > p->max_) {
1135 p->max_ = p->left_->max_;
1137 if (p->right_ && p->right_->max_ > p->max_) {
1138 p->max_ = p->right_->max_;
1166 auto* y = x->right_;
1167 x->right_ = y->left_;
1169 y->left_->parent_ = x;
1172 y->parent_ = x->parent_;
1175 }
else if (x->is_left()) {
1176 x->parent_->left_ = y;
1178 x->parent_->right_ = y;
1185 if (x->left_ && x->right_) {
1186 x->max_ = std::max(x->interval_.high(), std::max(x->left_->max_, x->right_->max_));
1187 }
else if (x->left_) {
1188 x->max_ = std::max(x->interval_.high(), x->left_->max_);
1189 }
else if (x->right_) {
1190 x->max_ = std::max(x->interval_.high(), x->right_->max_);
1192 x->max_ = x->interval_.high();
1196 y->max_ = std::max(y->interval_.high(), std::max(y->right_->max_, x->max_));
1198 y->max_ = std::max(y->interval_.high(), x->max_);
1205 y->left_ = x->right_;
1208 x->right_->parent_ = y;
1211 x->parent_= y->parent_;
1214 }
else if (y->is_left()) {
1215 y->parent_->left_ = x;
1217 y->parent_->right_ = x;
1224 if (y->left_ && y->right_) {
1225 y->max_ = std::max(y->interval_.high(), std::max(y->left_->max_, y->right_->max_));
1226 }
else if (y->left_) {
1227 y->max_ = std::max(y->interval_.high(), y->left_->max_);
1228 }
else if (y->right_) {
1229 y->max_ = std::max(y->interval_.high(), y->right_->max_);
1231 y->max_ = y->interval_.high();
1235 x->max_ = std::max(x->interval_.high(), std::max(x->left_->max_, y->max_));
1237 x->max_ = std::max(x->interval_.high(), y->max_);
1244 if (!z->parent_->parent_) {
1247 if (z->parent_ == z->parent_->parent_->left_) {
1248 node_type* y = z->parent_->parent_->right_;
1253 z = z->parent_->parent_;
1255 if (z == z->parent_->right_) {
1261 right_rotate_(z->parent_->parent_);
1264 node_type* y = z->parent_->parent_->left_;
1269 z = z->parent_->parent_;
1277 left_rotate_(z->parent_->parent_);
1289 w = x_parent->right_;
1293 left_rotate_(x_parent);
1294 w = x_parent->right_;
1303 x_parent = x->parent_;
1304 y_is_left = (x == x_parent->left_);
1310 w = x_parent->right_;
1313 w->color_ = x_parent->color_;
1319 left_rotate_(x_parent);
1324 w = x_parent->left_;
1328 right_rotate_(x_parent);
1329 w = x_parent->left_;
1338 x_parent = x->parent_;
1339 y_is_left = (x == x_parent->left_);
1345 w = x_parent->left_;
1348 w->color_ = x_parent->color_;
1354 right_rotate_(x_parent);
1374 #endif // include guard