1 /*****************************************************************************
3 Copyright (c) 2006, 2009, Innobase Oy. All Rights Reserved.
5 This program is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free Software
7 Foundation; version 2 of the License.
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License along with
14 this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 *****************************************************************************/
19 /*******************************************************************//**
21 Red-Black tree implementation
23 Created 2007-03-20 Sunny Bains
24 ***********************************************************************/
28 /************************************************************************
29 Definition of a red-black tree
30 ==============================
32 A red-black tree is a binary search tree which has the following
35 1. Every node is either red or black.
36 2. Every leaf (NULL - in our case tree->nil) is black.
37 3. If a node is red, then both its children are black.
38 4. Every simple path from a node to a descendant leaf contains the
39 same number of black nodes.
41 from (3) above, the implication is that on any path from the root
42 to a leaf, red nodes must not be adjacent.
44 However, any number of black nodes may appear in a sequence. */
46 #if defined(IB_RBT_TESTING)
47 #warning "Testing enabled!"
50 #define ROOT(t) (t->root->left)
51 #define SIZEOF_NODE(t) ((sizeof(ib_rbt_node_t) + t->sizeof_value) - 1)
53 /****************************************************************//**
54 Print out the sub-tree recursively. */
59 const ib_rbt_t
* tree
, /*!< in: tree to traverse */
60 const ib_rbt_node_t
* node
, /*!< in: node to print */
61 ib_rbt_print_node print
) /*!< in: print key function */
63 /* FIXME: Doesn't do anything yet */
64 if (node
!= tree
->nil
) {
66 rbt_print_subtree(tree
, node
->left
, print
);
67 rbt_print_subtree(tree
, node
->right
, print
);
71 /****************************************************************//**
72 Verify that the keys are in order.
73 @return TRUE of OK. FALSE if not ordered */
78 const ib_rbt_t
* tree
) /*!< in: tree to verfify */
80 const ib_rbt_node_t
* node
;
81 const ib_rbt_node_t
* prev
= NULL
;
83 /* Iterate over all the nodes, comparing each node with the prev */
84 for (node
= rbt_first(tree
); node
; node
= rbt_next(tree
, prev
)) {
86 if (prev
&& tree
->compare(prev
->value
, node
->value
) >= 0) {
96 /****************************************************************//**
97 Check that every path from the root to the leaves has the same count.
98 Count is expressed in the number of black nodes.
99 @return 0 on failure else black height of the subtree */
102 rbt_count_black_nodes(
103 /*==================*/
104 const ib_rbt_t
* tree
, /*!< in: tree to verify */
105 const ib_rbt_node_t
* node
) /*!< in: start of sub-tree */
109 if (node
!= tree
->nil
) {
110 ulint left_height
= rbt_count_black_nodes(tree
, node
->left
);
112 ulint right_height
= rbt_count_black_nodes(tree
, node
->right
);
116 || left_height
!= right_height
) {
119 } else if (node
->color
== IB_RBT_RED
) {
122 if (node
->left
->color
!= IB_RBT_BLACK
123 || node
->right
->color
!= IB_RBT_BLACK
) {
127 result
= left_height
;
129 /* Check if it's anything other than RED or BLACK. */
130 } else if (node
->color
!= IB_RBT_BLACK
) {
135 result
= right_height
+ 1;
144 /****************************************************************//**
145 Turn the node's right child's left sub-tree into node's right sub-tree.
146 This will also make node's right child it's parent. */
151 const ib_rbt_node_t
* nil
, /*!< in: nil node of the tree */
152 ib_rbt_node_t
* node
) /*!< in: node to rotate */
154 ib_rbt_node_t
* right
= node
->right
;
156 node
->right
= right
->left
;
158 if (right
->left
!= nil
) {
159 right
->left
->parent
= node
;
162 /* Right's new parent was node's parent. */
163 right
->parent
= node
->parent
;
165 /* Since root's parent is tree->nil and root->parent->left points
166 back to root, we can avoid the check. */
167 if (node
== node
->parent
->left
) {
168 /* Node was on the left of its parent. */
169 node
->parent
->left
= right
;
171 /* Node must have been on the right. */
172 node
->parent
->right
= right
;
175 /* Finally, put node on right's left. */
177 node
->parent
= right
;
180 /****************************************************************//**
181 Turn the node's left child's right sub-tree into node's left sub-tree.
182 This also make node's left child it's parent. */
187 const ib_rbt_node_t
* nil
, /*!< in: nil node of tree */
188 ib_rbt_node_t
* node
) /*!< in: node to rotate */
190 ib_rbt_node_t
* left
= node
->left
;
192 node
->left
= left
->right
;
194 if (left
->right
!= nil
) {
195 left
->right
->parent
= node
;
198 /* Left's new parent was node's parent. */
199 left
->parent
= node
->parent
;
201 /* Since root's parent is tree->nil and root->parent->left points
202 back to root, we can avoid the check. */
203 if (node
== node
->parent
->right
) {
204 /* Node was on the left of its parent. */
205 node
->parent
->right
= left
;
207 /* Node must have been on the left. */
208 node
->parent
->left
= left
;
211 /* Finally, put node on left's right. */
216 /****************************************************************//**
217 Append a node to the tree.
218 @return inserted node */
223 const ib_rbt_t
* tree
, /*!< in: rbt tree */
224 ib_rbt_bound_t
* parent
, /*!< in: node's parent */
225 ib_rbt_node_t
* node
) /*!< in: node to add */
227 /* Cast away the const. */
228 ib_rbt_node_t
* last
= (ib_rbt_node_t
*) parent
->last
;
230 if (last
== tree
->root
|| parent
->result
< 0) {
233 /* FIXME: We don't handle duplicates (yet)! */
234 ut_a(parent
->result
!= 0);
244 /****************************************************************//**
245 Generic binary tree insert
246 @return inserted node */
251 ib_rbt_t
* tree
, /*!< in: rb tree */
252 const void* key
, /*!< in: key for ordering */
253 ib_rbt_node_t
* node
) /*!< in: node hold the insert value */
255 ib_rbt_bound_t parent
;
256 ib_rbt_node_t
* current
= ROOT(tree
);
259 parent
.last
= tree
->root
;
261 /* Regular binary search. */
262 while (current
!= tree
->nil
) {
264 parent
.last
= current
;
265 parent
.result
= tree
->compare(key
, current
->value
);
267 if (parent
.result
< 0) {
268 current
= current
->left
;
270 current
= current
->right
;
274 ut_a(current
== tree
->nil
);
276 rbt_tree_add_child(tree
, &parent
, node
);
281 /****************************************************************//**
282 Balance a tree after inserting a node. */
287 const ib_rbt_t
* tree
, /*!< in: tree to balance */
288 ib_rbt_node_t
* node
) /*!< in: node that was inserted */
290 const ib_rbt_node_t
* nil
= tree
->nil
;
291 ib_rbt_node_t
* parent
= node
->parent
;
293 /* Restore the red-black property. */
294 node
->color
= IB_RBT_RED
;
296 while (node
!= ROOT(tree
) && parent
->color
== IB_RBT_RED
) {
297 ib_rbt_node_t
* grand_parent
= parent
->parent
;
299 if (parent
== grand_parent
->left
) {
300 ib_rbt_node_t
* uncle
= grand_parent
->right
;
302 if (uncle
->color
== IB_RBT_RED
) {
304 /* Case 1 - change the colors. */
305 uncle
->color
= IB_RBT_BLACK
;
306 parent
->color
= IB_RBT_BLACK
;
307 grand_parent
->color
= IB_RBT_RED
;
309 /* Move node up the tree. */
314 if (node
== parent
->right
) {
315 /* Right is a black node and node is
316 to the right, case 2 - move node
319 rbt_rotate_left(nil
, node
);
322 grand_parent
= node
->parent
->parent
;
325 node
->parent
->color
= IB_RBT_BLACK
;
326 grand_parent
->color
= IB_RBT_RED
;
328 rbt_rotate_right(nil
, grand_parent
);
332 ib_rbt_node_t
* uncle
= grand_parent
->left
;
334 if (uncle
->color
== IB_RBT_RED
) {
336 /* Case 1 - change the colors. */
337 uncle
->color
= IB_RBT_BLACK
;
338 parent
->color
= IB_RBT_BLACK
;
339 grand_parent
->color
= IB_RBT_RED
;
341 /* Move node up the tree. */
346 if (node
== parent
->left
) {
347 /* Left is a black node and node is to
348 the right, case 2 - move node up and
351 rbt_rotate_right(nil
, node
);
354 grand_parent
= node
->parent
->parent
;
357 node
->parent
->color
= IB_RBT_BLACK
;
358 grand_parent
->color
= IB_RBT_RED
;
360 rbt_rotate_left(nil
, grand_parent
);
364 parent
= node
->parent
;
367 /* Color the root black. */
368 ROOT(tree
)->color
= IB_RBT_BLACK
;
371 /****************************************************************//**
372 Find the given node's successor.
373 @return successor node or NULL if no successor */
378 const ib_rbt_t
* tree
, /*!< in: rb tree */
379 const ib_rbt_node_t
* current
)/*!< in: this is declared const
380 because it can be called via
383 const ib_rbt_node_t
* nil
= tree
->nil
;
384 ib_rbt_node_t
* next
= current
->right
;
386 /* Is there a sub-tree to the right that we can follow. */
389 /* Follow the left most links of the current right child. */
390 while (next
->left
!= nil
) {
394 } else { /* We will have to go up the tree to find the successor. */
395 ib_rbt_node_t
* parent
= current
->parent
;
397 /* Cast away the const. */
398 next
= (ib_rbt_node_t
*) current
;
400 while (parent
!= tree
->root
&& next
== parent
->right
) {
402 parent
= next
->parent
;
405 next
= (parent
== tree
->root
) ? NULL
: parent
;
411 /****************************************************************//**
412 Find the given node's precedecessor.
413 @return predecessor node or NULL if no predecesor */
416 rbt_find_predecessor(
417 /*=================*/
418 const ib_rbt_t
* tree
, /*!< in: rb tree */
419 const ib_rbt_node_t
* current
) /*!< in: this is declared const
420 because it can be called via
423 const ib_rbt_node_t
* nil
= tree
->nil
;
424 ib_rbt_node_t
* prev
= current
->left
;
426 /* Is there a sub-tree to the left that we can follow. */
429 /* Follow the right most links of the current left child. */
430 while (prev
->right
!= nil
) {
434 } else { /* We will have to go up the tree to find the precedecessor. */
435 ib_rbt_node_t
* parent
= current
->parent
;
437 /* Cast away the const. */
438 prev
= (ib_rbt_node_t
*)current
;
440 while (parent
!= tree
->root
&& prev
== parent
->left
) {
442 parent
= prev
->parent
;
445 prev
= (parent
== tree
->root
) ? NULL
: parent
;
451 /****************************************************************//**
452 Replace node with child. After applying transformations eject becomes
458 ib_rbt_node_t
* eject
, /*!< in: node to eject */
459 ib_rbt_node_t
* node
) /*!< in: node to replace with */
461 /* Update the to be ejected node's parent's child pointers. */
462 if (eject
->parent
->left
== eject
) {
463 eject
->parent
->left
= node
;
464 } else if (eject
->parent
->right
== eject
) {
465 eject
->parent
->right
= node
;
469 /* eject is now an orphan but otherwise its pointers
470 and color are left intact. */
472 node
->parent
= eject
->parent
;
475 /****************************************************************//**
476 Replace a node with another node. */
481 ib_rbt_node_t
* replace
, /*!< in: node to replace */
482 ib_rbt_node_t
* node
) /*!< in: node to replace with */
484 ib_rbt_color_t color
= node
->color
;
486 /* Update the node pointers. */
487 node
->left
= replace
->left
;
488 node
->right
= replace
->right
;
490 /* Update the child node pointers. */
491 node
->left
->parent
= node
;
492 node
->right
->parent
= node
;
494 /* Make the parent of replace point to node. */
495 rbt_eject_node(replace
, node
);
497 /* Swap the colors. */
498 node
->color
= replace
->color
;
499 replace
->color
= color
;
502 /****************************************************************//**
503 Detach node from the tree replacing it with one of it's children.
504 @return the child node that now occupies the position of the detached node */
509 const ib_rbt_t
* tree
, /*!< in: rb tree */
510 ib_rbt_node_t
* node
) /*!< in: node to detach */
512 ib_rbt_node_t
* child
;
513 const ib_rbt_node_t
* nil
= tree
->nil
;
515 if (node
->left
!= nil
&& node
->right
!= nil
) {
516 /* Case where the node to be deleted has two children. */
517 ib_rbt_node_t
* successor
= rbt_find_successor(tree
, node
);
519 ut_a(successor
!= nil
);
520 ut_a(successor
->parent
!= nil
);
521 ut_a(successor
->left
== nil
);
523 child
= successor
->right
;
525 /* Remove the successor node and replace with its child. */
526 rbt_eject_node(successor
, child
);
528 /* Replace the node to delete with its successor node. */
529 rbt_replace_node(node
, successor
);
531 ut_a(node
->left
== nil
|| node
->right
== nil
);
533 child
= (node
->left
!= nil
) ? node
->left
: node
->right
;
535 /* Replace the node to delete with one of it's children. */
536 rbt_eject_node(node
, child
);
539 /* Reset the node links. */
540 node
->parent
= node
->right
= node
->left
= tree
->nil
;
545 /****************************************************************//**
546 Rebalance the right sub-tree after deletion.
547 @return node to rebalance if more rebalancing required else NULL */
552 const ib_rbt_node_t
* nil
, /*!< in: rb tree nil node */
553 ib_rbt_node_t
* parent
, /*!< in: parent node */
554 ib_rbt_node_t
* sibling
)/*!< in: sibling node */
556 ib_rbt_node_t
* node
= NULL
;
558 ut_a(sibling
!= nil
);
561 if (sibling
->color
== IB_RBT_RED
) {
563 parent
->color
= IB_RBT_RED
;
564 sibling
->color
= IB_RBT_BLACK
;
566 rbt_rotate_left(nil
, parent
);
568 sibling
= parent
->right
;
570 ut_a(sibling
!= nil
);
573 /* Since this will violate case 3 because of the change above. */
574 if (sibling
->left
->color
== IB_RBT_BLACK
575 && sibling
->right
->color
== IB_RBT_BLACK
) {
577 node
= parent
; /* Parent needs to be rebalanced too. */
578 sibling
->color
= IB_RBT_RED
;
581 if (sibling
->right
->color
== IB_RBT_BLACK
) {
583 ut_a(sibling
->left
->color
== IB_RBT_RED
);
585 sibling
->color
= IB_RBT_RED
;
586 sibling
->left
->color
= IB_RBT_BLACK
;
588 rbt_rotate_right(nil
, sibling
);
590 sibling
= parent
->right
;
591 ut_a(sibling
!= nil
);
594 sibling
->color
= parent
->color
;
595 sibling
->right
->color
= IB_RBT_BLACK
;
597 parent
->color
= IB_RBT_BLACK
;
599 rbt_rotate_left(nil
, parent
);
605 /****************************************************************//**
606 Rebalance the left sub-tree after deletion.
607 @return node to rebalance if more rebalancing required else NULL */
612 const ib_rbt_node_t
* nil
, /*!< in: rb tree nil node */
613 ib_rbt_node_t
* parent
, /*!< in: parent node */
614 ib_rbt_node_t
* sibling
)/*!< in: sibling node */
616 ib_rbt_node_t
* node
= NULL
;
618 ut_a(sibling
!= nil
);
621 if (sibling
->color
== IB_RBT_RED
) {
623 parent
->color
= IB_RBT_RED
;
624 sibling
->color
= IB_RBT_BLACK
;
626 rbt_rotate_right(nil
, parent
);
627 sibling
= parent
->left
;
629 ut_a(sibling
!= nil
);
632 /* Since this will violate case 3 because of the change above. */
633 if (sibling
->right
->color
== IB_RBT_BLACK
634 && sibling
->left
->color
== IB_RBT_BLACK
) {
636 node
= parent
; /* Parent needs to be rebalanced too. */
637 sibling
->color
= IB_RBT_RED
;
640 if (sibling
->left
->color
== IB_RBT_BLACK
) {
642 ut_a(sibling
->right
->color
== IB_RBT_RED
);
644 sibling
->color
= IB_RBT_RED
;
645 sibling
->right
->color
= IB_RBT_BLACK
;
647 rbt_rotate_left(nil
, sibling
);
649 sibling
= parent
->left
;
651 ut_a(sibling
!= nil
);
654 sibling
->color
= parent
->color
;
655 sibling
->left
->color
= IB_RBT_BLACK
;
657 parent
->color
= IB_RBT_BLACK
;
659 rbt_rotate_right(nil
, parent
);
665 /****************************************************************//**
666 Delete the node and rebalance the tree if necessary */
669 rbt_remove_node_and_rebalance(
670 /*==========================*/
671 ib_rbt_t
* tree
, /*!< in: rb tree */
672 ib_rbt_node_t
* node
) /*!< in: node to remove */
674 /* Detach node and get the node that will be used
675 as rebalance start. */
676 ib_rbt_node_t
* child
= rbt_detach_node(tree
, node
);
678 if (node
->color
== IB_RBT_BLACK
) {
679 ib_rbt_node_t
* last
= child
;
681 ROOT(tree
)->color
= IB_RBT_RED
;
683 while (child
&& child
->color
== IB_RBT_BLACK
) {
684 ib_rbt_node_t
* parent
= child
->parent
;
686 /* Did the deletion cause an imbalance in the
687 parents left sub-tree. */
688 if (parent
->left
== child
) {
690 child
= rbt_balance_right(
691 tree
->nil
, parent
, parent
->right
);
693 } else if (parent
->right
== child
) {
695 child
= rbt_balance_left(
696 tree
->nil
, parent
, parent
->left
);
709 last
->color
= IB_RBT_BLACK
;
710 ROOT(tree
)->color
= IB_RBT_BLACK
;
713 /* Note that we have removed a node from the tree. */
717 /****************************************************************//**
718 Recursively free the nodes. */
723 ib_rbt_node_t
* node
, /*!< in: node to free */
724 ib_rbt_node_t
* nil
) /*!< in: rb tree nil node */
727 rbt_free_node(node
->left
, nil
);
728 rbt_free_node(node
->right
, nil
);
734 /****************************************************************//**
735 Free all the nodes and free the tree. */
740 ib_rbt_t
* tree
) /*!< in: rb tree to free */
742 rbt_free_node(tree
->root
, tree
->nil
);
747 /****************************************************************//**
748 Create an instance of a red black tree.
749 @return an empty rb tree */
754 size_t sizeof_value
, /*!< in: sizeof data item */
755 ib_rbt_compare compare
) /*!< in: fn to compare items */
760 tree
= (ib_rbt_t
*) ut_malloc(sizeof(*tree
));
761 memset(tree
, 0, sizeof(*tree
));
763 tree
->sizeof_value
= sizeof_value
;
765 /* Create the sentinel (NIL) node. */
766 node
= tree
->nil
= (ib_rbt_node_t
*) ut_malloc(sizeof(*node
));
767 memset(node
, 0, sizeof(*node
));
769 node
->color
= IB_RBT_BLACK
;
770 node
->parent
= node
->left
= node
->right
= node
;
772 /* Create the "fake" root, the real root node will be the
773 left child of this node. */
774 node
= tree
->root
= (ib_rbt_node_t
*) ut_malloc(sizeof(*node
));
775 memset(node
, 0, sizeof(*node
));
777 node
->color
= IB_RBT_BLACK
;
778 node
->parent
= node
->left
= node
->right
= tree
->nil
;
780 tree
->compare
= compare
;
785 /****************************************************************//**
786 Generic insert of a value in the rb tree.
787 @return inserted node */
792 ib_rbt_t
* tree
, /*!< in: rb tree */
793 const void* key
, /*!< in: key for ordering */
794 const void* value
) /*!< in: value of key, this value
795 is copied to the node */
799 /* Create the node that will hold the value data. */
800 node
= (ib_rbt_node_t
*) ut_malloc(SIZEOF_NODE(tree
));
802 memcpy(node
->value
, value
, tree
->sizeof_value
);
803 node
->parent
= node
->left
= node
->right
= tree
->nil
;
805 /* Insert in the tree in the usual way. */
806 rbt_tree_insert(tree
, key
, node
);
807 rbt_balance_tree(tree
, node
);
814 /****************************************************************//**
815 Add a new node to the tree, useful for data that is pre-sorted.
816 @return appended node */
821 ib_rbt_t
* tree
, /*!< in: rb tree */
822 ib_rbt_bound_t
* parent
, /*!< in: bounds */
823 const void* value
) /*!< in: this value is copied
828 /* Create the node that will hold the value data */
829 node
= (ib_rbt_node_t
*) ut_malloc(SIZEOF_NODE(tree
));
831 memcpy(node
->value
, value
, tree
->sizeof_value
);
832 node
->parent
= node
->left
= node
->right
= tree
->nil
;
834 /* If tree is empty */
835 if (parent
->last
== NULL
) {
836 parent
->last
= tree
->root
;
839 /* Append the node, the hope here is that the caller knows
840 what s/he is doing. */
841 rbt_tree_add_child(tree
, parent
, node
);
842 rbt_balance_tree(tree
, node
);
846 #if defined(IB_RBT_TESTING)
847 ut_a(rbt_validate(tree
));
852 /****************************************************************//**
853 Find a matching node in the rb tree.
854 @return NULL if not found else the node where key was found */
859 const ib_rbt_t
* tree
, /*!< in: rb tree */
860 const void* key
) /*!< in: key to use for search */
862 const ib_rbt_node_t
* current
= ROOT(tree
);
864 /* Regular binary search. */
865 while (current
!= tree
->nil
) {
866 int result
= tree
->compare(key
, current
->value
);
869 current
= current
->left
;
870 } else if (result
> 0) {
871 current
= current
->right
;
877 return(current
!= tree
->nil
? current
: NULL
);
880 /****************************************************************//**
881 Delete a node from the red black tree, identified by key.
882 @return TRUE if success FALSE if not found */
887 ib_rbt_t
* tree
, /*!< in: rb tree */
888 const void* key
) /*!< in: key to delete */
890 ibool deleted
= FALSE
;
891 ib_rbt_node_t
* node
= (ib_rbt_node_t
*) rbt_lookup(tree
, key
);
894 rbt_remove_node_and_rebalance(tree
, node
);
903 /****************************************************************//**
904 Remove a node from the rb tree, the node is not free'd, that is the
905 callers responsibility.
906 @return deleted node but without the const */
911 ib_rbt_t
* tree
, /*!< in: rb tree */
912 const ib_rbt_node_t
* const_node
) /*!< in: node to delete, this
913 is a fudge and declared const
914 because the caller can access
917 /* Cast away the const. */
918 rbt_remove_node_and_rebalance(tree
, (ib_rbt_node_t
*) const_node
);
920 /* This is to make it easier to do something like this:
921 ut_free(rbt_remove_node(node));
924 return((ib_rbt_node_t
*) const_node
);
927 /****************************************************************//**
928 Find the node that has the lowest key that is >= key.
929 @return node satisfying the lower bound constraint or NULL */
934 const ib_rbt_t
* tree
, /*!< in: rb tree */
935 const void* key
) /*!< in: key to search */
937 ib_rbt_node_t
* lb_node
= NULL
;
938 ib_rbt_node_t
* current
= ROOT(tree
);
940 while (current
!= tree
->nil
) {
941 int result
= tree
->compare(key
, current
->value
);
945 current
= current
->right
;
947 } else if (result
< 0) {
950 current
= current
->left
;
961 /****************************************************************//**
962 Find the node that has the greatest key that is <= key.
963 @return node satisfying the upper bound constraint or NULL */
968 const ib_rbt_t
* tree
, /*!< in: rb tree */
969 const void* key
) /*!< in: key to search */
971 ib_rbt_node_t
* ub_node
= NULL
;
972 ib_rbt_node_t
* current
= ROOT(tree
);
974 while (current
!= tree
->nil
) {
975 int result
= tree
->compare(key
, current
->value
);
980 current
= current
->right
;
982 } else if (result
< 0) {
984 current
= current
->left
;
995 /****************************************************************//**
996 Find the node that has the greatest key that is <= key.
997 @return value of result */
1002 const ib_rbt_t
* tree
, /*!< in: rb tree */
1003 ib_rbt_bound_t
* parent
, /*!< in: search bounds */
1004 const void* key
) /*!< in: key to search */
1006 ib_rbt_node_t
* current
= ROOT(tree
);
1008 /* Every thing is greater than the NULL root. */
1010 parent
->last
= NULL
;
1012 while (current
!= tree
->nil
) {
1014 parent
->last
= current
;
1015 parent
->result
= tree
->compare(key
, current
->value
);
1017 if (parent
->result
> 0) {
1018 current
= current
->right
;
1019 } else if (parent
->result
< 0) {
1020 current
= current
->left
;
1026 return(parent
->result
);
1029 /****************************************************************//**
1030 Find the node that has the greatest key that is <= key. But use the
1031 supplied comparison function.
1032 @return value of result */
1037 const ib_rbt_t
* tree
, /*!< in: rb tree */
1038 ib_rbt_bound_t
* parent
, /*!< in: search bounds */
1039 const void* key
, /*!< in: key to search */
1040 ib_rbt_compare compare
) /*!< in: fn to compare items */
1042 ib_rbt_node_t
* current
= ROOT(tree
);
1044 /* Every thing is greater than the NULL root. */
1046 parent
->last
= NULL
;
1048 while (current
!= tree
->nil
) {
1050 parent
->last
= current
;
1051 parent
->result
= compare(key
, current
->value
);
1053 if (parent
->result
> 0) {
1054 current
= current
->right
;
1055 } else if (parent
->result
< 0) {
1056 current
= current
->left
;
1062 return(parent
->result
);
1065 /****************************************************************//**
1066 Get the leftmost node.
1067 Return the left most node in the tree. */
1069 const ib_rbt_node_t
*
1072 const ib_rbt_t
* tree
) /* in: rb tree */
1074 ib_rbt_node_t
* first
= NULL
;
1075 ib_rbt_node_t
* current
= ROOT(tree
);
1077 while (current
!= tree
->nil
) {
1079 current
= current
->left
;
1085 /****************************************************************//**
1086 Return the right most node in the tree.
1087 @return the rightmost node or NULL */
1089 const ib_rbt_node_t
*
1092 const ib_rbt_t
* tree
) /*!< in: rb tree */
1094 ib_rbt_node_t
* last
= NULL
;
1095 ib_rbt_node_t
* current
= ROOT(tree
);
1097 while (current
!= tree
->nil
) {
1099 current
= current
->right
;
1105 /****************************************************************//**
1106 Return the next node.
1107 @return node next from current */
1109 const ib_rbt_node_t
*
1112 const ib_rbt_t
* tree
, /*!< in: rb tree */
1113 const ib_rbt_node_t
* current
)/*!< in: current node */
1115 return(current
? rbt_find_successor(tree
, current
) : NULL
);
1118 /****************************************************************//**
1119 Return the previous node.
1120 @return node prev from current */
1122 const ib_rbt_node_t
*
1125 const ib_rbt_t
* tree
, /*!< in: rb tree */
1126 const ib_rbt_node_t
* current
)/*!< in: current node */
1128 return(current
? rbt_find_predecessor(tree
, current
) : NULL
);
1131 /****************************************************************//**
1132 Reset the tree. Delete all the nodes. */
1137 ib_rbt_t
* tree
) /*!< in: rb tree */
1139 rbt_free_node(ROOT(tree
), tree
->nil
);
1142 tree
->root
->left
= tree
->root
->right
= tree
->nil
;
1145 /****************************************************************//**
1146 Merge the node from dst into src. Return the number of nodes merged.
1147 @return no. of recs merged */
1152 ib_rbt_t
* dst
, /*!< in: dst rb tree */
1153 const ib_rbt_t
* src
) /*!< in: src rb tree */
1155 ib_rbt_bound_t parent
;
1157 const ib_rbt_node_t
* src_node
= rbt_first(src
);
1159 if (rbt_empty(src
) || dst
== src
) {
1163 for (/* No op */; src_node
; src_node
= rbt_next(src
, src_node
)) {
1165 if (rbt_search(dst
, &parent
, src_node
->value
) != 0) {
1166 rbt_add_node(dst
, &parent
, src_node
->value
);
1174 /****************************************************************//**
1175 Merge the node from dst into src. Return the number of nodes merged.
1176 Delete the nodes from src after copying node to dst. As a side effect
1177 the duplicates will be left untouched in the src.
1178 @return no. of recs merged */
1181 rbt_merge_uniq_destructive(
1182 /*=======================*/
1183 ib_rbt_t
* dst
, /*!< in: dst rb tree */
1184 ib_rbt_t
* src
) /*!< in: src rb tree */
1186 ib_rbt_bound_t parent
;
1187 ib_rbt_node_t
* src_node
;
1188 ulint old_size
= rbt_size(dst
);
1190 if (rbt_empty(src
) || dst
== src
) {
1194 for (src_node
= (ib_rbt_node_t
*) rbt_first(src
); src_node
; /* */) {
1195 ib_rbt_node_t
* prev
= src_node
;
1197 src_node
= (ib_rbt_node_t
*)rbt_next(src
, prev
);
1199 /* Skip duplicates. */
1200 if (rbt_search(dst
, &parent
, prev
->value
) != 0) {
1202 /* Remove and reset the node but preserve
1203 the node (data) value. */
1204 rbt_remove_node_and_rebalance(src
, prev
);
1206 /* The nil should be taken from the dst tree. */
1207 prev
->parent
= prev
->left
= prev
->right
= dst
->nil
;
1208 rbt_tree_add_child(dst
, &parent
, prev
);
1209 rbt_balance_tree(dst
, prev
);
1215 #if defined(IB_RBT_TESTING)
1216 ut_a(rbt_validate(dst
));
1217 ut_a(rbt_validate(src
));
1219 return(rbt_size(dst
) - old_size
);
1222 /****************************************************************//**
1223 Check that every path from the root to the leaves has the same count and
1224 the tree nodes are in order.
1225 @return TRUE if OK FALSE otherwise */
1230 const ib_rbt_t
* tree
) /*!< in: RB tree to validate */
1232 if (rbt_count_black_nodes(tree
, ROOT(tree
)) > 0) {
1233 return(rbt_check_ordering(tree
));
1239 /****************************************************************//**
1240 Iterate over the tree in depth first order. */
1245 const ib_rbt_t
* tree
, /*!< in: tree to traverse */
1246 ib_rbt_print_node print
) /*!< in: print function */
1248 rbt_print_subtree(tree
, ROOT(tree
), print
);