#include <stdio.h>
#include <netdb.h>
-#include <freeradius-devel/util/base.h>
+#include <freeradius-devel/util/rbtree.c>
+#include <freeradius-devel/util/rand.h>
-/*
- * We need knowlege of the internal structures.
- * This needs to be kept in lockstep with rbtree.c
- */
-
-struct rbnode_s {
- fr_rb_node_t *left; //!< left child
- fr_rb_node_t *right; //!< right child
- fr_rb_node_t *parent; //!< Parent
- fr_rb_colour_t colour; //!< Node colour (BLACK, RED)
- void *data; //!< data stored in node
-};
-
-struct rbtree_s {
-#ifndef NDEBUG
- uint32_t magic;
-#endif
- fr_rb_node_t *root;
- int num_elements;
- fr_rb_cmp_t compare;
- fr_rb_free_t free;
- bool replace;
- bool lock;
- pthread_mutex_t mutex;
-};
-
-/* Storage for the NIL pointer. */
-static fr_rb_node_t *NIL;
+typedef struct {
+ uint32_t num;
+ fr_rb_node_t node;
+} fr_rb_test_node_t;
static int comp(void const *a, void const *b)
{
- if (*(uint32_t const *)a > *(uint32_t const *)b) {
- return -1;
- }
+ fr_rb_test_node_t const *our_a = a, *our_b = b;
- if (*(uint32_t const *)a < *(uint32_t const *)b) {
- return 1;
- }
- return 0;
+ return (our_a->num > our_b->num) - (our_a->num < our_b->num);
}
#if 0
static int print_cb(void *i, UNUSED void *uctx)
{
- fprintf(stderr, "%i\n", *(int*)i);
+ fprintf(stderr, "%i\n", (fr_rb_test_node_t *)i->num);
return 0;
}
#endif
#define MAXSIZE 1024
static int cb_stored = 0;
-static uint32_t rvals[MAXSIZE];
+static fr_rb_test_node_t rvals[MAXSIZE];
static int store_cb(void *i, UNUSED void *uctx)
{
- rvals[cb_stored++] = *(int const *)i;
+ rvals[cb_stored++].num = *(int const *)i;
return 0;
}
static int filter_cb(void *i, void *uctx)
{
- if ((*(uint32_t *)i & mask) == (*(uint32_t *)uctx & mask)) {
+ if ((((fr_rb_test_node_t *)i)->num & mask) == (((fr_rb_test_node_t *)uctx)->num & mask)) {
return 2;
}
return 0;
}
n = n->right;
}
- if (n->left != NIL || n->right != NIL) {
+ if ((n->left != NIL) || (n->right != NIL)) {
goto descend;
}
if (count_expect < 0) {
int main(UNUSED int argc, UNUSED char *argv[])
{
- rbtree_t *t;
- int i, j;
- uint32_t thresh;
- int n, rep;
- uint32_t vals[MAXSIZE];
+ rbtree_t *t;
+ int i, j;
+ uint32_t thresh;
+ int n, rep;
+ fr_rb_test_node_t vals[MAXSIZE];
+
+ memset(&vals, 0, sizeof(vals));
/* TODO: make starting seed and repetitions a CLI option */
rep = REPS;
thresh &= mask;
n = (fr_rand() % MAXSIZE) + 1;
- fprintf(stderr, "filter = %x mask = %x n= %i\n",
- thresh, mask, n);
+ fprintf(stderr, "filter = %x mask = %x n = %i\n", thresh, mask, n);
t = rbtree_alloc(NULL, comp, freenode, RBTREE_FLAG_LOCK);
- /* Find out the value of the NIL node */
- NIL = t->root->left;
-
for (i = 0; i < n; i++) {
- int *p;
- p = talloc(t, int);
- *p = fr_rand();
- vals[i] = *p;
+ fr_rb_test_node_t *p;
+
+ p = talloc(t, fr_rb_test_node_t); /* Do not use talloc_zero, rbcode should initialise fr_rb_node_t */
+ p->num = fr_rand();
+ vals[i].num = p->num;
rbtree_insert(t, p);
}
i = rbcount(t);
- fprintf(stderr,"After insert rbcount is %i.\n", i);
- if (i < 0) { return i; }
+ fprintf(stderr,"After insert rbcount is %i\n", i);
+ if (i < 0) return i;
- qsort(vals, n, sizeof(int), comp);
+ qsort(vals, n, sizeof(fr_rb_test_node_t), comp);
/*
* For testing deletebydata instead
for (i = 0; i < n; i++) {
- if (filter_cb(&vals[i], &thresh) == 2) {
- rbtree_deletebydata(t, &vals[i]);
- }
+ if (filter_cb(&vals[i], &thresh) == 2) rbtree_deletebydata(t, &vals[i]);
}
*
*/
(void) rbtree_walk(t, RBTREE_DELETE_ORDER, filter_cb, &thresh);
i = rbcount(t);
- fprintf(stderr,"After delete rbcount is %i.\n", i);
- if (i < 0) { return i; }
+ fprintf(stderr,"After delete rbcount is %i\n", i);
+ if (i < 0) return i;
cb_stored = 0;
rbtree_walk(t, RBTREE_IN_ORDER, &store_cb, NULL);
for (j = i = 0; i < n; i++) {
- if (i && vals[i-1] == vals[i]) continue;
+ if (i && vals[i-1].num == vals[i].num) continue;
if (!filter_cb(&thresh, &vals[i])) {
- if (vals[i] != rvals[j]) goto bad;
+ if (vals[i].num != rvals[j].num) goto bad;
j++;
}
}
bad:
for (j = i = 0; i < n; i++) {
- if (i && vals[i-1] == vals[i]) continue;
+ if (i && vals[i-1].num == vals[i].num) continue;
if (!filter_cb(&thresh, &vals[i])) {
- fprintf(stderr, "%i: %x %x\n", j, vals[i], rvals[j]);
+ fprintf(stderr, "%i: %x %x\n", j, vals[i].num, rvals[j].num);
j++;
} else {
- fprintf(stderr, "skipped %x\n", vals[i]);
+ fprintf(stderr, "skipped %x\n", vals[i].num);
}
}
return -1;