36 #ifndef ORBTREE_BASE_H 37 #define ORBTREE_BASE_H 38 #include "orbtree_node.h" 62 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
66 typedef typename NodeAllocator::Node
Node;
67 typedef typename NodeAllocator::KeyValue KeyValue;
68 typedef typename NodeAllocator::KeyValue::KeyType KeyType;
69 typedef typename NodeAllocator::KeyValue::ValueType ValueType;
72 using NodeAllocator::Invalid;
76 typedef typename NodeAllocator::NVType
NVType;
80 void NVAdd(NVType* x,
const NVType* y)
const;
82 void NVSubtract(NVType* x,
const NVType* y)
const;
89 void create_sentinels() {
90 Node& rootn = get_node(root());
91 rootn.set_parent(nil());
92 rootn.set_left(nil());
93 rootn.set_right(nil());
95 Node& niln = get_node(nil());
96 niln.set_parent(nil());
98 niln.set_right(nil());
104 Node&
get_node(NodeHandle n) {
return NodeAllocator::get_node(n); }
106 const Node&
get_node(NodeHandle n)
const {
return NodeAllocator::get_node(n); }
108 NodeHandle
root()
const {
return NodeAllocator::root; }
110 NodeHandle
nil()
const {
return NodeAllocator::nil; }
143 std::pair<NodeHandle,bool> insert(ValueType&& kv);
145 std::pair<NodeHandle,bool> insert(
const ValueType& kv);
164 NodeHandle insert(NodeHandle hint, ValueType&& kv);
166 NodeHandle insert(NodeHandle hint,
const ValueType& kv);
171 template<
class... T> std::pair<NodeHandle,bool> emplace(T&&... t);
176 template<
class... T> NodeHandle emplace_hint(NodeHandle hint, T&&... t);
186 bool insert_search(
const KeyType& k, NodeHandle& n,
bool& insert_left)
const;
191 bool insert_search_hint(NodeHandle hint,
const KeyType& k, NodeHandle& n,
bool& insert_left)
const;
200 void insert_helper(NodeHandle n, NodeHandle n1,
bool insert_left);
207 template<
class K>
auto find(
const K& key)
const -> NodeHandle;
209 template<
class K>
auto lower_bound(
const K& key)
const -> NodeHandle;
211 template<
class K>
auto upper_bound(
const K& key)
const -> NodeHandle;
214 const KeyType&
get_node_key(NodeHandle n)
const {
return get_node(n).get_key_value().key(); }
218 return (!c(get_node_key(n),k)) && (!c(k,get_node_key(n)));
227 void get_node_grvalue(NodeHandle n, NVType* res)
const { f(get_node(n).get_key_value().keyvalue(), res); }
230 NodeHandle first()
const;
232 NodeHandle last()
const;
234 NodeHandle next(NodeHandle n)
const;
236 NodeHandle previous(NodeHandle n)
const;
239 NodeHandle erase(NodeHandle n);
255 if(n == get_parent(n).get_left())
return get_parent(n).get_right();
256 else return get_parent(n).get_left();
259 Node&
get_sibling(NodeHandle n) {
return get_node(get_sibling_handle(n)); }
261 const Node&
get_sibling(NodeHandle n)
const {
return get_node(get_sibling_handle(n)); }
263 bool is_left_side(NodeHandle n)
const {
return (get_parent(n).get_left() == n); }
266 void update_sum(NodeHandle n);
268 void update_sum_r(NodeHandle n) {
for(;n != root();n = get_node(n).get_parent()) update_sum(n); }
272 template<
class KeyValue_ = KeyValue>
273 void update_value(NodeHandle n,
typename KeyValue_::MappedType
const& v) {
274 get_node(n).get_key_value().value() = v;
279 template<
class KeyValue_ = KeyValue>
281 get_node(n).get_key_value().value() = std::move(v);
290 void rotate_left(NodeHandle x);
295 void rotate_right(NodeHandle x);
298 void rotate_parent(NodeHandle x);
303 NodeAllocator::clear_tree();
308 template<
class K>
void get_sum_fv(
const K& k, NVType* res)
const;
310 void get_sum_fv_node(NodeHandle x, NVType* res)
const;
312 void get_norm_fv(NVType* res)
const;
320 void check_tree(
double epsilon = -1.0)
const;
323 void check_tree_r(
double epsilon, NodeHandle x,
size_t black_count,
size_t& previous_black_count)
const;
327 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
template<
class K>
329 if(root() == Invalid)
return nil();
331 if(n == Invalid || n == nil())
return nil();
333 const KeyType& k1 = get_node_key(n);
336 n = get_node(n).get_left();
339 if(c(k1,key)) n = get_node(n).get_right();
342 if(n == nil())
return n;
346 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
template<
class K>
348 if(root() == Invalid)
return nil();
350 if(n == Invalid || n == nil())
return nil();
353 const KeyType& k1 = get_node_key(n);
356 n = get_node(n).get_right();
360 n = get_node(n).get_left();
362 if(n == nil())
return last;
366 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
template<
class K>
368 if(root() == Invalid)
return nil();
370 if(n == Invalid || n == nil())
return nil();
373 const KeyType& k1 = get_node_key(n);
377 n = get_node(n).left;
381 n = get_node(n).right;
383 if(n == nil())
return last;
387 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
template<
class K>
389 for(
unsigned int i=0; i < f.get_nr(); i++) res[i] =
NVType();
391 if(root() == Invalid)
return;
394 if(n == Invalid || n == nil())
return;
396 const KeyType& k1 = get_node_key(n);
401 this->get_node_sum(l,tmp);
404 get_node_grvalue(n,tmp);
407 n = get_node(n).get_right();
408 if(n == nil())
break;
412 n = get_node(n).get_left();
413 if(n == nil())
break;
418 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
420 for(
unsigned int i=0; i < f.get_nr(); i++) res[i] =
NVType();
422 if(x == this->Invalid || x == nil() || x == root())
return;
429 this->get_node_sum(l,tmp);
436 if(x == get_node(p).get_right()) {
437 l = get_node(p).get_left();
439 this->get_node_sum(l,tmp);
442 get_node_grvalue(p,tmp);
446 p = get_node(x).get_parent();
451 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
453 if(root() != Invalid) {
455 if(n != Invalid && n != nil()) {
456 this->get_node_sum(n,res);
460 for(
unsigned int i=0; i < f.get_nr(); i++) res[i] =
NVType();
465 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
467 if(root() == Invalid)
return nil();
469 if(n == Invalid || n == nil())
return nil();
471 while(get_node(n).get_left() != nil()) n = get_node(n).get_left();
474 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
476 if(root() == Invalid)
return nil();
478 if(n == Invalid || n == nil())
return nil();
480 while(get_node(n).get_right() != nil()) n = get_node(n).get_right();
483 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
485 if(n == nil())
return n;
487 if(get_node(n).get_right() != nil()) {
488 n = get_node(n).get_right();
490 while(get_node(n).get_left() != nil()) n = get_node(n).get_left();
496 if(p == root())
return nil();
497 if(get_node(p).get_left() == n)
return p;
501 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
503 if(n == nil())
return last();
505 if(get_node(n).get_left() != nil()) {
506 n = get_node(n).get_left();
508 while(get_node(n).get_right() != nil()) n = get_node(n).get_right();
514 if(p == root())
return nil();
515 if(get_node(p).get_right() == n)
return p;
524 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
529 get_node_grvalue(n,sum);
530 if(get_node(n).get_left() != nil()) {
531 this->get_node_sum(get_node(n).get_left(),tmp);
534 if(get_node(n).get_right() != nil()) {
535 this->get_node_sum(get_node(n).get_right(),tmp);
538 this->set_node_sum(n,sum);
546 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
549 get_node(x).set_right( get_node(y).get_left() );
550 if(get_node(x).get_right() != nil()) get_right(x).set_parent(x);
551 get_node(y).set_parent( get_node(x).get_parent() );
553 if( x == get_parent(x).get_right() ) get_parent(x).set_right(y);
554 else get_parent(x).set_left(y);
555 get_node(y).set_left(x);
556 get_node(x).set_parent(y);
565 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
568 get_node(x).set_left( get_node(y).get_right() );
569 if(get_node(x).get_left() != nil()) get_left(x).set_parent(x);
570 get_node(y).set_parent( get_node(x).get_parent() );
572 if( x == get_parent(x).get_right() ) get_parent(x).set_right(y);
573 else get_parent(x).set_left(y);
574 get_node(y).set_right(x);
575 get_node(x).set_parent(y);
583 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
585 if(n == get_parent(n).get_left()) rotate_right(get_node(n).get_parent());
586 else rotate_left(get_node(n).get_parent());
593 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
596 if(n == Invalid)
throw std::runtime_error(
"orbtree_base::insert_search(): root is Invalid!\n");
597 if(get_node(n).get_right() == nil()) {
602 n = get_node(n).get_right();
604 const KeyType& k1 = get_node_key(n);
607 if(get_node(n).get_left() == nil()) { insert_left =
true;
return true; }
608 n = get_node(n).get_left();
613 if(!multi)
if(!c(k1,k))
return false;
614 if(get_node(n).get_right() == nil()) { insert_left =
false;
return true; }
615 n = get_node(n).get_right();
625 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
627 if(insert_left) get_node(n).set_left(n1);
628 else get_node(n).set_right(n1);
629 get_node(n1).set_parent(n);
630 get_node(n1).set_left(nil());
631 get_node(n1).set_right(nil());
632 get_node(n1).set_red();
633 NVType sum_add[f.get_nr()];
634 get_node_grvalue(n1,sum_add);
635 this->set_node_sum(n1,sum_add);
637 for(
NodeHandle n2 = n; n2 != root(); n2 = get_node(n2).get_parent()) {
639 this->get_node_sum(n2,tmp);
641 this->set_node_sum(n2,tmp);
645 if(n == root())
return;
649 if(get_node(n).is_black())
return;
654 if(get_node(n).get_parent() == root()) { get_node(n).set_black();
return; }
657 if(get_sibling(n).is_red()) {
660 get_sibling(n).set_black();
661 get_node(n).set_black();
662 get_parent(n).set_red();
664 n1 = get_node(n).get_parent();
665 n = get_node(n1).get_parent();
670 if(is_left_side(n1) != is_left_side(n)) {
678 get_node(n).set_black();
679 get_parent(n).set_red();
686 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
691 if(!insert_search(
KeyValue::key(kv),n,insert_left))
return std::pair<NodeHandle,bool>(n,
false);
694 NodeHandle n1 = this->new_node(std::move(kv));
695 insert_helper(n,n1,insert_left);
697 return std::pair<NodeHandle,bool>(n1,
true);
700 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
704 if(!insert_search(
KeyValue::key(kv),n,insert_left))
return std::pair<NodeHandle,bool>(n,
false);
708 insert_helper(n,n1,insert_left);
710 return std::pair<NodeHandle,bool>(n1,
true);
713 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
715 if(c(k,get_node_key(hint))) {
719 if(!c(k,get_node_key(p))) {
721 if(!multi)
if(!c(get_node_key(p),k))
return p;
724 if(get_node(hint).get_left() == nil()) { n = hint; insert_left =
true;
return true; }
726 if(get_node(p).get_right() == nil()) { n = p; insert_left =
false;
return true; }
727 else throw std::runtime_error(
"orbtree_base::insert(): inconsistent tree detected!\n");
733 return insert_search(k,n,insert_left).first;
736 if(!c(get_node_key(hint),k)) {
737 if(!multi) { n = hint;
return false; }
738 if(get_node(hint).get_left() == nil()) { n = hint; insert_left =
true;
return true; }
741 if(get_node(p).get_right() != nil()) std::runtime_error(
"orbtree_base::insert(): inconsistent tree detected!\n");
750 if(get_node(n).get_left() == nil()) { insert_left =
true;
return true; }
753 if(get_node(p).get_right() != nil()) std::runtime_error(
"orbtree_base::insert(): inconsistent tree detected!\n");
766 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
771 if(!insert_search_hint(hint,
KeyValue::key(kv),n,insert_left))
return n;
774 insert_helper(n,n1,insert_left);
780 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
785 if(!insert_search_hint(hint,
KeyValue::key(kv),n,insert_left))
return n;
787 NodeHandle n1 = this->new_node(std::move(kv));
788 insert_helper(n,n1,insert_left);
794 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
template<
class... T>
800 if(!insert_search(get_node_key(n1),n,insert_left)) {
802 return std::pair<NodeHandle,bool>(n,
false);
804 insert_helper(n,n1,insert_left);
806 return std::pair<NodeHandle,bool>(n1,
true);
809 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
template<
class... T>
815 if(!insert_search_hint(hint,get_node_key(n1),n,insert_left)) {
821 insert_helper(n,n1,insert_left);
827 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
835 if(get_node(n).get_left() != nil() && get_node(n).get_right() != nil()) del = x;
839 if(c == nil()) c = get_node(del).get_right();
841 get_node(c).set_parent( p );
842 if(get_node(p).get_left() == del) get_node(p).set_left(c);
843 else get_node(p).set_right(c);
847 get_node_grvalue(del,x2);
848 for(
NodeHandle p2 = p; p2 != root(); p2 = get_node(p2).get_parent()) {
850 this->get_node_sum(p2,y);
852 this->set_node_sum(p2,y);
861 if(get_node(del).is_black()) {
863 get_node(c).set_black();
869 if(s == nil() || s == c) s = get_node(p).get_right();
870 if(s == nil() || s == c)
throw std::runtime_error(
"orbtree_base::erase(): found black node with no sibling!\n");
872 if(get_node(s).is_red()) {
875 get_node(p).set_red();
876 get_node(s).set_black();
881 if(get_left(s).is_black() && get_right(s).is_black()) {
884 get_node(s).set_red();
886 if(get_node(p).is_red()) {
887 get_node(p).set_black();
892 p = get_node(p).get_parent();
893 if(p == root())
break;
899 if(s == get_node(p).get_right() && get_right(s).is_black()) {
901 get_node(s).set_red();
902 get_left(s).set_black();
907 if(s == get_node(p).get_left() && get_left(s).is_black()) {
909 get_node(s).set_red();
910 get_right(s).set_black();
917 if(get_node(p).is_red()) get_node(s).set_red();
918 get_node(p).set_black();
919 if(s == get_node(p).get_right()) get_right(s).set_black();
920 else get_left(s).set_black();
932 get_node(x).set_left( get_node(n).get_left() );
933 get_node(x).set_right( get_node(n).get_right() );
934 get_node(x).set_parent( get_node(n).get_parent() );
935 if(get_node(n).is_black()) get_node(x).set_black();
936 else get_node(x).set_red();
937 if(get_parent(n).get_left() == n) get_parent(n).set_left(x);
939 if(get_parent(n).get_right() == n) get_parent(n).set_right(x);
940 else throw std::runtime_error(
"orbtree_base::erase(): inconsistent tree detected!\n");
942 if(get_node(x).get_left() != nil()) get_left(x).set_parent(x);
943 if(get_node(x).get_right() != nil()) get_right(x).set_parent(x);
950 if(!size1)
throw std::runtime_error(
"size1 is zero in orbtree_base::erase!\n");
955 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
957 unsigned int nr = f.get_nr();
959 if(std::is_integral<NVType>::value) {
961 NVType max = std::numeric_limits<NVType>::max();
962 NVType min = std::numeric_limits<NVType>::min();
963 for(
unsigned int i = 0;i<nr;i++) {
965 if(max - y[i] < x[i])
throw std::runtime_error(
"orbtree_base::NVAdd(): overflow!\n");
968 if(min - y[i] > x[i])
throw std::runtime_error(
"orbtree_base::NVAdd(): underflow!\n");
975 for(
unsigned int i=0;i<nr;i++) x[i] += y[i];
979 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
981 unsigned int nr = f.get_nr();
983 if(std::is_integral<NVType>::value) {
985 NVType max = std::numeric_limits<NVType>::max();
986 NVType min = std::numeric_limits<NVType>::min();
987 for(
unsigned int i = 0;i<nr;i++) {
989 if(min + y[i] > x[i])
throw std::runtime_error(
"orbtree_base::NVSubtract(): underflow!\n");
992 if(max + y[i] < x[i])
throw std::runtime_error(
"orbtree_base::NVSubtract(): overflow!\n");
999 for(
unsigned int i=0;i<nr;i++) x[i] -= y[i];
1003 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
1006 const Node& r = get_node(root());
1007 if(r.get_left() != nil() || r.get_parent() != nil())
throw std::runtime_error(
"orbtree_base::check_tree(): root is invalid!\n");
1009 if(x == nil())
return;
1010 if(x == this->Invalid)
throw std::runtime_error(
"orbtree_base::check_tree(): invalid node handle found!\n");
1011 if(get_node(x).get_parent() != root())
throw std::runtime_error(
"orbtree_base::check_tree(): inconsistent root node!\n");
1013 size_t previous_black_count = (size_t)-1;
1014 check_tree_r(epsilon,x,0,previous_black_count);
1028 template<
class NodeAllocator,
class Compare,
class NVFunc,
bool multi>
1037 if(epsilon >= 0.0) get_node_grvalue(x,sum);
1041 if(get_node(l).get_parent() != x)
throw std::runtime_error(
"orbtree_base::check_tree(): inconsistent node!\n");
1043 if(get_node(x).is_red() && get_node(l).is_red())
throw std::runtime_error(
"orbtree_base::check_tree(): inconsistent node (red parent with red child)!\n");
1045 if( ! c(get_node_key(l),get_node_key(x)) ) {
1046 if( !multi || c(get_node_key(x),get_node_key(l)) )
throw std::runtime_error(
"orbtree_base::check_tree(): inconsistent ordering!\n");
1049 if(epsilon >= 0.0) {
1050 this->get_node_sum(l,tmp);
1057 if(get_node(r).get_parent() != x)
throw std::runtime_error(
"orbtree_base::check_tree(): inconsistent node!\n");
1059 if(get_node(x).is_red() && get_node(r).is_red())
throw std::runtime_error(
"orbtree_base::check_tree(): inconsistent node (red parent with red child)!\n");
1061 if( c(get_node_key(r),get_node_key(x)) )
throw std::runtime_error(
"orbtree_base::check_tree(): inconsistent ordering!\n");
1062 if( !multi && ! c(get_node_key(x),get_node_key(r)) )
throw std::runtime_error(
"orbtree_base::check_tree(): non-unique key found!\n");
1065 if(epsilon >= 0.0) {
1066 this->get_node_sum(r,tmp);
1071 if(epsilon >= 0.0) {
1073 this->get_node_sum(x,tmp);
1076 if(std::is_integral<NVType>::value) {
for(
unsigned int i=0;i<f.get_nr();i++)
if(tmp[i] != sum[i])
1077 throw std::runtime_error(
"orbtree_base::check_tree(): partial sums are inconsistent!\n"); }
1078 else for(
unsigned int i=0;i<f.get_nr();i++)
if(fabs(tmp[i]-sum[i]) > epsilon)
1079 throw std::runtime_error(
"orbtree_base::check_tree(): partial sums are inconsistent!\n");
1084 if(get_node(x).is_black()) black_count++;
1085 if(r == nil() || l == nil()) {
1087 if(previous_black_count == (
size_t)-1) previous_black_count = black_count;
1088 else if(previous_black_count != black_count)
throw std::runtime_error(
"orbtree_base::check_tree(): inconsistent node (black conut differs)!\n");
1092 if(l != nil()) check_tree_r(epsilon,l,black_count,previous_black_count);
1093 if(r != nil()) check_tree_r(epsilon,r,black_count,previous_black_count);
auto upper_bound(const K &key) const -> NodeHandle
find the first node larger than the given key – returns nil if none found
Definition: orbtree_base.h:367
NodeHandle nil() const
handle of nil sentinel
Definition: orbtree_base.h:110
auto lower_bound(const K &key) const -> NodeHandle
find the first node not less than the given key – returns nil if none found
Definition: orbtree_base.h:347
void update_value(NodeHandle n, typename KeyValue_::MappedType const &v)
update value in a node – only if this is a map; update sum recursively based on it as well ...
Definition: orbtree_base.h:273
Node & get_right(NodeHandle n)
convenience helper to get node object that is the right child of the given node handle ...
Definition: orbtree_base.h:246
Definition: orbtree_base.h:42
const KeyType & get_node_key(NodeHandle n) const
convenience function to get the key of a node
Definition: orbtree_base.h:214
Node & get_parent(NodeHandle n)
convenience helper to get node object that is the parent of the given node handle ...
Definition: orbtree_base.h:250
void rotate_right(NodeHandle x)
right rotate
Definition: orbtree_base.h:566
const Node & get_right(NodeHandle n) const
convenience helper to get node object that is the right child of the given node handle ...
Definition: orbtree_base.h:248
NodeHandle emplace_hint(NodeHandle hint, T &&... t)
Construct new element in place with hint.
void rotate_left(NodeHandle x)
left rotate
Definition: orbtree_base.h:547
void clear()
erase all nodes
Definition: orbtree_base.h:302
std::pair< NodeHandle, bool > emplace(T &&... t)
Construct new element in place.
NodeAllocator::Node Node
node objects
Definition: orbtree_base.h:66
void get_sum_fv_node(NodeHandle x, NVType *res) const
get the generalized rank for a given node, i.e. the sum of NVFunv for all nodes before it in order ...
Definition: orbtree_base.h:419
NodeHandle previous(NodeHandle n) const
get node before n (or nil) – note: previous(nil) == last() to make it easier to implement end() iter...
Definition: orbtree_base.h:502
const Node & get_parent(NodeHandle n) const
convenience helper to get node object that is the parent of the given node handle ...
Definition: orbtree_base.h:252
void check_tree(double epsilon=-1.0) const
check that the tree is valid
Definition: orbtree_base.h:1004
auto find(const K &key) const -> NodeHandle
find any node with the given key
Definition: orbtree_base.h:328
NodeHandle last() const
get last node (or nil)
Definition: orbtree_base.h:475
void update_sum(NodeHandle n)
update the sum only inside n
Definition: orbtree_base.h:525
bool compare_key_equals(NodeHandle n, const KeyType &k) const
helper for erase to compare elements
Definition: orbtree_base.h:217
void rotate_parent(NodeHandle x)
rotate by parent of x (x takes parent's place), this calls either rotate_left() or rotate_right() wit...
Definition: orbtree_base.h:584
void get_node_grvalue(NodeHandle n, NVType *res) const
get the value of NVFunc for the given node
Definition: orbtree_base.h:227
void update_value(NodeHandle n, typename KeyValue_::MappedType &&v)
update value in a node – only if this is a map; update sum recursively based on it as well ...
Definition: orbtree_base.h:280
size_t size1
keep track of the number of inserted elements
Definition: orbtree_base.h:85
const Node & get_sibling(NodeHandle n) const
convenience helper to get the node object of a node's sibling (i.e. parent's other child) ...
Definition: orbtree_base.h:261
const Key & key() const
access key – only const access is possible, key should not change
Definition: orbtree_node.h:123
void update_sum_r(NodeHandle n)
update the sum recursively up the tree
Definition: orbtree_base.h:268
void get_sum_fv(const K &k, NVType *res) const
get the generalized rank for a key, i.e. the sum of NVFunc for all nodes with node.key < k
Definition: orbtree_base.h:388
NodeHandle erase(NodeHandle n)
remove the given node – return the next node (i.e. next(n) before deleting n)
Definition: orbtree_base.h:828
std::pair< NodeHandle, bool > insert(ValueType &&kv)
Insert new element.
Definition: orbtree_base.h:687
void NVSubtract(NVType *x, const NVType *y) const
function to subtract NVType values; checks for overflow and throws exception in the case of integral ...
Definition: orbtree_base.h:980
base class for both map and set – should not be used directly
Definition: orbtree_base.h:63
bool is_left_side(NodeHandle n) const
check which side child is n (i.e. returns true if n is the left child of its parent) – requires that...
Definition: orbtree_base.h:263
NodeHandle next(NodeHandle n) const
get node after n (or nil) – note: next(nil) == nil
Definition: orbtree_base.h:484
NodeHandle get_sibling_handle(NodeHandle n) const
convenience helper to get the handle of a node's sibling (i.e. parent's other child) ...
Definition: orbtree_base.h:254
bool insert_search(const KeyType &k, NodeHandle &n, bool &insert_left) const
helper for insert – find the location where to insert
Definition: orbtree_base.h:594
const Node & get_left(NodeHandle n) const
convenience helper to get node object that is the left child of the given node handle ...
Definition: orbtree_base.h:244
void insert_helper(NodeHandle n, NodeHandle n1, bool insert_left)
helper function to do the real work for insert
Definition: orbtree_base.h:626
NodeHandle first() const
get first node (or nil)
Definition: orbtree_base.h:466
void check_tree_r(double epsilon, NodeHandle x, size_t black_count, size_t &previous_black_count) const
recursive helper for check_tree(double)
Definition: orbtree_base.h:1029
Node & get_sibling(NodeHandle n)
convenience helper to get the node object of a node's sibling (i.e. parent's other child) ...
Definition: orbtree_base.h:259
NodeAllocator::NVType NVType
Type the function NVFunc returns.
Definition: orbtree_base.h:76
void NVAdd(NVType *x, const NVType *y) const
function to add NVType values; checks for overflow and throws exception in the case of integral types...
Definition: orbtree_base.h:956
Node & get_node(NodeHandle n)
convenience function that returns node object for a node handle
Definition: orbtree_base.h:104
const Node & get_node(NodeHandle n) const
convenience function that returns node object for a node handle
Definition: orbtree_base.h:106
void get_norm_fv(NVType *res) const
get the normalization factor, i.e. the sum of all keys
Definition: orbtree_base.h:452
NodeHandle root() const
handle of root sentinel
Definition: orbtree_base.h:108
NodeAllocator::NodeHandle NodeHandle
handle to refer nodes to (pointer or integer)
Definition: orbtree_base.h:71
bool insert_search_hint(NodeHandle hint, const KeyType &k, NodeHandle &n, bool &insert_left) const
helper for insert – find the location where to insert
Definition: orbtree_base.h:714
Node & get_left(NodeHandle n)
convenience helper to get node object that is the left child of the given node handle ...
Definition: orbtree_base.h:242