Home | History | Annotate | Download | only in ffsb-6.0-rc2
      1 /*
      2  *   Copyright (c) International Business Machines Corp., 2001-2004
      3  *
      4  *   This program is free software;  you can redistribute it and/or modify
      5  *   it under the terms of the GNU General Public License as published by
      6  *   the Free Software Foundation; either version 2 of the License, or
      7  *   (at your option) any later version.
      8  *
      9  *   This program is distributed in the hope that it will be useful,
     10  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
     11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
     12  *   the GNU General Public License for more details.
     13  *
     14  *   You should have received a copy of the GNU General Public License
     15  *   along with this program;  if not, write to the Free Software
     16  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     17  */
     18 #include <stdio.h>
     19 #include <stdlib.h>
     20 #include <assert.h>
     21 #include "rbt.h"
     22 
     23 /*
     24  * ***********************************************
     25  *
     26  * D.H. IBM, S. Rao
     27  *
     28  * Module: Operations executed on red-black struct
     29  *
     30  * ***********************************************
     31  */
     32 
     33 /* Construct a red-black tree node */
     34 
     35 rb_node *rbnode_construct(datatype object, rb_color color)
     36 {
     37 	rb_node *node = (rb_node *) malloc(sizeof(rb_node));
     38 	if (!node) {
     39 		fprintf(stderr, "Memory Shortage - No Execution Possible\n");
     40 		return NULL;
     41 	}
     42 	node->object = object;
     43 	node->color = color;
     44 	node->parent = node->right = node->left = NULL;
     45 	return node;
     46 }
     47 
     48 /* Destructor of a red-black tree node */
     49 
     50 void rbnode_destruct(rb_node * node, destructor d)
     51 {
     52 	if (!node)
     53 		return;
     54 	if (d != NULL)
     55 		d(node->object);
     56 	rbnode_destruct(node->right, d);
     57 	rbnode_destruct(node->left, d);
     58 	free(node);
     59 }
     60 
     61 /* Determine the depth of the subtree spanned by a given node */
     62 
     63 int rbnode_depth(rb_node * node)
     64 {
     65 	/* Recursively determine the depth of the left and right
     66 	 * subtrees
     67 	 */
     68 	int irightdepth = (node->right) ? rbnode_depth(node->right) : 0;
     69 	int ileftdepth = (node->left) ? rbnode_depth(node->left) : 0;
     70 
     71 	/* Return the maximal child depth + 1 (the current node) */
     72 	return ((irightdepth >
     73 		 ileftdepth) ? (irightdepth + 1) : (ileftdepth + 1));
     74 }
     75 
     76 /* Return the leftmost leaf in the tree */
     77 
     78 rb_node *rbnode_minimum(rb_node * node)
     79 {
     80 	while (node->left)
     81 		node = node->left;
     82 	return node;
     83 }
     84 
     85 /* Return the rightmost leaf in the tree */
     86 
     87 rb_node *rbnode_maximum(rb_node * node)
     88 {
     89 	while (node->right)
     90 		node = node->right;
     91 	return node;
     92 }
     93 
     94 /* Replace an object */
     95 
     96 void rbnode_replace(rb_node * node, datatype object)
     97 {
     98 	/* Make sure the replacement does not violate the tree order
     99 	 * Replace the object at the node
    100 	 */
    101 	node->object = object;
    102 }
    103 
    104 /* Get the next node in the tree (according to the tree order) */
    105 
    106 rb_node *rbnode_successor(rb_node * node)
    107 {
    108 	rb_node *succ_node;
    109 
    110 	if (node->right) {
    111 
    112 		/* If there is a right child, the successor is the
    113 		 * minimal object in the sub-tree spanned by this
    114 		 * child.
    115 		 */
    116 
    117 		succ_node = node->right;
    118 		while (succ_node->left)
    119 			succ_node = succ_node->left;
    120 	} else {
    121 
    122 		/* Otherwise, go up the tree until reaching the parent
    123 		 * from the left direction.
    124 		 */
    125 
    126 		rb_node *prev_node = node;
    127 		succ_node = node->parent;
    128 		while (succ_node && prev_node == succ_node->right) {
    129 			prev_node = succ_node;
    130 			succ_node = succ_node->parent;
    131 		}
    132 	}
    133 
    134 	return (succ_node);
    135 }
    136 
    137 /* Get the previous node in the tree (according to the tree order) */
    138 
    139 rb_node *rbnode_predecessor(rb_node * node)
    140 {
    141 	rb_node *pred_node;
    142 
    143 	if (node->left) {
    144 
    145 		/* If there is a left child, the predecessor is the
    146 		 * maximal object in the sub-tree spanned by this
    147 		 * child.
    148 		 */
    149 
    150 		pred_node = node->left;
    151 		while (pred_node->right)
    152 			pred_node = pred_node->right;
    153 	} else {
    154 
    155 		/* Otherwise, go up the tree until reaching the parent
    156 		 * from the right direction.
    157 		 */
    158 
    159 		rb_node *prev_node = node;
    160 		pred_node = node->parent;
    161 		while (pred_node && prev_node == pred_node->left) {
    162 			prev_node = pred_node;
    163 			pred_node = pred_node->parent;
    164 		}
    165 	}
    166 
    167 	return (pred_node);
    168 }
    169 
    170 /* Return a pointer to a duplication of the given node */
    171 
    172 rb_node *rbnode_duplicate(rb_node * node)
    173 {
    174 	/* Create a node of the same color, containing the same
    175 	 * object
    176 	 */
    177 	rb_node *dup_node = rbnode_construct(node->object, node->color);
    178 	if (!dup_node)
    179 		return NULL;
    180 
    181 	/* Duplicate the children recursively */
    182 	if (node->right) {
    183 		dup_node->right = rbnode_duplicate(node->right);
    184 		dup_node->right->parent = dup_node;
    185 	} else {
    186 		dup_node->right = NULL;
    187 	}
    188 
    189 	if (node->left) {
    190 		dup_node->left = rbnode_duplicate(node->left);
    191 		dup_node->left->parent = dup_node;
    192 	} else {
    193 		dup_node->left = NULL;
    194 	}
    195 
    196 	return dup_node;	/* Return the duplicated node */
    197 }
    198 
    199 /* Traverse a red-black subtree */
    200 
    201 void rbnode_traverse(rb_node * node, opr * op)
    202 {
    203 	if (!node)
    204 		return;
    205 	rbnode_traverse(node->left, op);
    206 	op(node->object);
    207 	rbnode_traverse(node->right, op);
    208 }
    209 
    210 /*
    211  * ***********************************
    212  *
    213  * Operations on rb_tree struct
    214  *
    215  * ***********************************
    216  */
    217 
    218 /* Intialize a tree */
    219 void rbtree_init(rb_tree * tree)
    220 {
    221 /*   tree->comp = comp; */
    222 	tree->isize = 0;
    223 	tree->root = NULL;
    224 }
    225 
    226 /* Construct a tree given a comparison function */
    227 
    228 rb_tree *rbtree_construct()
    229 {
    230 	rb_tree *tree = (rb_tree *) malloc(sizeof(rb_tree));
    231 	if (!tree) {
    232 		fprintf(stderr, "Memory Issue - Shortge Exists!\n");
    233 		return NULL;
    234 	}
    235 	rbtree_init(tree);
    236 	return tree;
    237 }
    238 
    239 /* Remove all objects from a black-red tree */
    240 
    241 void rbtree_clean(rb_tree * tree, destructor d)
    242 {
    243 	if (tree->root)
    244 		rbnode_destruct(tree->root, d);
    245 	tree->root = NULL;
    246 	tree->isize = 0;
    247 }
    248 
    249 /* Destruct a red-black tree */
    250 
    251 void rbtree_destruct(rb_tree * tree, destructor d)
    252 {
    253 	rbtree_clean(tree, d);
    254 	free(tree);
    255 }
    256 
    257 /* Returns the size of the tree */
    258 
    259 int rbtree_size(rb_tree * tree)
    260 {
    261 	return tree->isize;
    262 }
    263 
    264 /* Returns the depth of the tree */
    265 
    266 int rbtree_depth(rb_tree * tree)
    267 {
    268 	if (!(tree->root))
    269 		return 0;
    270 	return rbnode_depth(tree->root);
    271 }
    272 
    273 /* Check whether the tree contains a certain object */
    274 
    275 int rbtree_contains(rb_tree * tree, datatype object)
    276 {
    277 	return (rbtree_find(tree, object) != NULL);
    278 }
    279 
    280 /* Insert an object into the rb-tree */
    281 
    282 rb_node *rbtree_insert(rb_tree * tree, datatype object)
    283 {
    284 	rb_node *cur_node;
    285 	rb_node *new_node;
    286 	int comp_result = 0;
    287 
    288 	if (!(tree->root)) {
    289 		/* Assign a new root node (the root is always
    290 		 * black)
    291 		 */
    292 		new_node = rbnode_construct(object, black);
    293 		if (!new_node)
    294 			return NULL;
    295 		tree->root = new_node;
    296 		tree->isize = 1;
    297 		return new_node;
    298 	}
    299 
    300 	/* Find a spot for the new object, insert the object as a red
    301 	 * leaf
    302 	 */
    303 
    304 	cur_node = tree->root;
    305 	new_node = rbnode_construct(object, red);
    306 	if (!new_node)
    307 		return NULL;
    308 
    309 	while (cur_node) {
    310 		/* Compare inserted object with the object stored in
    311 		 * the current node
    312 		 */
    313 		comp_result = COMP_NODES(object, cur_node->object);
    314 		if (comp_result == 0) {
    315 			printf
    316 			    ("Attempted to insert duplicate node, aborting\n");
    317 			free(new_node);
    318 			return NULL;
    319 		}
    320 		if (comp_result > 0) {
    321 			if (!(cur_node->left)) {
    322 				/* Insert the new leaf as the left
    323 				 * child of the current node
    324 				 */
    325 				cur_node->left = new_node;
    326 				new_node->parent = cur_node;
    327 				cur_node = NULL;	/* Terminate the while loop */
    328 			} else {
    329 				/* Go to the left subtree */
    330 				cur_node = cur_node->left;
    331 			}
    332 		} else {
    333 			if (!(cur_node->right)) {
    334 				/* Insert the new leaf as the right
    335 				 * child of the current node
    336 				 */
    337 				cur_node->right = new_node;
    338 				new_node->parent = cur_node;
    339 				cur_node = NULL;	/* Terminate the while loop */
    340 			} else {
    341 				/* Go to the right subtree */
    342 				cur_node = cur_node->right;
    343 			}
    344 		}
    345 	}
    346 
    347 	/* Mark the fact that a new node was added */
    348 	tree->isize++;
    349 
    350 	/* Fix the tree properties */
    351 	rbtree_insert_fixup(tree, new_node);
    352 
    353 	return new_node;
    354 }
    355 
    356 /* Insert a new object to the tree as the a successor of a given
    357  * node
    358  */
    359 
    360 rb_node *insert_successor_at(rb_tree * tree, rb_node * at_node, datatype object)
    361 {
    362 	rb_node *parent;
    363 	rb_node *new_node;
    364 
    365 	if (!(tree->root)) {
    366 		/* Assign a new root node (the root is always
    367 		 * black)
    368 		 */
    369 		new_node = rbnode_construct(object, black);
    370 		if (!new_node)
    371 			return NULL;
    372 		tree->root = new_node;
    373 		tree->isize = 1;
    374 		return new_node;
    375 	}
    376 
    377 	/* Insert the new object as a red leaf, being the successor of
    378 	 * node
    379 	 */
    380 	new_node = rbnode_construct(object, red);
    381 	if (!new_node)
    382 		return NULL;
    383 
    384 	if (!at_node) {
    385 		/* The new node should become the tree's minimum Place
    386 		 * is as the left child of the current minimal leaf
    387 		 */
    388 		parent = rbnode_minimum(tree->root);
    389 		parent->left = new_node;
    390 	} else {
    391 		/* Make sure the insertion does not violate the tree
    392 		 * order In case given node has no right child, place
    393 		 * the new node as its right child. Otherwise, place
    394 		 * it at the leftmost position at the sub-tree rooted
    395 		 * at its right side.
    396 		 */
    397 		if (!at_node->right) {
    398 			parent = at_node;
    399 			parent->right = new_node;
    400 		} else {
    401 			parent = rbnode_minimum(at_node->right);
    402 			parent->left = new_node;
    403 		}
    404 	}
    405 
    406 	new_node->parent = parent;
    407 
    408 	/* Mark that a new node was added */
    409 	tree->isize++;
    410 
    411 	/* Fix the tree properties */
    412 	rbtree_insert_fixup(tree, new_node);
    413 
    414 	return new_node;
    415 }
    416 
    417 /* Insert a new object to the tree as the a predecessor of a given node */
    418 
    419 rb_node *insert_predecessor_at(rb_tree * tree, rb_node * at_node,
    420 			       datatype object)
    421 {
    422 	rb_node *parent;
    423 	rb_node *new_node;
    424 
    425 	if (!(tree->root)) {
    426 		/* Assign a new root node (the root is always
    427 		 * black)
    428 		 */
    429 		new_node = rbnode_construct(object, black);
    430 		if (!new_node)
    431 			return NULL;
    432 		tree->root = new_node;
    433 		tree->isize = 1;
    434 		return new_node;
    435 	}
    436 
    437 	/* Insert the new object as a red leaf, being the predecessor
    438 	 * of at_node
    439 	 */
    440 	new_node = rbnode_construct(object, red);
    441 	if (!new_node)
    442 		return NULL;
    443 
    444 	if (!at_node) {
    445 		/* The new node should become the tree maximum. Place
    446 		 * is as the right child of the current maximal leaf
    447 		 */
    448 		parent = rbnode_maximum(tree->root);
    449 		parent->right = new_node;
    450 	} else {
    451 		/* Make sure the insertion does not violate the tree
    452 		 * order In case given node has no left child, place
    453 		 * the new node as its left child. Otherwise, place it
    454 		 * at the rightmost position at the sub-tree rooted at
    455 		 * its left side.
    456 		 */
    457 		if (!(at_node->left)) {
    458 			parent = at_node;
    459 			parent->left = new_node;
    460 		} else {
    461 			parent = rbnode_maximum(at_node->left);
    462 			parent->right = new_node;
    463 		}
    464 	}
    465 
    466 	new_node->parent = parent;
    467 
    468 	/* Mark that a new node was added */
    469 	tree->isize++;
    470 
    471 	/* Fix the tree properties */
    472 	rbtree_insert_fixup(tree, new_node);
    473 
    474 	return new_node;
    475 }
    476 
    477 /* Remove an object from the tree */
    478 
    479 void rbtree_remove(rb_tree * tree, datatype object, destructor d)
    480 {
    481 	rb_node *node = rbtree_find(tree, object);	/* Find the node */
    482 	rbtree_remove_at(tree, node, d);	/* Remove the node */
    483 }
    484 
    485 /* Remove the object pointed by the given node. */
    486 
    487 void rbtree_remove_at(rb_tree * tree, rb_node * node, destructor d)
    488 {
    489 	rb_node *child = NULL;
    490 
    491 	/* In case of deleting the single object stored in the tree,
    492 	 * free the root, thus emptying the tree
    493 	 */
    494 	if (tree->isize == 1) {
    495 		rbnode_destruct(tree->root, d);
    496 		tree->root = NULL;
    497 		tree->isize = 0;
    498 		return;
    499 	}
    500 
    501 	/* Remove the given node from the tree */
    502 	if (node->left && node->right) {
    503 		/* If the node we want to remove has two children,
    504 		 * find its successor, which is the leftmost child in
    505 		 * its right sub-tree and has at most one child (it
    506 		 * may have a right child).
    507 		 */
    508 		rb_node *succ_node = rbnode_minimum(node->right);
    509 
    510 		/* Now physically swap node and its successor. Notice
    511 		 * this may temporarily violate the tree properties,
    512 		 * but we are going to remove node anyway.  This way
    513 		 * we have moved node to a position were it is more
    514 		 * convinient to delete it.
    515 		 */
    516 		int immediate_succ = (node->right == succ_node);
    517 		rb_node *succ_parent = succ_node->parent;
    518 		rb_node *succ_left = succ_node->left;
    519 		rb_node *succ_right = succ_node->right;
    520 		rb_color succ_color = succ_node->color;
    521 
    522 		succ_node->parent = node->parent;
    523 		succ_node->left = node->left;
    524 		succ_node->right = immediate_succ ? node : node->right;
    525 		succ_node->color = node->color;
    526 
    527 		node->parent = immediate_succ ? succ_node : succ_parent;
    528 		node->left = succ_left;
    529 		node->right = succ_right;
    530 		node->color = succ_color;
    531 
    532 		if (!immediate_succ) {
    533 			if (succ_node == node->parent->left)
    534 				node->parent->left = node;
    535 			else
    536 				node->parent->right = node;
    537 		}
    538 
    539 		if (node->left)
    540 			node->left->parent = node;
    541 		if (node->right)
    542 			node->right->parent = node;
    543 
    544 		if (succ_node->parent) {
    545 			if (node == succ_node->parent->left)
    546 				succ_node->parent->left = succ_node;
    547 			else
    548 				succ_node->parent->right = succ_node;
    549 		} else {
    550 			tree->root = succ_node;
    551 		}
    552 
    553 		if (succ_node->left)
    554 			succ_node->left->parent = succ_node;
    555 		if (succ_node->right)
    556 			succ_node->right->parent = succ_node;
    557 	}
    558 
    559 	/* At this stage, the node we are going to remove has at most
    560 	 * one child
    561 	 */
    562 	child = (node->left) ? node->left : node->right;
    563 
    564 	/* Splice out the node to be removed, by linking its parent
    565 	 * straight to the removed node's single child.
    566 	 */
    567 	if (child)
    568 		child->parent = node->parent;
    569 
    570 	if (!(node->parent)) {
    571 		/* If we are deleting the root, make the child the new
    572 		 * tree node
    573 		 */
    574 		tree->root = child;
    575 	} else {
    576 		/* Link the removed node parent to its child */
    577 		if (node == node->parent->left)
    578 			node->parent->left = child;
    579 		else
    580 			node->parent->right = child;
    581 	}
    582 
    583 	/* Fix-up the red-black properties that may have been damaged:
    584 	 * If we have just removed a black node, the black-depth
    585 	 * property is no longer valid
    586 	 */
    587 	if (node->color == black && child)
    588 		rbtree_remove_fixup(tree, child);
    589 
    590 	/* Delete the un-necessary node (nullify both its children
    591 	 * because the node's destructor is recursive).
    592 	 */
    593 	node->left = NULL;
    594 	node->right = NULL;
    595 	free(node);
    596 
    597 	/* Decrease the number of objects in the tree */
    598 	tree->isize--;
    599 }
    600 
    601 /* Get the tree minimum */
    602 
    603 rb_node *rbtree_minimum(rb_tree * tree)
    604 {
    605 	if (!(tree->root))
    606 		return NULL;
    607 
    608 	/* Return the leftmost leaf in the tree */
    609 	return rbnode_minimum(tree->root);
    610 }
    611 
    612 /* Get the tree maximum */
    613 
    614 rb_node *rbtree_maximum(rb_tree * tree)
    615 {
    616 	if (!(tree->root))
    617 		return NULL;
    618 
    619 	/* Return the rightmost leaf in the tree */
    620 	return rbnode_maximum(tree->root);
    621 }
    622 
    623 /* Return a pointer to the node containing the given object */
    624 
    625 rb_node *rbtree_find(rb_tree * tree, datatype object)
    626 {
    627 	rb_node *cur_node = tree->root;
    628 	int comp_result;
    629 
    630 	while (cur_node) {
    631 		comp_result = COMP_NODES(object, cur_node->object);
    632 		/* In case of equality, we can return the current
    633 		 * node.
    634 		 */
    635 		if (comp_result == 0)
    636 			return cur_node;
    637 		/* Go down to the left or right child. */
    638 		cur_node = (comp_result > 0) ? cur_node->left : cur_node->right;
    639 	}
    640 
    641 	/* If we get here, the object is not in the tree */
    642 	return NULL;
    643 }
    644 
    645 void rbtree_rotate_left(rb_tree * tree, rb_node * x_node)
    646 {
    647 	/* Get the right child of the node */
    648 	rb_node *y_node = x_node->right;
    649 
    650 	/* Change its left subtree (T2) to x's right subtree */
    651 	x_node->right = y_node->left;
    652 
    653 	/* Link T2 to its new parent x */
    654 	if (y_node->left != NULL)
    655 		y_node->left->parent = x_node;
    656 
    657 	/* Assign x's parent to be y's parent */
    658 	y_node->parent = x_node->parent;
    659 
    660 	if (!(x_node->parent)) {
    661 		/* Make y the new tree root */
    662 		tree->root = y_node;
    663 	} else {
    664 		/* Assign a pointer to y from x's parent */
    665 		if (x_node == x_node->parent->left)
    666 			x_node->parent->left = y_node;
    667 		else
    668 			x_node->parent->right = y_node;
    669 	}
    670 
    671 	/* Assign x to be y's left child */
    672 	y_node->left = x_node;
    673 	x_node->parent = y_node;
    674 }
    675 
    676 /* Right-rotate the sub-tree spanned by the given node */
    677 
    678 void rbtree_rotate_right(rb_tree * tree, rb_node * y_node)
    679 {
    680 	/* Get the left child of the node */
    681 	rb_node *x_node = y_node->left;
    682 
    683 	/* Change its right subtree (T2) to y's left subtree */
    684 	y_node->left = x_node->right;
    685 
    686 	/* Link T2 to its new parent y */
    687 	if (x_node->right != NULL)
    688 		x_node->right->parent = y_node;
    689 
    690 	/* Assign y's parent to be x's parent */
    691 	x_node->parent = y_node->parent;
    692 
    693 	if (!(y_node->parent)) {
    694 		/* Make x the new tree root */
    695 		tree->root = x_node;
    696 	} else {
    697 		/* Assign a pointer to x from y's parent */
    698 		if (y_node == y_node->parent->left)
    699 			y_node->parent->left = x_node;
    700 		else
    701 			y_node->parent->right = x_node;
    702 	}
    703 
    704 	/* Assign y to be x's right child */
    705 	x_node->right = y_node;
    706 	y_node->parent = x_node;
    707 }
    708 
    709 /* Fix the tree so it maintains the red-black properties after an insert */
    710 
    711 void rbtree_insert_fixup(rb_tree * tree, rb_node * node)
    712 {
    713 	/* Fix the red-black propreties. We may have inserted a red
    714 	 * leaf as the child of a red parent - so we have to fix the
    715 	 * coloring of the parent recursively.
    716 	 */
    717 	rb_node *curr_node = node;
    718 	rb_node *grandparent;
    719 	rb_node *uncle;
    720 
    721 	assert(node && node->color == red);
    722 
    723 	while (curr_node != tree->root && curr_node->parent->color == red) {
    724 		/* Get a pointer to the current node's grandparent
    725 		 * (the root is always black, so the red parent must
    726 		 * have a parent).
    727 		 */
    728 
    729 		grandparent = curr_node->parent->parent;
    730 
    731 		if (curr_node->parent == grandparent->left) {
    732 			/* If the red parent is a left child, the
    733 			 * uncle is the right child of the grandparent.
    734 			 */
    735 			uncle = grandparent->right;
    736 
    737 			if (uncle && uncle->color == red) {
    738 
    739 				/* If both parent and uncle are red,
    740 				 * color them black and color the
    741 				 * grandparent red. In case of a NULL
    742 				 * uncle, treat it as a black node
    743 				 */
    744 				curr_node->parent->color = black;
    745 				uncle->color = black;
    746 				grandparent->color = red;
    747 
    748 				/* Move to the grandparent */
    749 				curr_node = grandparent;
    750 			} else {
    751 				/* Make sure the current node is a
    752 				 * right child. If not, left-rotate the
    753 				 * parent's sub-tree so the parent
    754 				 * becomes the right child of the
    755 				 * current node (see _rotate_left).
    756 				 */
    757 				if (curr_node == curr_node->parent->right) {
    758 					curr_node = curr_node->parent;
    759 					rbtree_rotate_left(tree, curr_node);
    760 				}
    761 
    762 				/* Color the parent black and the
    763 				 * grandparent red
    764 				 */
    765 				curr_node->parent->color = black;
    766 				grandparent->color = red;
    767 
    768 				/* Right-rotate the grandparent's
    769 				 * sub-tree
    770 				 */
    771 				rbtree_rotate_right(tree, grandparent);
    772 			}
    773 		} else {
    774 			/* If the red parent is a right child, the
    775 			 * uncle is the left child of the grandparent.
    776 			 */
    777 			uncle = grandparent->left;
    778 
    779 			if (uncle && uncle->color == red) {
    780 				/* If both parent and uncle are red,
    781 				 * color them black and color the
    782 				 * grandparent red. In case of a NULL
    783 				 * uncle, treat it as a black node
    784 				 */
    785 				curr_node->parent->color = black;
    786 				uncle->color = black;
    787 				grandparent->color = red;
    788 
    789 				/* Move to the grandparent */
    790 				curr_node = grandparent;
    791 			} else {
    792 				/* Make sure the current node is a
    793 				 * left child. If not, right-rotate
    794 				 * the parent's sub-tree so the parent
    795 				 * becomes the left child of the
    796 				 * current node.
    797 				 */
    798 				if (curr_node == curr_node->parent->left) {
    799 					curr_node = curr_node->parent;
    800 					rbtree_rotate_right(tree, curr_node);
    801 				}
    802 
    803 				/* Color the parent black and the
    804 				 * grandparent red
    805 				 */
    806 				curr_node->parent->color = black;
    807 				grandparent->color = red;
    808 
    809 				/* Left-rotate the grandparent's
    810 				 * sub-tree
    811 				 */
    812 				rbtree_rotate_left(tree, grandparent);
    813 			}
    814 		}
    815 	}
    816 
    817 	/* Make sure that the root is black */
    818 	tree->root->color = black;
    819 }
    820 
    821 void rbtree_remove_fixup(rb_tree * tree, rb_node * node)
    822 {
    823 	rb_node *curr_node = node;
    824 	rb_node *sibling;
    825 
    826 	while (curr_node != tree->root && curr_node->color == black) {
    827 		/* Get a pointer to the current node's sibling (notice
    828 		 * that the node's parent must exist, since the node
    829 		 * is not the root).
    830 		 */
    831 		if (curr_node == curr_node->parent->left) {
    832 			/* If the current node is a left child, its
    833 			 * sibling is the right child of the parent.
    834 			 */
    835 			sibling = curr_node->parent->right;
    836 
    837 			/* Check the sibling's color. Notice that NULL
    838 			 * nodes are treated as if they are colored
    839 			 * black.
    840 			 */
    841 			if (sibling && sibling->color == red) {
    842 				/* In case the sibling is red, color
    843 				 * it black and rotate.  Then color
    844 				 * the parent red (the grandparent is
    845 				 * now black)
    846 				 */
    847 				sibling->color = black;
    848 				curr_node->parent->color = red;
    849 				rbtree_rotate_left(tree, curr_node->parent);
    850 				sibling = curr_node->parent->right;
    851 			}
    852 
    853 			if (sibling &&
    854 			    (!(sibling->left) || sibling->left->color == black)
    855 			    && (!(sibling->right)
    856 				|| sibling->right->color == black)) {
    857 				/* If the sibling has two black
    858 				 * children, color it red
    859 				 */
    860 				sibling->color = red;
    861 				if (curr_node->parent->color == red) {
    862 					/* If the parent is red, we
    863 					 * can safely color it black
    864 					 * and terminate the fix
    865 					 * process.
    866 					 */
    867 					curr_node->parent->color = black;
    868 					/* In order to stop the while loop */
    869 					curr_node = tree->root;
    870 				} else {
    871 					/* The black depth of the
    872 					 * entire sub-tree rooted at
    873 					 * the parent is now too small
    874 					 * - fix it up recursively.
    875 					 */
    876 					curr_node = curr_node->parent;
    877 				}
    878 			} else {
    879 				if (!sibling) {
    880 					/* Take special care of the
    881 					 * case of a NULL sibling
    882 					 */
    883 					if (curr_node->parent->color == red) {
    884 						curr_node->parent->color =
    885 						    black;
    886 						/* In order to stop
    887 						 * the while loop */
    888 						curr_node = tree->root;
    889 					} else {
    890 						curr_node = curr_node->parent;
    891 					}
    892 				} else {
    893 					/* In this case, at least one
    894 					 * of the sibling's children
    895 					 * is red.  It is therfore
    896 					 * obvious that the sibling
    897 					 * itself is black.
    898 					 */
    899 					if (sibling->right
    900 					    && sibling->right->color == red) {
    901 						/* If the right child
    902 						 * of the sibling is
    903 						 * red, color it black
    904 						 * and rotate around
    905 						 * the current parent.
    906 						 */
    907 						sibling->right->color = black;
    908 						rbtree_rotate_left(tree,
    909 								   curr_node->
    910 								   parent);
    911 					} else {
    912 						/* If the left child
    913 						 * of the sibling is
    914 						 * red, rotate around
    915 						 * the sibling, then
    916 						 * rotate around the
    917 						 * new sibling of our
    918 						 * current node.
    919 						 */
    920 						rbtree_rotate_right(tree,
    921 								    sibling);
    922 						sibling =
    923 						    curr_node->parent->right;
    924 						rbtree_rotate_left(tree,
    925 								   sibling);
    926 					}
    927 
    928 					/* It is now safe to color the
    929 					 * parent black and to
    930 					 * terminate the fix process.
    931 					 */
    932 					if (curr_node->parent->parent)
    933 						curr_node->parent->parent->
    934 						    color =
    935 						    curr_node->parent->color;
    936 					curr_node->parent->color = black;
    937 					/* In order to stop the while loop */
    938 					curr_node = tree->root;
    939 				}
    940 			}
    941 		} else {
    942 			/* If the current node is a right child, its
    943 			 * sibling is the left child of the parent.
    944 			 */
    945 			sibling = curr_node->parent->left;
    946 
    947 			/* Check the sibling's color. Notice that NULL
    948 			 * nodes are treated as if they are colored
    949 			 * black.
    950 			 */
    951 			if (sibling && sibling->color == red) {
    952 				/* In case the sibling is red, color
    953 				 * it black and rotate.  Then color
    954 				 * the parent red (the grandparent is
    955 				 * now black).
    956 				 */
    957 				sibling->color = black;
    958 				curr_node->parent->color = red;
    959 				rbtree_rotate_right(tree, curr_node->parent);
    960 
    961 				sibling = curr_node->parent->left;
    962 			}
    963 
    964 			if (sibling &&
    965 			    (!(sibling->left) || sibling->left->color == black)
    966 			    && (!(sibling->right)
    967 				|| sibling->right->color == black)) {
    968 				/* If the sibling has two black children, color it red */
    969 				sibling->color = red;
    970 				if (curr_node->parent->color == red) {
    971 					/* If the parent is red, we
    972 					 * can safely color it black
    973 					 * and terminate the fix-up
    974 					 * process.
    975 					 */
    976 					curr_node->parent->color = black;
    977 					/* In order to stop the while
    978 					 * loop
    979 					 */
    980 					curr_node = tree->root;
    981 				} else {
    982 					/* The black depth of the
    983 					 * entire sub-tree rooted at
    984 					 * the parent is now too small
    985 					 * - fix it up recursively.
    986 					 */
    987 					curr_node = curr_node->parent;
    988 				}
    989 			} else {
    990 				if (!sibling) {
    991 					/* Take special care of the
    992 					 * case of a NULL sibling */
    993 					if (curr_node->parent->color == red) {
    994 						curr_node->parent->color =
    995 						    black;
    996 						/* In order to stop
    997 						 * the while loop */
    998 						curr_node = tree->root;
    999 					} else {
   1000 						curr_node = curr_node->parent;
   1001 					}
   1002 				} else {
   1003 					/* In this case, at least one
   1004 					 * of the sibling's children is
   1005 					 * red.  It is therfore obvious
   1006 					 * that the sibling itself is
   1007 					 * black.
   1008 					 */
   1009 					if (sibling->left
   1010 					    && sibling->left->color == red) {
   1011 						/* If the left child
   1012 						 * of the sibling is
   1013 						 * red, color it black
   1014 						 * and rotate around
   1015 						 * the current parent
   1016 						 */
   1017 						sibling->left->color = black;
   1018 						rbtree_rotate_right(tree,
   1019 								    curr_node->
   1020 								    parent);
   1021 					} else {
   1022 						/* If the right child
   1023 						 * of the sibling is
   1024 						 * red, rotate around
   1025 						 * the sibling, then
   1026 						 * rotate around the
   1027 						 * new sibling of our
   1028 						 * current node
   1029 						 */
   1030 						rbtree_rotate_left(tree,
   1031 								   sibling);
   1032 						sibling =
   1033 						    curr_node->parent->left;
   1034 						rbtree_rotate_right(tree,
   1035 								    sibling);
   1036 					}
   1037 
   1038 					/* It is now safe to color the
   1039 					 * parent black and to
   1040 					 * terminate the fix process.
   1041 					 */
   1042 					if (curr_node->parent->parent)
   1043 						curr_node->parent->parent->
   1044 						    color =
   1045 						    curr_node->parent->color;
   1046 					curr_node->parent->color = black;
   1047 					/* In order to stop the while loop */
   1048 					curr_node = tree->root;
   1049 				}
   1050 			}
   1051 		}
   1052 	}
   1053 
   1054 	/* The root can always be colored black */
   1055 	curr_node->color = black;
   1056 }
   1057 
   1058 /* Traverse a red-black tree */
   1059 
   1060 void rbtree_traverse(rb_tree * tree, opr * op)
   1061 {
   1062 	rbnode_traverse(tree->root, op);
   1063 }
   1064