1
/***************************************************************************//**
3
Copyright (C) 2007, 2010, Innobase Oy. All Rights Reserved.
5
Portions of this file contain modifications contributed and copyrighted by
6
Sun Microsystems, Inc. Those modifications are gratefully acknowledged and
7
are described briefly in the InnoDB documentation. The contributions by
8
Sun Microsystems are incorporated with their permission, and subject to the
9
conditions contained in the file COPYING.Sun_Microsystems.
11
This program is free software; you can redistribute it and/or modify it under
12
the terms of the GNU General Public License as published by the Free Software
13
Foundation; version 2 of the License.
15
This program is distributed in the hope that it will be useful, but WITHOUT
16
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
19
You should have received a copy of the GNU General Public License along with
20
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21
Place, Suite 330, Boston, MA 02111-1307 USA
23
*****************************************************************************/
24
/********************************************************************//**
25
Red-Black tree implementation
27
(c) 2007 Oracle/Innobase Oy
29
Created 2007-03-20 Sunny Bains
30
***********************************************************************/
34
/**********************************************************************//**
35
Definition of a red-black tree
36
==============================
38
A red-black tree is a binary search tree which has the following
41
1. Every node is either red or black.
42
2. Every leaf (NULL - in our case tree->nil) is black.
43
3. If a node is red, then both its children are black.
44
4. Every simple path from a node to a descendant leaf contains the
45
same number of black nodes.
47
from (3) above, the implication is that on any path from the root
48
to a leaf, red nodes must not be adjacent.
50
However, any number of black nodes may appear in a sequence.
53
#if defined(IB_RBT_TESTING)
54
#warning "Testing enabled!"
57
#define ROOT(t) (t->root->left)
58
#define SIZEOF_NODE(t) ((sizeof(ib_rbt_node_t) + t->sizeof_value) - 1)
60
/**********************************************************************//**
61
Print out the sub-tree recursively. */
66
const ib_rbt_t* tree, /*!< in: tree to traverse */
67
const ib_rbt_node_t* node, /*!< in: node to print */
68
ib_rbt_print_node print) /*!< in: print key function */
70
/* FIXME: Doesn't do anything yet */
71
if (node != tree->nil) {
73
rbt_print_subtree(tree, node->left, print);
74
rbt_print_subtree(tree, node->right, print);
78
/**********************************************************************//**
79
Verify that the keys are in order.
80
@return TRUE of OK. FALSE if not ordered */
85
const ib_rbt_t* tree) /*!< in: tree to verfify */
87
const ib_rbt_node_t* node;
88
const ib_rbt_node_t* prev = NULL;
90
/* Iterate over all the nodes, comparing each node with the prev */
91
for (node = rbt_first(tree); node; node = rbt_next(tree, prev)) {
93
if (prev && tree->compare(prev->value, node->value) >= 0) {
103
/**********************************************************************//**
104
Check that every path from the root to the leaves has the same count.
105
Count is expressed in the number of black nodes.
106
@return 0 on failure else black height of the subtree */
109
rbt_count_black_nodes(
110
/*==================*/
111
const ib_rbt_t* tree, /*!< in: tree to verify */
112
const ib_rbt_node_t* node) /*!< in: start of sub-tree */
116
if (node != tree->nil) {
117
ulint left_height = rbt_count_black_nodes(tree, node->left);
119
ulint right_height = rbt_count_black_nodes(tree, node->right);
123
|| left_height != right_height) {
126
} else if (node->color == IB_RBT_RED) {
129
if (node->left->color != IB_RBT_BLACK
130
|| node->right->color != IB_RBT_BLACK) {
134
result = left_height;
136
/* Check if it's anything other than RED or BLACK. */
137
} else if (node->color != IB_RBT_BLACK) {
142
result = right_height + 1;
151
/**********************************************************************//**
152
Turn the node's right child's left sub-tree into node's right sub-tree.
153
This will also make node's right child it's parent. */
158
const ib_rbt_node_t* nil, /*!< in: nil node of the tree */
159
ib_rbt_node_t* node) /*!< in: node to rotate */
161
ib_rbt_node_t* right = node->right;
163
node->right = right->left;
165
if (right->left != nil) {
166
right->left->parent = node;
169
/* Right's new parent was node's parent. */
170
right->parent = node->parent;
172
/* Since root's parent is tree->nil and root->parent->left points
173
back to root, we can avoid the check. */
174
if (node == node->parent->left) {
175
/* Node was on the left of its parent. */
176
node->parent->left = right;
178
/* Node must have been on the right. */
179
node->parent->right = right;
182
/* Finally, put node on right's left. */
184
node->parent = right;
187
/**********************************************************************//**
188
Turn the node's left child's right sub-tree into node's left sub-tree.
189
This also make node's left child it's parent. */
194
const ib_rbt_node_t* nil, /*!< in: nil node of tree */
195
ib_rbt_node_t* node) /*!< in: node to rotate */
197
ib_rbt_node_t* left = node->left;
199
node->left = left->right;
201
if (left->right != nil) {
202
left->right->parent = node;
205
/* Left's new parent was node's parent. */
206
left->parent = node->parent;
208
/* Since root's parent is tree->nil and root->parent->left points
209
back to root, we can avoid the check. */
210
if (node == node->parent->right) {
211
/* Node was on the left of its parent. */
212
node->parent->right = left;
214
/* Node must have been on the left. */
215
node->parent->left = left;
218
/* Finally, put node on left's right. */
223
/**********************************************************************//**
224
Append a node to the tree. */
229
const ib_rbt_t* tree,
230
ib_rbt_bound_t* parent,
233
/* Cast away the const. */
234
ib_rbt_node_t* last = (ib_rbt_node_t*) parent->last;
236
if (last == tree->root || parent->result < 0) {
239
/* FIXME: We don't handle duplicates (yet)! */
240
ut_a(parent->result != 0);
250
/**********************************************************************//**
251
Generic binary tree insert */
260
ib_rbt_bound_t parent;
261
ib_rbt_node_t* current = ROOT(tree);
264
parent.last = tree->root;
266
/* Regular binary search. */
267
while (current != tree->nil) {
269
parent.last = current;
270
parent.result = tree->compare(key, current->value);
272
if (parent.result < 0) {
273
current = current->left;
275
current = current->right;
279
ut_a(current == tree->nil);
281
rbt_tree_add_child(tree, &parent, node);
286
/**********************************************************************//**
287
Balance a tree after inserting a node. */
292
const ib_rbt_t* tree, /*!< in: tree to balance */
293
ib_rbt_node_t* node) /*!< in: node that was inserted */
295
const ib_rbt_node_t* nil = tree->nil;
296
ib_rbt_node_t* parent = node->parent;
298
/* Restore the red-black property. */
299
node->color = IB_RBT_RED;
301
while (node != ROOT(tree) && parent->color == IB_RBT_RED) {
302
ib_rbt_node_t* grand_parent = parent->parent;
304
if (parent == grand_parent->left) {
305
ib_rbt_node_t* uncle = grand_parent->right;
307
if (uncle->color == IB_RBT_RED) {
309
/* Case 1 - change the colors. */
310
uncle->color = IB_RBT_BLACK;
311
parent->color = IB_RBT_BLACK;
312
grand_parent->color = IB_RBT_RED;
314
/* Move node up the tree. */
319
if (node == parent->right) {
320
/* Right is a black node and node is
321
to the right, case 2 - move node
324
rbt_rotate_left(nil, node);
327
grand_parent = node->parent->parent;
330
node->parent->color = IB_RBT_BLACK;
331
grand_parent->color = IB_RBT_RED;
333
rbt_rotate_right(nil, grand_parent);
337
ib_rbt_node_t* uncle = grand_parent->left;
339
if (uncle->color == IB_RBT_RED) {
341
/* Case 1 - change the colors. */
342
uncle->color = IB_RBT_BLACK;
343
parent->color = IB_RBT_BLACK;
344
grand_parent->color = IB_RBT_RED;
346
/* Move node up the tree. */
351
if (node == parent->left) {
352
/* Left is a black node and node is to
353
the right, case 2 - move node up and
356
rbt_rotate_right(nil, node);
359
grand_parent = node->parent->parent;
362
node->parent->color = IB_RBT_BLACK;
363
grand_parent->color = IB_RBT_RED;
365
rbt_rotate_left(nil, grand_parent);
369
parent = node->parent;
372
/* Color the root black. */
373
ROOT(tree)->color = IB_RBT_BLACK;
376
/**********************************************************************//**
377
Find the given node's successor.
378
@return successor node or NULL if no successor */
383
const ib_rbt_t* tree, /*!< in: rb tree */
384
const ib_rbt_node_t* current) /*!< in: this is declared const
385
because it can be called via
388
const ib_rbt_node_t* nil = tree->nil;
389
ib_rbt_node_t* next = current->right;
391
/* Is there a sub-tree to the right that we can follow. */
394
/* Follow the left most links of the current right child. */
395
while (next->left != nil) {
399
} else { /* We will have to go up the tree to find the successor. */
400
ib_rbt_node_t* parent = current->parent;
402
/* Cast away the const. */
403
next = (ib_rbt_node_t*) current;
405
while (parent != tree->root && next == parent->right) {
407
parent = next->parent;
410
next = (parent == tree->root) ? NULL : parent;
416
/**********************************************************************//**
417
Find the given node's precedecessor.
418
@return predecessor node or NULL if no predecesor */
421
rbt_find_predecessor(
422
/*=================*/
423
const ib_rbt_t* tree, /*!< in: rb tree */
424
const ib_rbt_node_t* current) /*!< in: this is declared const
425
because it can be called via
428
const ib_rbt_node_t* nil = tree->nil;
429
ib_rbt_node_t* prev = current->left;
431
/* Is there a sub-tree to the left that we can follow. */
434
/* Follow the right most links of the current left child. */
435
while (prev->right != nil) {
439
} else { /* We will have to go up the tree to find the precedecessor. */
440
ib_rbt_node_t* parent = current->parent;
442
/* Cast away the const. */
443
prev = (ib_rbt_node_t*)current;
445
while (parent != tree->root && prev == parent->left) {
447
parent = prev->parent;
450
prev = (parent == tree->root) ? NULL : parent;
456
/**********************************************************************//**
457
Replace node with child. After applying transformations eject becomes
463
ib_rbt_node_t* eject, /*!< in: node to eject */
464
ib_rbt_node_t* node) /*!< in: node to replace with */
466
/* Update the to be ejected node's parent's child pointers. */
467
if (eject->parent->left == eject) {
468
eject->parent->left = node;
469
} else if (eject->parent->right == eject) {
470
eject->parent->right = node;
474
/* eject is now an orphan but otherwise its pointers
475
and color are left intact. */
477
node->parent = eject->parent;
480
/**********************************************************************//**
481
Replace a node with another node. */
486
ib_rbt_node_t* replace, /*!< in: node to replace */
487
ib_rbt_node_t* node) /*!< in: node to replace with */
489
ib_rbt_color_t color = node->color;
491
/* Update the node pointers. */
492
node->left = replace->left;
493
node->right = replace->right;
495
/* Update the child node pointers. */
496
node->left->parent = node;
497
node->right->parent = node;
499
/* Make the parent of replace point to node. */
500
rbt_eject_node(replace, node);
502
/* Swap the colors. */
503
node->color = replace->color;
504
replace->color = color;
507
/**********************************************************************//**
508
Detach node from the tree replacing it with one of it's children.
509
@return the child node that now occupies the position of the detached node */
514
const ib_rbt_t* tree, /*!< in: rb tree */
515
ib_rbt_node_t* node) /*!< in: node to detach */
517
ib_rbt_node_t* child;
518
const ib_rbt_node_t* nil = tree->nil;
520
if (node->left != nil && node->right != nil) {
521
/* Case where the node to be deleted has two children. */
522
ib_rbt_node_t* successor = rbt_find_successor(tree, node);
524
ut_a(successor != nil);
525
ut_a(successor->parent != nil);
526
ut_a(successor->left == nil);
528
child = successor->right;
530
/* Remove the successor node and replace with its child. */
531
rbt_eject_node(successor, child);
533
/* Replace the node to delete with its successor node. */
534
rbt_replace_node(node, successor);
536
ut_a(node->left == nil || node->right == nil);
538
child = (node->left != nil) ? node->left : node->right;
540
/* Replace the node to delete with one of it's children. */
541
rbt_eject_node(node, child);
544
/* Reset the node links. */
545
node->parent = node->right = node->left = tree->nil;
550
/**********************************************************************//**
551
Rebalance the right sub-tree after deletion.
552
@return node to rebalance if more rebalancing required else NULL */
557
const ib_rbt_node_t* nil, /*!< in: rb tree nil node */
558
ib_rbt_node_t* parent, /*!< in: parent node */
559
ib_rbt_node_t* sibling) /*!< in: sibling node */
561
ib_rbt_node_t* node = NULL;
563
ut_a(sibling != nil);
566
if (sibling->color == IB_RBT_RED) {
568
parent->color = IB_RBT_RED;
569
sibling->color = IB_RBT_BLACK;
571
rbt_rotate_left(nil, parent);
573
sibling = parent->right;
575
ut_a(sibling != nil);
578
/* Since this will violate case 3 because of the change above. */
579
if (sibling->left->color == IB_RBT_BLACK
580
&& sibling->right->color == IB_RBT_BLACK) {
582
node = parent; /* Parent needs to be rebalanced too. */
583
sibling->color = IB_RBT_RED;
586
if (sibling->right->color == IB_RBT_BLACK) {
588
ut_a(sibling->left->color == IB_RBT_RED);
590
sibling->color = IB_RBT_RED;
591
sibling->left->color = IB_RBT_BLACK;
593
rbt_rotate_right(nil, sibling);
595
sibling = parent->right;
596
ut_a(sibling != nil);
599
sibling->color = parent->color;
600
sibling->right->color = IB_RBT_BLACK;
602
parent->color = IB_RBT_BLACK;
604
rbt_rotate_left(nil, parent);
610
/**********************************************************************//**
611
Rebalance the left sub-tree after deletion.
612
@return node to rebalance if more rebalancing required else NULL */
617
const ib_rbt_node_t* nil, /*!< in: rb tree nil node */
618
ib_rbt_node_t* parent, /*!< in: parent node */
619
ib_rbt_node_t* sibling) /*!< in: sibling node */
621
ib_rbt_node_t* node = NULL;
623
ut_a(sibling != nil);
626
if (sibling->color == IB_RBT_RED) {
628
parent->color = IB_RBT_RED;
629
sibling->color = IB_RBT_BLACK;
631
rbt_rotate_right(nil, parent);
632
sibling = parent->left;
634
ut_a(sibling != nil);
637
/* Since this will violate case 3 because of the change above. */
638
if (sibling->right->color == IB_RBT_BLACK
639
&& sibling->left->color == IB_RBT_BLACK) {
641
node = parent; /* Parent needs to be rebalanced too. */
642
sibling->color = IB_RBT_RED;
645
if (sibling->left->color == IB_RBT_BLACK) {
647
ut_a(sibling->right->color == IB_RBT_RED);
649
sibling->color = IB_RBT_RED;
650
sibling->right->color = IB_RBT_BLACK;
652
rbt_rotate_left(nil, sibling);
654
sibling = parent->left;
656
ut_a(sibling != nil);
659
sibling->color = parent->color;
660
sibling->left->color = IB_RBT_BLACK;
662
parent->color = IB_RBT_BLACK;
664
rbt_rotate_right(nil, parent);
670
/**********************************************************************//**
671
Delete the node and rebalance the tree if necessary */
674
rbt_remove_node_and_rebalance(
675
/*==========================*/
676
ib_rbt_t* tree, /*!< in: rb tree */
677
ib_rbt_node_t* node) /*!< in: node to remove */
679
/* Detach node and get the node that will be used
680
as rebalance start. */
681
ib_rbt_node_t* child = rbt_detach_node(tree, node);
683
if (node->color == IB_RBT_BLACK) {
684
ib_rbt_node_t* last = child;
686
ROOT(tree)->color = IB_RBT_RED;
688
while (child && child->color == IB_RBT_BLACK) {
689
ib_rbt_node_t* parent = child->parent;
691
/* Did the deletion cause an imbalance in the
692
parents left sub-tree. */
693
if (parent->left == child) {
695
child = rbt_balance_right(
696
tree->nil, parent, parent->right);
698
} else if (parent->right == child) {
700
child = rbt_balance_left(
701
tree->nil, parent, parent->left);
714
last->color = IB_RBT_BLACK;
715
ROOT(tree)->color = IB_RBT_BLACK;
718
/* Note that we have removed a node from the tree. */
722
/**********************************************************************//**
723
Recursively free the nodes. */
728
ib_rbt_node_t* node, /*!< in: node to free */
729
ib_rbt_node_t* nil) /*!< in: rb tree nil node */
732
rbt_free_node(node->left, nil);
733
rbt_free_node(node->right, nil);
739
/**********************************************************************//**
740
Free all the nodes and free the tree. */
745
ib_rbt_t* tree) /*!< in: rb tree to free */
747
rbt_free_node(tree->root, tree->nil);
752
/**********************************************************************//**
753
Create an instance of a red black tree.
754
@return an empty rb tree */
759
size_t sizeof_value, /*!< in: sizeof data item */
760
ib_rbt_compare compare) /*!< in: fn to compare items */
765
tree = (ib_rbt_t*) ut_malloc(sizeof(*tree));
766
memset(tree, 0, sizeof(*tree));
768
tree->sizeof_value = sizeof_value;
770
/* Create the sentinel (NIL) node. */
771
node = tree->nil = (ib_rbt_node_t*) ut_malloc(sizeof(*node));
772
memset(node, 0, sizeof(*node));
774
node->color = IB_RBT_BLACK;
775
node->parent = node->left = node->right = node;
777
/* Create the "fake" root, the real root node will be the
778
left child of this node. */
779
node = tree->root = (ib_rbt_node_t*) ut_malloc(sizeof(*node));
780
memset(node, 0, sizeof(*node));
782
node->color = IB_RBT_BLACK;
783
node->parent = node->left = node->right = tree->nil;
785
tree->compare = compare;
790
/**********************************************************************//**
791
Generic insert of a value in the rb tree.
792
@return inserted node */
797
ib_rbt_t* tree, /*!< in: rb tree */
798
const void* key, /*!< in: key for ordering */
799
const void* value) /*!< in: value of key, this value
800
is copied to the node */
804
/* Create the node that will hold the value data. */
805
node = (ib_rbt_node_t*) ut_malloc(SIZEOF_NODE(tree));
807
memcpy(node->value, value, tree->sizeof_value);
808
node->parent = node->left = node->right = tree->nil;
810
/* Insert in the tree in the usual way. */
811
rbt_tree_insert(tree, key, node);
812
rbt_balance_tree(tree, node);
819
/**********************************************************************//**
820
Add a new node to the tree, useful for data that is pre-sorted.
821
@return appended node */
826
ib_rbt_t* tree, /*!< in: rb tree */
827
ib_rbt_bound_t* parent, /*!< in: bounds */
828
const void* value) /*!< in: this value is copied
833
/* Create the node that will hold the value data */
834
node = (ib_rbt_node_t*) ut_malloc(SIZEOF_NODE(tree));
836
memcpy(node->value, value, tree->sizeof_value);
837
node->parent = node->left = node->right = tree->nil;
839
/* If tree is empty */
840
if (parent->last == NULL) {
841
parent->last = tree->root;
844
/* Append the node, the hope here is that the caller knows
845
what s/he is doing. */
846
rbt_tree_add_child(tree, parent, node);
847
rbt_balance_tree(tree, node);
851
#if defined(IB_RBT_TESTING)
852
ut_a(rbt_validate(tree));
857
/**********************************************************************//**
858
Find a matching node in the rb tree.
859
@return NULL if not found else the node where key was found */
864
const ib_rbt_t* tree, /*!< in: rb tree */
865
const void* key) /*!< in: key to use for search */
867
const ib_rbt_node_t* current = ROOT(tree);
869
/* Regular binary search. */
870
while (current != tree->nil) {
871
int result = tree->compare(key, current->value);
874
current = current->left;
875
} else if (result > 0) {
876
current = current->right;
882
return(current != tree->nil ? current : NULL);
885
/**********************************************************************//**
886
Delete a node indentified by key.
887
@return TRUE if success FALSE if not found */
892
ib_rbt_t* tree, /*!< in: rb tree */
893
const void* key) /*!< in: key to delete */
895
ibool deleted = FALSE;
896
ib_rbt_node_t* node = (ib_rbt_node_t*) rbt_lookup(tree, key);
899
rbt_remove_node_and_rebalance(tree, node);
908
/**********************************************************************//**
909
Remove a node from the rb tree, the node is not free'd, that is the
910
callers responsibility.
911
@return deleted node but without the const */
916
ib_rbt_t* tree, /*!< in: rb tree */
917
const ib_rbt_node_t* const_node) /*!< in: node to delete, this
918
is a fudge and declared const
919
because the caller can access
922
/* Cast away the const. */
923
rbt_remove_node_and_rebalance(tree, (ib_rbt_node_t*) const_node);
925
/* This is to make it easier to do something like this:
926
ut_free(rbt_remove_node(node));
929
return((ib_rbt_node_t*) const_node);
932
/**********************************************************************//**
933
Find the node that has the lowest key that is >= key.
934
@return node satisfying the lower bound constraint or NULL */
939
const ib_rbt_t* tree, /*!< in: rb tree */
940
const void* key) /*!< in: key to search */
942
ib_rbt_node_t* lb_node = NULL;
943
ib_rbt_node_t* current = ROOT(tree);
945
while (current != tree->nil) {
946
int result = tree->compare(key, current->value);
950
current = current->right;
952
} else if (result < 0) {
955
current = current->left;
966
/**********************************************************************//**
967
Find the node that has the greatest key that is <= key.
968
@return node satisfying the upper bound constraint or NULL */
973
const ib_rbt_t* tree, /*!< in: rb tree */
974
const void* key) /*!< in: key to search */
976
ib_rbt_node_t* ub_node = NULL;
977
ib_rbt_node_t* current = ROOT(tree);
979
while (current != tree->nil) {
980
int result = tree->compare(key, current->value);
985
current = current->right;
987
} else if (result < 0) {
989
current = current->left;
1000
/**********************************************************************//**
1001
Find the node that has the greatest key that is <= key.
1002
@return value of result */
1007
const ib_rbt_t* tree, /*!< in: rb tree */
1008
ib_rbt_bound_t* parent, /*!< in: search bounds */
1009
const void* key) /*!< in: key to search */
1011
ib_rbt_node_t* current = ROOT(tree);
1013
/* Every thing is greater than the NULL root. */
1015
parent->last = NULL;
1017
while (current != tree->nil) {
1019
parent->last = current;
1020
parent->result = tree->compare(key, current->value);
1022
if (parent->result > 0) {
1023
current = current->right;
1024
} else if (parent->result < 0) {
1025
current = current->left;
1031
return(parent->result);
1034
/**********************************************************************//**
1035
Find the node that has the greatest key that is <= key. But use the
1036
supplied comparison function.
1037
@return value of result */
1042
const ib_rbt_t* tree, /*!< in: rb tree */
1043
ib_rbt_bound_t* parent, /*!< in: search bounds */
1044
const void* key, /*!< in: key to search */
1045
ib_rbt_compare compare) /*!< in: fn to compare items */
1047
ib_rbt_node_t* current = ROOT(tree);
1049
/* Every thing is greater than the NULL root. */
1051
parent->last = NULL;
1053
while (current != tree->nil) {
1055
parent->last = current;
1056
parent->result = compare(key, current->value);
1058
if (parent->result > 0) {
1059
current = current->right;
1060
} else if (parent->result < 0) {
1061
current = current->left;
1067
return(parent->result);
1070
/**********************************************************************//**
1071
Return the left most node in the tree. */
1073
const ib_rbt_node_t*
1076
/* out leftmost node or NULL */
1077
const ib_rbt_t* tree) /* in: rb tree */
1079
ib_rbt_node_t* first = NULL;
1080
ib_rbt_node_t* current = ROOT(tree);
1082
while (current != tree->nil) {
1084
current = current->left;
1090
/**********************************************************************//**
1091
Return the right most node in the tree.
1092
@return the rightmost node or NULL */
1094
const ib_rbt_node_t*
1097
const ib_rbt_t* tree) /*!< in: rb tree */
1099
ib_rbt_node_t* last = NULL;
1100
ib_rbt_node_t* current = ROOT(tree);
1102
while (current != tree->nil) {
1104
current = current->right;
1110
/**********************************************************************//**
1111
Return the next node.
1112
@return node next from current */
1114
const ib_rbt_node_t*
1117
const ib_rbt_t* tree, /*!< in: rb tree */
1118
const ib_rbt_node_t* current) /*!< in: current node */
1120
return(current ? rbt_find_successor(tree, current) : NULL);
1123
/**********************************************************************//**
1124
Return the previous node.
1125
@return node prev from current */
1127
const ib_rbt_node_t*
1130
const ib_rbt_t* tree, /*!< in: rb tree */
1131
const ib_rbt_node_t* current) /*!< in: current node */
1133
return(current ? rbt_find_predecessor(tree, current) : NULL);
1136
/**********************************************************************//**
1137
Reset the tree. Delete all the nodes. */
1142
ib_rbt_t* tree) /*!< in: rb tree */
1144
rbt_free_node(ROOT(tree), tree->nil);
1147
tree->root->left = tree->root->right = tree->nil;
1150
/**********************************************************************//**
1151
Merge the node from dst into src. Return the number of nodes merged.
1152
@return no. of recs merged */
1157
ib_rbt_t* dst, /*!< in: dst rb tree */
1158
const ib_rbt_t* src) /*!< in: src rb tree */
1160
ib_rbt_bound_t parent;
1162
const ib_rbt_node_t* src_node = rbt_first(src);
1164
if (rbt_empty(src) || dst == src) {
1168
for (/* No op */; src_node; src_node = rbt_next(src, src_node)) {
1170
if (rbt_search(dst, &parent, src_node->value) != 0) {
1171
rbt_add_node(dst, &parent, src_node->value);
1179
/**********************************************************************//**
1180
Merge the node from dst into src. Return the number of nodes merged.
1181
Delete the nodes from src after copying node to dst. As a side effect
1182
the duplicates will be left untouched in the src.
1183
@return no. of recs merged */
1186
rbt_merge_uniq_destructive(
1187
/*=======================*/
1188
ib_rbt_t* dst, /*!< in: dst rb tree */
1189
ib_rbt_t* src) /*!< in: src rb tree */
1191
ib_rbt_bound_t parent;
1192
ib_rbt_node_t* src_node;
1193
ulint old_size = rbt_size(dst);
1195
if (rbt_empty(src) || dst == src) {
1199
for (src_node = (ib_rbt_node_t*) rbt_first(src); src_node; /* */) {
1200
ib_rbt_node_t* prev = src_node;
1202
src_node = (ib_rbt_node_t*)rbt_next(src, prev);
1204
/* Skip duplicates. */
1205
if (rbt_search(dst, &parent, prev->value) != 0) {
1207
/* Remove and reset the node but preserve
1208
the node (data) value. */
1209
rbt_remove_node_and_rebalance(src, prev);
1211
/* The nil should be taken from the dst tree. */
1212
prev->parent = prev->left = prev->right = dst->nil;
1213
rbt_tree_add_child(dst, &parent, prev);
1214
rbt_balance_tree(dst, prev);
1220
#if defined(IB_RBT_TESTING)
1221
ut_a(rbt_validate(dst));
1222
ut_a(rbt_validate(src));
1224
return(rbt_size(dst) - old_size);
1227
/**********************************************************************//**
1228
Check that every path from the root to the leaves has the same count and
1229
the tree nodes are in order.
1230
@return TRUE if OK FALSE otherwise */
1235
const ib_rbt_t* tree) /*!< in: RB tree to validate */
1237
if (rbt_count_black_nodes(tree, ROOT(tree)) > 0) {
1238
return(rbt_check_ordering(tree));
1244
/**********************************************************************//**
1245
Iterate over the tree in depth first order. */
1250
const ib_rbt_t* tree, /*!< in: tree to traverse */
1251
ib_rbt_print_node print) /*!< in: print function */
1253
rbt_print_subtree(tree, ROOT(tree), print);