47 #if defined(IB_RBT_TESTING)
48 #warning "Testing enabled!"
51 #define ROOT(t) (t->root->left)
52 #define SIZEOF_NODE(t) ((sizeof(ib_rbt_node_t) + t->sizeof_value) - 1)
62 ib_rbt_print_node print)
65 if (node != tree->nil) {
67 rbt_print_subtree(tree, node->left, print);
68 rbt_print_subtree(tree, node->right, print);
91 result = tree->compare_with_arg(
92 tree->cmp_arg, prev->value,
95 result = tree->compare(
96 prev->value, node->value);
116 rbt_count_black_nodes(
123 if (node != tree->nil) {
124 ulint left_height = rbt_count_black_nodes(tree, node->left);
126 ulint right_height = rbt_count_black_nodes(tree, node->right);
130 || left_height != right_height) {
133 }
else if (node->color == IB_RBT_RED) {
136 if (node->left->color != IB_RBT_BLACK
137 || node->right->color != IB_RBT_BLACK) {
141 result = left_height;
144 }
else if (node->color != IB_RBT_BLACK) {
149 result = right_height + 1;
170 node->right = right->left;
172 if (right->left != nil) {
173 right->left->parent = node;
177 right->parent = node->parent;
181 if (node == node->parent->left) {
183 node->parent->left = right;
186 node->parent->right = right;
191 node->parent = right;
206 node->left = left->right;
208 if (left->right != nil) {
209 left->right->parent = node;
213 left->parent = node->parent;
217 if (node == node->parent->right) {
219 node->parent->right = left;
222 node->parent->left = left;
243 if (last == tree->root || parent->result < 0) {
247 ut_a(parent->result != 0);
271 parent.last = tree->root;
274 while (current != tree->nil) {
276 parent.last = current;
279 parent.result = tree->compare_with_arg(
280 tree->cmp_arg, key, current->value);
282 parent.result = tree->compare(key, current->value);
285 if (parent.result < 0) {
286 current = current->left;
288 current = current->right;
292 ut_a(current == tree->nil);
294 rbt_tree_add_child(tree, &parent, node);
312 node->color = IB_RBT_RED;
314 while (node != ROOT(tree) && parent->color == IB_RBT_RED) {
317 if (parent == grand_parent->left) {
320 if (uncle->color == IB_RBT_RED) {
323 uncle->color = IB_RBT_BLACK;
324 parent->color = IB_RBT_BLACK;
325 grand_parent->color = IB_RBT_RED;
332 if (node == parent->right) {
337 rbt_rotate_left(nil, node);
340 grand_parent = node->parent->parent;
343 node->parent->color = IB_RBT_BLACK;
344 grand_parent->color = IB_RBT_RED;
346 rbt_rotate_right(nil, grand_parent);
352 if (uncle->color == IB_RBT_RED) {
355 uncle->color = IB_RBT_BLACK;
356 parent->color = IB_RBT_BLACK;
357 grand_parent->color = IB_RBT_RED;
364 if (node == parent->left) {
369 rbt_rotate_right(nil, node);
372 grand_parent = node->parent->parent;
375 node->parent->color = IB_RBT_BLACK;
376 grand_parent->color = IB_RBT_RED;
378 rbt_rotate_left(nil, grand_parent);
382 parent = node->parent;
386 ROOT(tree)->color = IB_RBT_BLACK;
408 while (next->left != nil) {
418 while (parent != tree->root && next == parent->right) {
420 parent = next->parent;
423 next = (parent == tree->root) ? NULL : parent;
434 rbt_find_predecessor(
448 while (prev->right != nil) {
458 while (parent != tree->root && prev == parent->left) {
460 parent = prev->parent;
463 prev = (parent == tree->root) ? NULL : parent;
480 if (eject->parent->left == eject) {
481 eject->parent->left = node;
482 }
else if (eject->parent->right == eject) {
483 eject->parent->right = node;
490 node->parent = eject->parent;
505 node->left = replace->left;
506 node->right = replace->right;
509 node->left->parent = node;
510 node->right->parent = node;
513 rbt_eject_node(replace, node);
516 node->color = replace->color;
517 replace->color = color;
533 if (node->left != nil && node->right != nil) {
537 ut_a(successor != nil);
538 ut_a(successor->parent != nil);
539 ut_a(successor->left == nil);
541 child = successor->right;
544 rbt_eject_node(successor, child);
547 rbt_replace_node(node, successor);
549 ut_a(node->left == nil || node->right == nil);
551 child = (node->left != nil) ? node->left : node->right;
554 rbt_eject_node(node, child);
558 node->parent = node->right = node->left = tree->nil;
576 ut_a(sibling != nil);
579 if (sibling->color == IB_RBT_RED) {
581 parent->color = IB_RBT_RED;
582 sibling->color = IB_RBT_BLACK;
584 rbt_rotate_left(nil, parent);
586 sibling = parent->right;
588 ut_a(sibling != nil);
592 if (sibling->left->color == IB_RBT_BLACK
593 && sibling->right->color == IB_RBT_BLACK) {
596 sibling->color = IB_RBT_RED;
599 if (sibling->right->color == IB_RBT_BLACK) {
601 ut_a(sibling->left->color == IB_RBT_RED);
603 sibling->color = IB_RBT_RED;
604 sibling->left->color = IB_RBT_BLACK;
606 rbt_rotate_right(nil, sibling);
608 sibling = parent->right;
609 ut_a(sibling != nil);
612 sibling->color = parent->color;
613 sibling->right->color = IB_RBT_BLACK;
615 parent->color = IB_RBT_BLACK;
617 rbt_rotate_left(nil, parent);
636 ut_a(sibling != nil);
639 if (sibling->color == IB_RBT_RED) {
641 parent->color = IB_RBT_RED;
642 sibling->color = IB_RBT_BLACK;
644 rbt_rotate_right(nil, parent);
645 sibling = parent->left;
647 ut_a(sibling != nil);
651 if (sibling->right->color == IB_RBT_BLACK
652 && sibling->left->color == IB_RBT_BLACK) {
655 sibling->color = IB_RBT_RED;
658 if (sibling->left->color == IB_RBT_BLACK) {
660 ut_a(sibling->right->color == IB_RBT_RED);
662 sibling->color = IB_RBT_RED;
663 sibling->right->color = IB_RBT_BLACK;
665 rbt_rotate_left(nil, sibling);
667 sibling = parent->left;
669 ut_a(sibling != nil);
672 sibling->color = parent->color;
673 sibling->left->color = IB_RBT_BLACK;
675 parent->color = IB_RBT_BLACK;
677 rbt_rotate_right(nil, parent);
687 rbt_remove_node_and_rebalance(
696 if (node->color == IB_RBT_BLACK) {
699 ROOT(tree)->color = IB_RBT_RED;
701 while (child && child->color == IB_RBT_BLACK) {
706 if (parent->left == child) {
708 child = rbt_balance_right(
709 tree->nil, parent, parent->right);
711 }
else if (parent->right == child) {
713 child = rbt_balance_left(
714 tree->nil, parent, parent->left);
727 last->color = IB_RBT_BLACK;
728 ROOT(tree)->color = IB_RBT_BLACK;
745 rbt_free_node(node->left, nil);
746 rbt_free_node(node->right, nil);
760 rbt_free_node(tree->root, tree->nil);
783 tree->cmp_arg = cmp_arg;
784 tree->compare_with_arg =
compare;
803 memset(tree, 0,
sizeof(*tree));
805 tree->sizeof_value = sizeof_value;
809 memset(node, 0,
sizeof(*node));
811 node->color = IB_RBT_BLACK;
812 node->parent = node->left = node->right = node;
817 memset(node, 0,
sizeof(*node));
819 node->color = IB_RBT_BLACK;
820 node->parent = node->left = node->right = tree->nil;
844 memcpy(node->value, value, tree->sizeof_value);
845 node->parent = node->left = node->right = tree->nil;
848 rbt_tree_insert(tree, key, node);
849 rbt_balance_tree(tree, node);
873 memcpy(node->value, value, tree->sizeof_value);
874 node->parent = node->left = node->right = tree->nil;
877 if (parent->last == NULL) {
878 parent->last = tree->root;
883 rbt_tree_add_child(tree, parent, node);
884 rbt_balance_tree(tree, node);
888 #if defined(IB_RBT_TESTING)
907 while (current != tree->nil) {
911 result = tree->compare_with_arg(
912 tree->cmp_arg, key, current->value);
914 result = tree->compare(key, current->value);
918 current = current->left;
919 }
else if (result > 0) {
920 current = current->right;
926 return(current != tree->nil ? current : NULL);
939 ibool deleted = FALSE;
943 rbt_remove_node_and_rebalance(tree, node);
967 rbt_remove_node_and_rebalance(tree, (
ib_rbt_node_t*) const_node);
989 while (current != tree->nil) {
993 result = tree->compare_with_arg(
994 tree->cmp_arg, key, current->value);
996 result = tree->compare(key, current->value);
1001 current = current->right;
1003 }
else if (result < 0) {
1006 current = current->left;
1030 while (current != tree->nil) {
1033 if (tree->cmp_arg) {
1034 result = tree->compare_with_arg(
1035 tree->cmp_arg, key, current->value);
1037 result = tree->compare(key, current->value);
1043 current = current->right;
1045 }
else if (result < 0) {
1047 current = current->left;
1073 parent->last = NULL;
1075 while (current != tree->nil) {
1077 parent->last = current;
1079 if (tree->cmp_arg) {
1080 parent->result = tree->compare_with_arg(
1081 tree->cmp_arg, key, current->value);
1083 parent->result = tree->compare(key, current->value);
1086 if (parent->result > 0) {
1087 current = current->right;
1088 }
else if (parent->result < 0) {
1089 current = current->left;
1095 return(parent->result);
1118 parent->last = NULL;
1120 while (current != tree->nil) {
1122 parent->last = current;
1125 ut_ad(tree->cmp_arg);
1126 parent->result = arg_compare(
1127 tree->cmp_arg, key, current->value);
1129 parent->result =
compare(key, current->value);
1132 if (parent->result > 0) {
1133 current = current->right;
1134 }
else if (parent->result < 0) {
1135 current = current->left;
1141 return(parent->result);
1156 while (current != tree->nil) {
1158 current = current->left;
1176 while (current != tree->nil) {
1178 current = current->right;
1194 return(current ? rbt_find_successor(tree, current) : NULL);
1207 return(current ? rbt_find_predecessor(tree, current) : NULL);
1218 rbt_free_node(ROOT(tree), tree->nil);
1221 tree->root->left = tree->root->right = tree->nil;
1238 if (rbt_empty(src) || dst == src) {
1242 for (; src_node; src_node =
rbt_next(src, src_node)) {
1244 if (
rbt_search(dst, &parent, src_node->value) != 0) {
1267 ulint old_size = rbt_size(dst);
1269 if (rbt_empty(src) || dst == src) {
1279 if (
rbt_search(dst, &parent, prev->value) != 0) {
1283 rbt_remove_node_and_rebalance(src, prev);
1286 prev->parent = prev->left = prev->right = dst->nil;
1287 rbt_tree_add_child(dst, &parent, prev);
1288 rbt_balance_tree(dst, prev);
1294 #if defined(IB_RBT_TESTING)
1298 return(rbt_size(dst) - old_size);
1311 if (rbt_count_black_nodes(tree, ROOT(tree)) > 0) {
1312 return(rbt_check_ordering(tree));
1325 ib_rbt_print_node print)
1327 rbt_print_subtree(tree, ROOT(tree), print);