version 1.1.1.1, 2012/02/21 16:23:02
|
version 1.1.1.2, 2012/05/29 12:26:49
|
Line 57
|
Line 57
|
|
|
#include "missing.h" |
#include "missing.h" |
#include "alloc.h" |
#include "alloc.h" |
|
#include "sudo_debug.h" |
#include "redblack.h" |
#include "redblack.h" |
|
|
static void rbrepair(struct rbtree *, struct rbnode *); |
static void rbrepair(struct rbtree *, struct rbnode *); |
Line 90 struct rbtree *
|
Line 91 struct rbtree *
|
rbcreate(int (*compar)(const void *, const void*)) |
rbcreate(int (*compar)(const void *, const void*)) |
{ |
{ |
struct rbtree *tree; |
struct rbtree *tree; |
|
debug_decl(rbcreate, SUDO_DEBUG_RBTREE) |
|
|
tree = (struct rbtree *) emalloc(sizeof(*tree)); |
tree = (struct rbtree *) emalloc(sizeof(*tree)); |
tree->compar = compar; |
tree->compar = compar; |
Line 110 rbcreate(int (*compar)(const void *, const void*))
|
Line 112 rbcreate(int (*compar)(const void *, const void*))
|
tree->root.color = black; |
tree->root.color = black; |
tree->root.data = NULL; |
tree->root.data = NULL; |
|
|
return tree; | debug_return_ptr(tree); |
} |
} |
|
|
/* |
/* |
Line 120 static void
|
Line 122 static void
|
rotate_left(struct rbtree *tree, struct rbnode *node) |
rotate_left(struct rbtree *tree, struct rbnode *node) |
{ |
{ |
struct rbnode *child; |
struct rbnode *child; |
|
debug_decl(rotate_left, SUDO_DEBUG_RBTREE) |
|
|
child = node->right; |
child = node->right; |
node->right = child->left; |
node->right = child->left; |
Line 134 rotate_left(struct rbtree *tree, struct rbnode *node)
|
Line 137 rotate_left(struct rbtree *tree, struct rbnode *node)
|
node->parent->right = child; |
node->parent->right = child; |
child->left = node; |
child->left = node; |
node->parent = child; |
node->parent = child; |
|
|
|
debug_return; |
} |
} |
|
|
/* |
/* |
Line 143 static void
|
Line 148 static void
|
rotate_right(struct rbtree *tree, struct rbnode *node) |
rotate_right(struct rbtree *tree, struct rbnode *node) |
{ |
{ |
struct rbnode *child; |
struct rbnode *child; |
|
debug_decl(rotate_right, SUDO_DEBUG_RBTREE) |
|
|
child = node->left; |
child = node->left; |
node->left = child->right; |
node->left = child->right; |
Line 157 rotate_right(struct rbtree *tree, struct rbnode *node)
|
Line 163 rotate_right(struct rbtree *tree, struct rbnode *node)
|
node->parent->right = child; |
node->parent->right = child; |
child->right = node; |
child->right = node; |
node->parent = child; |
node->parent = child; |
|
|
|
debug_return; |
} |
} |
|
|
/* |
/* |
Line 170 rbinsert(struct rbtree *tree, void *data)
|
Line 178 rbinsert(struct rbtree *tree, void *data)
|
struct rbnode *node = rbfirst(tree); |
struct rbnode *node = rbfirst(tree); |
struct rbnode *parent = rbroot(tree); |
struct rbnode *parent = rbroot(tree); |
int res; |
int res; |
|
debug_decl(rbinsert, SUDO_DEBUG_RBTREE) |
|
|
/* Find correct insertion point. */ |
/* Find correct insertion point. */ |
while (node != rbnil(tree)) { |
while (node != rbnil(tree)) { |
parent = node; |
parent = node; |
if ((res = tree->compar(data, node->data)) == 0) |
if ((res = tree->compar(data, node->data)) == 0) |
return node; | debug_return_ptr(node); |
node = res < 0 ? node->left : node->right; |
node = res < 0 ? node->left : node->right; |
} |
} |
|
|
Line 249 rbinsert(struct rbtree *tree, void *data)
|
Line 258 rbinsert(struct rbtree *tree, void *data)
|
} |
} |
} |
} |
rbfirst(tree)->color = black; /* first node is always black */ |
rbfirst(tree)->color = black; /* first node is always black */ |
return NULL; | debug_return_ptr(NULL); |
} |
} |
|
|
/* |
/* |
Line 261 rbfind(struct rbtree *tree, void *key)
|
Line 270 rbfind(struct rbtree *tree, void *key)
|
{ |
{ |
struct rbnode *node = rbfirst(tree); |
struct rbnode *node = rbfirst(tree); |
int res; |
int res; |
|
debug_decl(rbfind, SUDO_DEBUG_RBTREE) |
|
|
while (node != rbnil(tree)) { |
while (node != rbnil(tree)) { |
if ((res = tree->compar(key, node->data)) == 0) |
if ((res = tree->compar(key, node->data)) == 0) |
return node; | debug_return_ptr(node); |
node = res < 0 ? node->left : node->right; |
node = res < 0 ? node->left : node->right; |
} |
} |
return NULL; | debug_return_ptr(NULL); |
} |
} |
|
|
/* |
/* |
Line 280 rbapply_node(struct rbtree *tree, struct rbnode *node,
|
Line 290 rbapply_node(struct rbtree *tree, struct rbnode *node,
|
int (*func)(void *, void *), void *cookie, enum rbtraversal order) |
int (*func)(void *, void *), void *cookie, enum rbtraversal order) |
{ |
{ |
int error; |
int error; |
|
debug_decl(rbapply_node, SUDO_DEBUG_RBTREE) |
|
|
if (node != rbnil(tree)) { |
if (node != rbnil(tree)) { |
if (order == preorder) |
if (order == preorder) |
if ((error = func(node->data, cookie)) != 0) |
if ((error = func(node->data, cookie)) != 0) |
return error; | debug_return_int(error); |
if ((error = rbapply_node(tree, node->left, func, cookie, order)) != 0) |
if ((error = rbapply_node(tree, node->left, func, cookie, order)) != 0) |
return error; | debug_return_int(error); |
if (order == inorder) |
if (order == inorder) |
if ((error = func(node->data, cookie)) != 0) |
if ((error = func(node->data, cookie)) != 0) |
return error; | debug_return_int(error); |
if ((error = rbapply_node(tree, node->right, func, cookie, order)) != 0) |
if ((error = rbapply_node(tree, node->right, func, cookie, order)) != 0) |
return error; | debug_return_int(error); |
if (order == postorder) |
if (order == postorder) |
if ((error = func(node->data, cookie)) != 0) |
if ((error = func(node->data, cookie)) != 0) |
return error; | debug_return_int(error); |
} |
} |
return 0; | debug_return_int(0); |
} |
} |
|
|
/* |
/* |
Line 306 static struct rbnode *
|
Line 317 static struct rbnode *
|
rbsuccessor(struct rbtree *tree, struct rbnode *node) |
rbsuccessor(struct rbtree *tree, struct rbnode *node) |
{ |
{ |
struct rbnode *succ; |
struct rbnode *succ; |
|
debug_decl(rbsuccessor, SUDO_DEBUG_RBTREE) |
|
|
if ((succ = node->right) != rbnil(tree)) { |
if ((succ = node->right) != rbnil(tree)) { |
while (succ->left != rbnil(tree)) |
while (succ->left != rbnil(tree)) |
Line 317 rbsuccessor(struct rbtree *tree, struct rbnode *node)
|
Line 329 rbsuccessor(struct rbtree *tree, struct rbnode *node)
|
if (succ == rbroot(tree)) |
if (succ == rbroot(tree)) |
succ = rbnil(tree); |
succ = rbnil(tree); |
} |
} |
return succ; | debug_return_ptr(succ); |
} |
} |
|
|
/* |
/* |
Line 326 rbsuccessor(struct rbtree *tree, struct rbnode *node)
|
Line 338 rbsuccessor(struct rbtree *tree, struct rbnode *node)
|
static void |
static void |
_rbdestroy(struct rbtree *tree, struct rbnode *node, void (*destroy)(void *)) |
_rbdestroy(struct rbtree *tree, struct rbnode *node, void (*destroy)(void *)) |
{ |
{ |
|
debug_decl(_rbdestroy, SUDO_DEBUG_RBTREE) |
if (node != rbnil(tree)) { |
if (node != rbnil(tree)) { |
_rbdestroy(tree, node->left, destroy); |
_rbdestroy(tree, node->left, destroy); |
_rbdestroy(tree, node->right, destroy); |
_rbdestroy(tree, node->right, destroy); |
Line 333 _rbdestroy(struct rbtree *tree, struct rbnode *node, v
|
Line 346 _rbdestroy(struct rbtree *tree, struct rbnode *node, v
|
destroy(node->data); |
destroy(node->data); |
efree(node); |
efree(node); |
} |
} |
|
debug_return; |
} |
} |
|
|
/* |
/* |
Line 342 _rbdestroy(struct rbtree *tree, struct rbnode *node, v
|
Line 356 _rbdestroy(struct rbtree *tree, struct rbnode *node, v
|
void |
void |
rbdestroy(struct rbtree *tree, void (*destroy)(void *)) |
rbdestroy(struct rbtree *tree, void (*destroy)(void *)) |
{ |
{ |
|
debug_decl(rbdestroy, SUDO_DEBUG_RBTREE) |
_rbdestroy(tree, rbfirst(tree), destroy); |
_rbdestroy(tree, rbfirst(tree), destroy); |
efree(tree); |
efree(tree); |
|
debug_return; |
} |
} |
|
|
/* |
/* |
Line 353 void *rbdelete(struct rbtree *tree, struct rbnode *z)
|
Line 369 void *rbdelete(struct rbtree *tree, struct rbnode *z)
|
{ |
{ |
struct rbnode *x, *y; |
struct rbnode *x, *y; |
void *data = z->data; |
void *data = z->data; |
|
debug_decl(rbdelete, SUDO_DEBUG_RBTREE) |
|
|
if (z->left == rbnil(tree) || z->right == rbnil(tree)) |
if (z->left == rbnil(tree) || z->right == rbnil(tree)) |
y = z; |
y = z; |
Line 383 void *rbdelete(struct rbtree *tree, struct rbnode *z)
|
Line 400 void *rbdelete(struct rbtree *tree, struct rbnode *z)
|
} |
} |
free(z); |
free(z); |
|
|
return data; | debug_return_ptr(data); |
} |
} |
|
|
/* |
/* |
Line 394 static void
|
Line 411 static void
|
rbrepair(struct rbtree *tree, struct rbnode *node) |
rbrepair(struct rbtree *tree, struct rbnode *node) |
{ |
{ |
struct rbnode *sibling; |
struct rbnode *sibling; |
|
debug_decl(rbrepair, SUDO_DEBUG_RBTREE) |
|
|
while (node->color == black && node != rbroot(tree)) { |
while (node->color == black && node != rbroot(tree)) { |
if (node == node->parent->left) { |
if (node == node->parent->left) { |
Line 447 rbrepair(struct rbtree *tree, struct rbnode *node)
|
Line 465 rbrepair(struct rbtree *tree, struct rbnode *node)
|
} |
} |
} |
} |
node->color = black; |
node->color = black; |
|
|
|
debug_return; |
} |
} |