39 static void *rbtree_first(
struct RB_TRAV *);
40 static void *rbtree_last(
struct RB_TRAV *trav);
41 static void *rbtree_next(
struct RB_TRAV *);
42 static void *rbtree_previous(
struct RB_TRAV *);
43 static struct RB_NODE *rbtree_make_node(
size_t,
void *);
44 static int is_red(
struct RB_NODE *);
84 struct RB_NODE head = {0, 0, {0, 0}};
87 int dir = 0, last = 0;
92 q =
t->link[1] = tree->
root;
102 else if (is_red(q->
link[0]) && is_red(q->
link[1])) {
110 if (is_red(q) && is_red(p)) {
111 int dir2 =
t->link[1] ==
g;
113 if (q == p->
link[last])
114 t->link[dir2] = rbtree_single(
g, !last);
116 t->link[dir2] = rbtree_double(
g, !last);
156 struct RB_NODE head = {0, 0, {0, 0}};
159 int dir = 1, removed = 0;
188 if (!is_red(q) && !is_red(q->
link[dir])) {
189 if (is_red(q->
link[!dir]))
190 p = p->
link[last] = rbtree_single(q, dir);
191 else if (!is_red(q->
link[!dir])) {
195 if (!is_red(s->
link[!last]) && !is_red(s->
link[last])) {
202 int dir2 =
g->link[1] == p;
204 if (is_red(s->
link[last]))
205 g->link[dir2] = rbtree_double(p, last);
206 else if (is_red(s->
link[!last]))
207 g->link[dir2] = rbtree_single(p, last);
210 q->
red =
g->link[dir2]->red = 1;
211 g->link[dir2]->link[0]->red = 0;
212 g->link[dir2]->link[1]->red = 0;
230 G_debug(2,
"RB tree: data not found in search tree");
250 while (curr_node !=
NULL) {
253 return curr_node->
data;
255 curr_node = curr_node->
link[cmp < 0];
287 G_debug(1,
"RB tree: empty tree");
289 G_debug(1,
"RB tree: finished traversing");
295 return rbtree_next(trav);
298 return rbtree_first(trav);
313 G_debug(1,
"RB tree: empty tree");
315 G_debug(1,
"RB tree: finished traversing");
321 return rbtree_previous(trav);
324 return rbtree_last(trav);
345 G_warning(
"RB tree: finished traversing");
351 return rbtree_next(trav);
390 static void *rbtree_first(
struct RB_TRAV *trav)
404 static void *rbtree_last(
struct RB_TRAV *trav)
418 void *rbtree_next(
struct RB_TRAV *trav)
436 if (trav->
top == 0) {
455 void *rbtree_previous(
struct RB_TRAV *trav)
473 if (trav->
top == 0) {
500 while ((it = save) !=
NULL) {
539 int lcmp = 0, rcmp = 0;
543 if (is_red(ln) || is_red(rn)) {
544 G_warning(
"Red Black Tree debugging: Red violation");
562 if ((ln !=
NULL && lcmp > -1) || (rn !=
NULL && rcmp < 1)) {
563 G_warning(
"Red Black Tree debugging: Binary tree violation");
568 if (lh != 0 && rh != 0 && lh != rh) {
569 G_warning(
"Red Black Tree debugging: Black violation");
574 if (lh != 0 && rh != 0)
575 return is_red(root) ? lh : lh + 1;
588 static struct RB_NODE *rbtree_make_node(
size_t datasize,
void *
data)
592 if (new_node ==
NULL)
599 memcpy(new_node->
data,
data, datasize);
608 static int is_red(
struct RB_NODE *root)
611 return root->
red == 1;
617 static struct RB_NODE *rbtree_single(
struct RB_NODE *root,
int dir)
621 root->
link[!dir] = newroot->
link[dir];
622 newroot->
link[dir] = root;
631 static struct RB_NODE *rbtree_double(
struct RB_NODE *root,
int dir)
633 root->
link[!dir] = rbtree_single(root->
link[!dir], !dir);
634 return rbtree_single(root, dir);
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
int compare(const void *a, const void *b)
#define assert(condition)
void rbtree_destroy(struct RB_TREE *tree)
int rbtree_remove(struct RB_TREE *tree, const void *data)
int rbtree_debug(struct RB_TREE *tree, struct RB_NODE *root)
void * rbtree_traverse_backwd(struct RB_TRAV *trav)
int rbtree_init_trav(struct RB_TRAV *trav, struct RB_TREE *tree)
void rbtree_clear(struct RB_TREE *tree)
struct RB_TREE * rbtree_create(rb_compare_fn *compare, size_t rb_datasize)
void * rbtree_traverse(struct RB_TRAV *trav)
void * rbtree_find(struct RB_TREE *tree, const void *data)
int rbtree_insert(struct RB_TREE *tree, void *data)
void * rbtree_traverse_start(struct RB_TRAV *trav, const void *data)
int rb_compare_fn(const void *rb_a, const void *rb_b)
struct RB_NODE * curr_node
struct RB_NODE * up[RBTREE_MAX_HEIGHT]
rb_compare_fn * rb_compare