summaryrefslogtreecommitdiff
path: root/usr.bin/sudo/redblack.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/sudo/redblack.c')
-rw-r--r--usr.bin/sudo/redblack.c93
1 files changed, 40 insertions, 53 deletions
diff --git a/usr.bin/sudo/redblack.c b/usr.bin/sudo/redblack.c
index eba310a4427..555e9385f30 100644
--- a/usr.bin/sudo/redblack.c
+++ b/usr.bin/sudo/redblack.c
@@ -18,6 +18,8 @@
* Adapted from the following code written by Emin Martinian:
* http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
*
+ * Copyright (c) 2001 Emin Martinian
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that neither the name of Emin
* Martinian nor the names of any contributors are be used to endorse or
@@ -56,7 +58,7 @@
#include "redblack.h"
#ifndef lint
-__unused static const char rcsid[] = "$Sudo: redblack.c,v 1.8 2008/11/09 14:13:12 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: redblack.c,v 1.10 2008/11/22 15:01:25 millert Exp $";
#endif /* lint */
static void rbrepair __P((struct rbtree *, struct rbnode *));
@@ -367,59 +369,45 @@ rbdestroy(tree, destroy)
}
/*
- * Delete victim from tree and return its data pointer.
+ * Delete node 'z' from the tree and return its data pointer.
*/
-void *
-rbdelete(tree, victim)
- struct rbtree *tree;
- struct rbnode *victim;
+void *rbdelete(tree, z)
+ struct rbtree* tree;
+ struct rbnode* z;
{
- struct rbnode *pred, *succ;
- void *data;
+ struct rbnode *x, *y;
+ void *data = z->data;
- if (victim->left != rbnil(tree) && victim->right != rbnil(tree)) {
- succ = rbsuccessor(tree, victim);
- pred = succ->left == rbnil(tree) ? succ->right : succ->left;
- if (succ->parent == rbroot(tree)) {
- pred->parent = rbroot(tree);
- rbfirst(tree) = pred;
- } else {
- if (succ == succ->parent->left)
- succ->parent->left = pred;
- else
- succ->parent->right = pred;
- }
- if ((succ->color == black))
- rbrepair(tree, pred);
-
- succ->left = victim->left;
- succ->right = victim->right;
- succ->parent = victim->parent;
- succ->color = victim->color;
- victim->left->parent = victim->right->parent = succ;
- if (victim == victim->parent->left)
- victim->parent->left = succ;
- else
- victim->parent->right = succ;
- data = victim->data;
- efree(victim);
+ if (z->left == rbnil(tree) || z->right == rbnil(tree))
+ y = z;
+ else
+ y = rbsuccessor(tree, z);
+ x = (y->left == rbnil(tree)) ? y->right : y->left;
+
+ if ((x->parent = y->parent) == rbroot(tree)) {
+ rbfirst(tree) = x;
} else {
- pred = victim->left == rbnil(tree) ? victim->right : victim->left;
- if (victim->parent == rbroot(tree)) {
- pred->parent = rbroot(tree);
- rbfirst(tree) = pred;
- } else {
- if (victim == victim->parent->left)
- victim->parent->left = pred;
- else
- victim->parent->right = pred;
- }
- if (victim->color == black)
- rbrepair(tree, pred);
- data = victim->data;
- efree(victim);
+ if (y == y->parent->left)
+ y->parent->left = x;
+ else
+ y->parent->right = x;
+ }
+ if (y->color == black)
+ rbrepair(tree, x);
+ if (y != z) {
+ y->left = z->left;
+ y->right = z->right;
+ y->parent = z->parent;
+ y->color = z->color;
+ z->left->parent = z->right->parent = y;
+ if (z == z->parent->left)
+ z->parent->left = y;
+ else
+ z->parent->right = y;
}
- return(data);
+ free(z);
+
+ return (data);
}
/*
@@ -433,7 +421,7 @@ rbrepair(tree, node)
{
struct rbnode *sibling;
- while (node->color == black && node != rbfirst(tree)) {
+ while (node->color == black) {
if (node == node->parent->left) {
sibling = node->parent->right;
if (sibling->color == red) {
@@ -456,7 +444,7 @@ rbrepair(tree, node)
node->parent->color = black;
sibling->right->color = black;
rotate_left(tree, node->parent);
- return; /* XXX */
+ break;
}
} else { /* if (node == node->parent->right) */
sibling = node->parent->left;
@@ -480,9 +468,8 @@ rbrepair(tree, node)
node->parent->color = black;
sibling->left->color = black;
rotate_right(tree, node->parent);
- return; /* XXX */
+ break;
}
}
}
- node->color = black;
}