Archived
1
0
Fork 0

test/t_rbtree.c: properly rewritten.

This commit is contained in:
Henrik Hautakoski 2011-01-03 10:49:11 +01:00
parent 246ea7854e
commit 2c54173a52

View file

@ -11,14 +11,18 @@
#include "unit.h" #include "unit.h"
#include "../src/rbtree.h" #include "../src/rbtree.h"
#define MAX_VAL 500 #define NODES 3000
#define NODES 20 #define MAX_VAL (3*(NODES/4))
#define is_red(n) ((n) != NULL && (n)->color == RB_RED) #define is_red(n) ((n) != NULL && (n)->color == RB_RED)
static int vcmp(const void *a, const void *b); static int vcmp(const void *a, const void *b);
static void vdelete(void *ptr); static void vdelete(void *ptr);
/* data */
static rbtree tree = RBTREE_INIT(vdelete, NULL, vcmp);
static int keyref[NODES];
static int rb_assert(rbnode *node) { static int rb_assert(rbnode *node) {
int rh, lh; int rh, lh;
@ -61,10 +65,6 @@ static int rb_assert(rbnode *node) {
return 0; return 0;
} }
/* data */
static rbtree tree = RBTREE_INIT(vdelete, NULL, vcmp);
static int keyref[NODES];
static int vcmp(const void *a, const void *b) { static int vcmp(const void *a, const void *b) {
return *((int*)a) - *((int*)b); return *((int*)a) - *((int*)b);
@ -72,141 +72,166 @@ static int vcmp(const void *a, const void *b) {
static void vdelete(void *ptr) { static void vdelete(void *ptr) {
int i; int i, exists = 0;
printf("delete: %i\n", *((int*)ptr));
for(i=0; i < NODES; i++) { for(i=0; i < NODES; i++) {
if (keyref[i] == -1)
continue;
if (ptr == &keyref[i]) { if (ptr == &keyref[i]) {
keyref[i] = -1; exists = 1;
break; break;
} }
} }
assert(exists);
} }
static void vwalk(rbnode *node) { /* Helper, will check keyref to see if 'value' exist in the range */
static int keyref_exists(int low, int high, int value) {
int i, found = 0; for(; low <= high; low++)
if (keyref[low] == value)
/* check if this node exist in the reference list */ return 1;
for(i=0; i < NODES; i++) { return 0;
if (node->key == &keyref[i]) {
found = 1;
break;
}
}
assert(found);
} }
void test_insert() { static void walk_fn(rbnode *n) {
int i = 0; static int i = 0;
/* insert values */
while(i < NODES) {
rbnode *node; while(keyref_exists(0, i-1, keyref[i]))
keyref[i] = (uint) (rand() % MAX_VAL);
/* insert into rbtree and assert it */
node = rbtree_insert(&tree, &keyref[i]);
rb_assert(tree.root);
assert(node);
printf("insert: %i\n", *((int*)node->key));
i++; i++;
}
rb_assert(tree.root); assert(keyref[i] == *((int*)n->key));
if (++i > NODES)
i = 0;
} }
void test_delete() { static void setup(int sorted) {
int i, key; int i;
/* remove some values */
for(i=0; i < 10; i++) {
do
key = keyref[rand() % NODES];
while(key < 0);
rbtree_delete(&tree, &key);
rb_assert(tree.root);
keyref[key] = -1;
}
}
void test_search() {
int index;
int *n;
do
index = rand() % NODES;
while(keyref[index] < 0);
printf("search: expecting to find key %i\n", keyref[index]);
/* search for a key we know exists */
n = rbtree_search(&tree, &keyref[index]);
rb_assert(tree.root);
assert(n == &keyref[index]);
index = MAX_VAL + 512;
printf("search: expecting to not find key: %i\n", index);
/* search for a key we now don't exist */
n = rbtree_search(&tree, &index);
rb_assert(tree.root);
assert(n == NULL);
}
void test_walk() {
rbtree_walk(&tree, vwalk);
rb_assert(tree.root);
}
int main(int argc, char **argv) {
tree.root = NULL;
utest_init_RNG(); utest_init_RNG();
/* a new tree is empty */
assert(rbtree_is_empty(&tree));
test_insert(); for(i=0; i < NODES; i++)
keyref[i] = rand() % MAX_VAL;
test_search();
test_walk();
test_delete();
test_search();
test_walk();
/* free the tree */ if (sorted)
rbtree_free(&tree); qsort(keyref, NODES, sizeof(keyref[0]), vcmp);
/* tree is now empty again */ for(i=0; i < NODES; i++) {
assert(rbtree_is_empty(&tree)); rbtree_insert(&tree, &keyref[i]);
rb_assert(tree.root);
printf("-- TEST PASS --\n"); }
}
return 0;
static void teardown() {
int i;
rbtree_free(&tree);
rb_assert(tree.root);
for(i=0; i < NODES; i++)
keyref[i] = -1;
}
void test_rbtree_is_empty() {
setup(0);
assert(rbtree_is_empty(&tree) == 0);
rb_assert(tree.root);
rbtree_free(&tree);
rb_assert(tree.root);
assert(rbtree_is_empty(&tree));
rb_assert(tree.root);
teardown();
}
void test_rbtree_delete() {
int i;
setup(0);
for(i=NODES/2; i < 3*(NODES/4); i++) {
if (keyref_exists(NODES/2, i-1, keyref[i]))
continue;
assert(rbtree_delete(&tree, &keyref[i]));
rb_assert(tree.root);
}
/* delete a key that does not exist */
i = MAX_VAL + 512;
assert(rbtree_delete(&tree, &i) == 0);
rb_assert(tree.root);
teardown();
}
void test_rbtree_delete_all() {
int i;
setup(0);
for(i=0; i < NODES; i++) {
if (keyref_exists(0, i-1, keyref[i]))
continue;
assert(rbtree_delete(&tree, &keyref[i]));
rb_assert(tree.root);
}
assert(rbtree_is_empty(&tree));
rb_assert(tree.root);
teardown();
}
void test_rbtree_walk() {
setup(1);
rbtree_walk(&tree, walk_fn);
rb_assert(tree.root);
teardown();
}
void test_rbtree_search() {
int s, *f;
setup(0);
s = keyref[NODES/2];
f = rbtree_search(&tree, &s);
rb_assert(tree.root);
assert(f && *f == s);
s = MAX_VAL + 512;
f = rbtree_search(&tree, &s);
rb_assert(tree.root);
assert(f == NULL);
teardown();
}
int main() {
test_rbtree_delete();
test_rbtree_delete_all();
test_rbtree_search();
test_rbtree_is_empty();
test_rbtree_walk();
return 0;
} }