Archived
1
0
Fork 0

rbtree.c: moved tree assertion from the test.

This commit is contained in:
Henrik Hautakoski 2011-01-07 10:53:08 +01:00
parent 50c53e79bf
commit 41a253a00a
2 changed files with 75 additions and 64 deletions

View file

@ -12,6 +12,10 @@
*/
#include <stdlib.h>
#include <string.h>
#ifdef __DEBUG__
#include <assert.h>
#include <stdio.h>
#endif
#include "xalloc.h"
#include "rbtree.h"
@ -47,6 +51,60 @@ static void node_dealloc(rbnode *n, void (*dealloc)(void *)) {
free(n);
}
#ifdef __DEBUG__
#define rb_err(msg) fputs("rbtree error: " msg, stderr)
static int rb_assert_r(rbnode *node, int (*cmp)(const void *, const void *)) {
int rh, lh;
rbnode *ln, *rn;
if (node == NULL)
return 1;
ln = node->child[0];
rn = node->child[1];
if (is_red(node)) {
/* double red violation */
if (is_red(ln) || is_red(rn)) {
rb_err("Double red violation");
return 0;
}
}
lh = rb_assert_r(ln, cmp);
rh = rb_assert_r(rn, cmp);
if ( (ln && cmp(ln->key, node->key) >= 0) &&
(rn && cmp(rn->key, node->key) <= 0) ) {
rb_err("Binary tree violation");
return 0;
}
if (rh != 0 && lh != 0) {
if (rh != lh) {
rb_err("Black height violation");
return 0;
}
return is_red(node) ? lh : lh+1;
}
return 0;
}
#undef rb_err
static void rb_assert(rbtree *tree) {
if (!tree || !tree->cmp_fn)
return;
assert(rb_assert_r(tree->root, tree->cmp_fn));
}
#endif /* __DEBUG__ */
/*
* Recursivly walks a tree, applying action function on every node
*/
@ -112,6 +170,10 @@ void rbtree_walk(rbtree *tree, void (*action)(const void *)) {
return;
rbwalk(tree->root, action);
#ifdef __DEBUG__
rb_assert(tree);
#endif
}
void rbtree_free(rbtree *tree) {
@ -121,6 +183,10 @@ void rbtree_free(rbtree *tree) {
node_dealloc(tree->root, tree->delete_fn);
tree->root = NULL;
#ifdef __DEBUG__
rb_assert(tree);
#endif
}
int rbtree_insert(rbtree *tree, const void *key) {
@ -196,6 +262,10 @@ done:
/* root should be black */
tree->root->color = RB_BLACK;
#ifdef __DEBUG__
rb_assert(tree);
#endif
return 1;
}
@ -276,5 +346,9 @@ int rbtree_delete(rbtree *tree, const void *key) {
if (tree->root)
tree->root->color = RB_BLACK;
#ifdef __DEBUG__
rb_assert(tree);
#endif
return f != NULL;
}