Browse Source

add balanced search tree to lib, update Vlib and segment

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@42281 15284696-431f-4ddb-bdfa-cd5b030d7da7
Markus Metz 15 years ago
parent
commit
62a5737c3b

+ 4 - 3
include/Make/Grass.make

@@ -112,6 +112,7 @@ libs = \
 	BASIC:basic \
 	BITMAP:bitmap \
 	BTREE:btree \
+	BTREE2:btree2 \
 	CAIRODRIVER:cairodriver \
 	CDHC:cdhc \
 	CCMATH:ccmath \
@@ -213,13 +214,13 @@ RASTERDEPS       = $(GISLIB) $(XDRLIB) $(SOCKLIB) $(MATHLIB)
 RLIDEPS          = $(RASTERLIB) $(GISLIB) $(MATHLIB)
 ROWIODEPS        = $(GISLIB)
 RTREEDEPS        = $(MATHLIB)
-SEGMENTDEPS      = $(GISLIB)
+SEGMENTDEPS      = $(GISLIB) $(BTREE2LIB)
 #SIMDEPS          = $(VECTLIB) $(BITMAPLIB) $(GMATHLIB) $(LINKMLIB) $(SITESLIB) $(DBMILIB) $(GISLIB)
 SITESDEPS        = $(VECTORLIB) $(DBMILIB) $(GISLIB) $(DATETIMELIB)
 STATSDEPS        = $(RASTERLIB) $(GISLIB) $(MATHLIB)	# NB: doesn't use libgis directly
 SYMBDEPS         = $(GISLIB) $(MATHLIB)
 TRANSDEPS        = $(MATHLIB)
-VECTORDEPS       = $(DBMILIB) $(GRAPHLIB) $(DIG2LIB) $(LINKMLIB) $(RTREELIB) $(GISLIB) $(GEOSLIBS) $(GDALLIBS) $(MATHLIB)
+VECTORDEPS       = $(DBMILIB) $(GRAPHLIB) $(DIG2LIB) $(LINKMLIB) $(RTREELIB) $(GISLIB) $(GEOSLIBS) $(GDALLIBS) $(MATHLIB) $(BTREE2LIB)
 VEDITDEPS        = $(VECTORLIB) $(DBMILIB) $(GISLIB) $(MATHLIB)
 NETADEPS         = $(VECTORDEP) $(DBMIDEP) $(GISDEP)
 
@@ -276,7 +277,7 @@ endif
 
 DBMILIB     = $(DBMICLIENTLIB) $(DBMIBASELIB) $(DBMIEXTRALIB)
 GEOMLIB     = $(OPTRILIB) $(SOSLIB) $(LIALIB) $(BASICLIB)
-VECTLIB     = $(VECTORLIB) $(DIG2LIB) $(GRAPHLIB) $(RTREELIB) $(LINKMLIB) $(DBMILIB)
+VECTLIB     = $(VECTORLIB) $(DIG2LIB) $(GRAPHLIB) $(RTREELIB) $(LINKMLIB) $(DBMILIB) $(BTREE2LIB)
 
 DBMIDEP     = $(DBMICLIENTDEP) $(DBMIBASEDEP)
 GEOMDEP     = $(OPTRIDEP) $(SOSDEP) $(LIADEP) $(BASICDEP)

include/vect/rbtree.h → include/rbtree.h


+ 2 - 2
include/vect/dig_structs.h

@@ -20,7 +20,7 @@
 
 #include <grass/dgl.h>
 #include <grass/shapefil.h>
-#include <grass/btree.h>
+#include <grass/rbtree.h>
 #include <grass/rtree.h>
 
 #ifdef HAVE_OGR
@@ -31,7 +31,7 @@
 
   3.10 changes plus_t to  ints.
   This assumes that any reasonable machine will use 4 bytes to
-  store an int. The mapdev code is not guaranteed to work if
+  store an int. The diglib code is not guaranteed to work if
   plus_t is changed to a type that is larger than an int.
 */
 typedef int plus_t;

+ 1 - 0
lib/Makefile

@@ -17,6 +17,7 @@ SUBDIRS = \
 	cairodriver \
 	bitmap \
 	btree \
+	btree2 \
 	display \
 	db \
 	fonts \

+ 11 - 0
lib/btree2/Makefile

@@ -0,0 +1,11 @@
+MODULE_TOPDIR = ../..
+
+include $(MODULE_TOPDIR)/include/Make/Vars.make
+
+MOD_OBJS := $(filter-out try.o,$(AUTO_OBJS))
+
+LIB = BTREE2
+
+include $(MODULE_TOPDIR)/include/Make/Lib.make
+
+default: lib

+ 75 - 0
lib/btree2/README

@@ -0,0 +1,75 @@
+
+#include <grass/rbtree.h>
+
+and link to BTREE2LIB
+
+to make use of this binary balanced (Red-Black) search tree
+
+NOTE: duplicates are not supported
+
+
+USAGE
+=====
+
+see also grass/rbtree.h for instructions on how to use it
+  
+/* custom compare function */
+extern int my_compare_fn(const void *, const void *);
+int my_compare_fn(const void *a, const void *b)
+{
+    if ((mydatastruct *) a < (mydatastruct *) b)
+        return -1;
+    else if ((mydatastruct *) a > (mydatastruct *) b)
+        return 1;
+    else if ((mydatastruct *) a == (mydatastruct *) b)
+        return 0;
+}
+
+/* create and initialize tree: */
+struct RB_TREE *mytree = rbtree_create(my_compare_fn, item_size);
+
+/* insert items to tree: */
+    struct mydatastruct data = <some data>;
+    
+    if (rbtree_insert(mytree, &data) == 0)
+        G_warning("could not insert data");
+
+/* find item in tree: */
+    struct mydatastruct data = <some data>;
+    
+    if (rbtree_find(mytree, &data) == 0)
+        G_message("data not found");
+
+/* delete item from tree: */
+    struct mydatastruct data = <some data>;
+    
+    if (rbtree_remove(mytree, &data) == 0)
+        G_warning("could not find data in tree");
+
+/* traverse tree (get all items in tree in ascending order): */
+    struct RB_TRAV trav;
+    
+    rbtree_init_trav(&trav, tree);
+    while ((data = rbtree_traverse(&trav)) != NULL) {
+        if (my_compare_fn(data, threshold_data) == 0) break;
+  	    /* do something with data */
+    }
+
+/* get a selection of items: all data > data1 and < data2
+ * start in tree where data is last smaller or first larger compared to data1 */
+    struct RB_TRAV trav;
+    
+    rbtree_init_trav(&trav, tree);
+    data = rbtree_traverse_start(&trav, &data1);
+  	    /* do something with data */
+    while ((data = rbtree_traverse(&trav)) != NULL) {
+       if (data > data2) break;
+  	    /* do something with data */
+    }
+ 
+/* destroy tree: */
+    rbtree_destroy(mytree);
+ 
+/* debug the whole tree with */
+    rbtree_debug(mytree, mytree->root);
+    

+ 3 - 4
raster/r.watershed/ram/rbtree.c

@@ -16,12 +16,11 @@
 
 /* balanced binary search tree implementation
  * 
- * this one is a Red Black Tree, the bare version, no parent pointers, no threads
+ * this one is a Red Black Tree, no parent pointers, no threads
  * The core code comes from Julienne Walker's tutorials on binary search trees
  * original license: public domain
  * http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_rbtree.aspx
  * some ideas come from libavl (GPL >= 2)
- * I could have used some off-the-shelf solution, but that's boring
  *
  * Red Black Trees are used to maintain a data structure with
  * search, insertion and deletion in O(log N) time
@@ -32,7 +31,7 @@
 #include <string.h>
 #include <grass/gis.h>
 #include <grass/glocale.h>
-#include "rbtree.h"
+#include <grass/rbtree.h>
 
 /* internal functions */
 void rbtree_destroy2(struct RB_NODE *);
@@ -47,7 +46,7 @@ int is_red(struct RB_NODE *);
 /* create new tree and initialize
  * returns pointer to new tree, NULL for memory allocation error
  */
-struct RB_TREE *rbtree_create(rb_compare_fn * compare, size_t rb_datasize)
+struct RB_TREE *rbtree_create(rb_compare_fn *compare, size_t rb_datasize)
 {
     struct RB_TREE *tree = G_malloc(sizeof(*tree));
 

+ 2 - 0
lib/segment/Makefile

@@ -3,6 +3,8 @@ MODULE_TOPDIR = ../..
 
 LIB = SEGMENT
 
+LIBES = $(BTREE2LIB)
+
 include $(MODULE_TOPDIR)/include/Make/Lib.make
 include $(MODULE_TOPDIR)/include/Make/Doxygen.make
 

+ 1 - 1
lib/segment/pagein.c

@@ -17,7 +17,7 @@
 #include <string.h>
 #include <errno.h>
 #include <grass/segment.h>
-#include "rbtree.h"
+#include <grass/rbtree.h>
 
 
 /**

+ 0 - 535
lib/segment/rbtree.c

@@ -1,535 +0,0 @@
-/*!
- * \file rbtree.c
- *
- * \brief binary search tree 
- *
- * Generic balanced binary search tree (Red Black Tree) implementation
- *
- * (C) 2009 by the GRASS Development Team
- *
- * This program is free software under the GNU General Public License
- * (>=v2).  Read the file COPYING that comes with GRASS for details.
- *
- * \author Original author Julienne Walker 2003, 2008
- *         GRASS implementation Markus Metz, 2009
- */
-
-/* balanced binary search tree implementation
- * 
- * this one is a Red Black Tree, the bare version, no parent pointers, no threads
- * The core code comes from Julienne Walker's tutorials on binary search trees
- * original license: public domain
- * http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_rbtree.aspx
- * some ideas come from libavl (GPL >= 2)
- * I could have used some off-the-shelf solution, but that's boring
- *
- * Red Black Trees are used to maintain a data structure with
- * search, insertion and deletion in O(log N) time
- */
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <grass/gis.h>
-#include <grass/glocale.h>
-#include "rbtree.h"
-
-/* internal functions */
-void rbtree_destroy2(struct RB_NODE *);
-struct RB_NODE *rbtree_single(struct RB_NODE *, int);
-struct RB_NODE *rbtree_double(struct RB_NODE *, int);
-void *rbtree_first(struct RB_TRAV *);
-void *rbtree_next(struct RB_TRAV *);
-struct RB_NODE *rbtree_make_node(size_t, void *);
-int is_red(struct RB_NODE *);
-
-
-/* create new tree and initialize
- * returns pointer to new tree, NULL for memory allocation error
- */
-struct RB_TREE *rbtree_create(rb_compare_fn * compare, size_t rb_datasize)
-{
-    struct RB_TREE *tree = G_malloc(sizeof(*tree));
-
-    if (tree == NULL) {
-	G_warning("RB tree: Out of memory!");
-	return NULL;
-    }
-
-    assert(compare);
-
-    tree->datasize = rb_datasize;
-    tree->rb_compare = compare;
-    tree->count = 0;
-    tree->root = NULL;
-
-    return tree;
-}
-
-/* add an item to a tree
- * non-recursive top-down insertion
- * the algorithm does not allow duplicates and also does not warn about a duplicate
- * returns 1 on success, 0 on failure
- */
-int rbtree_insert(struct RB_TREE *tree, void *data)
-{
-    assert(tree && data);
-
-    if (tree->root == NULL) {
-	/* create a new root node for tree */
-	tree->root = rbtree_make_node(tree->datasize, data);
-	if (tree->root == NULL)
-	    return 0;
-    }
-    else {
-	struct RB_NODE head = { 0 };	/* False tree root */
-	struct RB_NODE *g, *t;	/* Grandparent & parent */
-	struct RB_NODE *p, *q;	/* Iterator & parent */
-	int dir = 0, last = 0;
-
-	/* Set up helpers */
-	t = &head;
-	g = p = NULL;
-	q = t->link[1] = tree->root;
-
-	/* Search down the tree */
-	for (;;) {
-	    if (q == NULL) {
-		/* Insert new node at the bottom */
-		p->link[dir] = q = rbtree_make_node(tree->datasize, data);
-		if (q == NULL)
-		    return 0;
-	    }
-	    else if (is_red(q->link[0]) && is_red(q->link[1])) {
-		/* Color flip */
-		q->red = 1;
-		q->link[0]->red = 0;
-		q->link[1]->red = 0;
-	    }
-
-	    /* Fix red violation */
-	    if (is_red(q) && is_red(p)) {
-		int dir2 = t->link[1] == g;
-
-		if (q == p->link[last])
-		    t->link[dir2] = rbtree_single(g, !last);
-		else
-		    t->link[dir2] = rbtree_double(g, !last);
-	    }
-
-	    last = dir;
-	    dir = tree->rb_compare(q->data, data);
-
-	    /* Stop if found. This check also disallows duplicates in the tree */
-	    if (dir == 0)
-		break;
-
-	    dir = dir < 0;
-
-	    /* Move the helpers down */
-	    if (g != NULL)
-		t = g;
-
-	    g = p, p = q;
-	    q = q->link[dir];
-	}
-
-	/* Update root */
-	tree->root = head.link[1];
-    }
-
-    /* Make root black */
-    tree->root->red = 0;
-
-    tree->count++;
-
-    return 1;
-}
-
-/* remove an item from a tree that matches given data
- * non-recursive top-down removal
- * returns 1 on successful removal
- * returns 0 if data item was not found
- */
-int rbtree_remove(struct RB_TREE *tree, const void *data)
-{
-    struct RB_NODE head = { 0 };	/* False tree root */
-    struct RB_NODE *q, *p, *g;	/* Helpers */
-    struct RB_NODE *f = NULL;	/* Found item */
-    int dir = 1, removed = 0;
-
-    assert(tree && data);
-
-    if (tree->root == NULL) {
-	return 0;		/* empty tree, nothing to remove */
-    }
-
-    /* Set up helpers */
-    q = &head;
-    g = p = NULL;
-    q->link[1] = tree->root;
-
-    /* Search and push a red down */
-    while (q->link[dir] != NULL) {
-	int last = dir;
-
-	/* Update helpers */
-	g = p, p = q;
-	q = q->link[dir];
-	dir = tree->rb_compare(q->data, data);
-
-	/* Save found node */
-	if (dir == 0)
-	    f = q;
-
-	dir = dir < 0;
-
-	/* Push the red node down */
-	if (!is_red(q) && !is_red(q->link[dir])) {
-	    if (is_red(q->link[!dir]))
-		p = p->link[last] = rbtree_single(q, dir);
-	    else if (!is_red(q->link[!dir])) {
-		struct RB_NODE *s = p->link[!last];
-
-		if (s != NULL) {
-		    if (!is_red(s->link[!last]) && !is_red(s->link[last])) {
-			/* Color flip */
-			p->red = 0;
-			s->red = 1;
-			q->red = 1;
-		    }
-		    else {
-			int dir2 = g->link[1] == p;
-
-			if (is_red(s->link[last]))
-			    g->link[dir2] = rbtree_double(p, last);
-			else if (is_red(s->link[!last]))
-			    g->link[dir2] = rbtree_single(p, last);
-
-			/* Ensure correct coloring */
-			q->red = g->link[dir2]->red = 1;
-			g->link[dir2]->link[0]->red = 0;
-			g->link[dir2]->link[1]->red = 0;
-		    }
-		}
-	    }
-	}
-    }
-
-    /* Replace and remove if found */
-    if (f != NULL) {
-	G_free(f->data);
-	f->data = q->data;
-	p->link[p->link[1] == q] = q->link[q->link[0] == NULL];
-	G_free(q);
-	tree->count--;
-	removed = 1;
-    }
-    else
-	G_debug(2, "RB tree: data not found in search tree");
-
-    /* Update root and make it black */
-    tree->root = head.link[1];
-    if (tree->root != NULL)
-	tree->root->red = 0;
-
-    return removed;
-}
-
-/* find data item in tree
- * returns pointer to data item if found else NULL
- */
-void *rbtree_find(struct RB_TREE *tree, const void *data)
-{
-    struct RB_NODE *curr_node = tree->root;
-    int cmp;
-
-    assert(tree && data);
-
-    while (curr_node != NULL) {
-	cmp = tree->rb_compare(curr_node->data, data);
-	if (cmp == 0)
-	    return curr_node->data;	/* found */
-
-	curr_node = curr_node->link[cmp < 0];
-    }
-    return NULL;
-}
-
-/* initialize tree traversal
- * (re-)sets trav structure
- * returns 0
- */
-int rbtree_init_trav(struct RB_TRAV *trav, struct RB_TREE *tree)
-{
-    assert(trav && tree);
-
-    trav->tree = tree;
-    trav->curr_node = tree->root;
-    trav->first = 1;
-    trav->top = 0;
-
-    return 0;
-}
-
-/* traverse the tree in ascending order
- * useful to get all items in the tree non-recursively
- * struct RB_TRAV *trav needs to be initialized first
- * returns pointer to data, NULL when finished
- */
-void *rbtree_traverse(struct RB_TRAV *trav)
-{
-    assert(trav);
-
-    if (trav->curr_node == NULL) {
-	if (trav->first)
-	    G_debug(1, "RB tree: empty tree");
-	else
-	    G_debug(1, "RB tree: finished traversing");
-
-	return NULL;
-    }
-
-    if (!trav->first)
-	return rbtree_next(trav);
-    else {
-	trav->first = 0;
-	return rbtree_first(trav);
-    }
-}
-
-/* find start point to traverse the tree in ascending order
- * useful to get a selection of items in the tree
- * magnitudes faster than traversing the whole tree
- * may return first item that's smaller or first item that's larger
- * struct RB_TRAV *trav needs to be initialized first
- * returns pointer to data, NULL when finished
- */
-void *rbtree_traverse_start(struct RB_TRAV *trav, const void *data)
-{
-    int dir = 0;
-
-    assert(trav && data);
-
-    if (trav->curr_node == NULL) {
-	if (trav->first)
-	    G_warning("RB tree: empty tree");
-	else
-	    G_warning("RB tree: finished traversing");
-
-	return NULL;
-    }
-
-    if (!trav->first)
-	return rbtree_next(trav);
-
-    /* else first time, get start node */
-
-    trav->first = 0;
-    trav->top = 0;
-
-    while (trav->curr_node != NULL) {
-	dir = trav->tree->rb_compare(trav->curr_node->data, data);
-	/* exact match, great! */
-	if (dir == 0)
-	    return trav->curr_node->data;
-	else {
-	    dir = dir < 0;
-	    /* end of branch, also reached if
-	     * smallest item is larger than search template or
-	     * largest item is smaller than search template */
-	    if (trav->curr_node->link[dir] == NULL)
-		return trav->curr_node->data;
-
-	    trav->up[trav->top++] = trav->curr_node;
-	    trav->curr_node = trav->curr_node->link[dir];
-	}
-    }
-
-    return NULL;		/* should not happen */
-}
-
-/* two functions needed to fully traverse the tree: initialize and continue
- * useful to get all items in the tree non-recursively
- * this one here uses a stack
- * parent pointers or threads would also be possible
- * but these would need to be added to RB_NODE
- * -> more memory needed for standard operations
- */
-
-/* start traversing the tree
- * returns pointer to smallest data item
- */
-void *rbtree_first(struct RB_TRAV *trav)
-{
-    /* get smallest item */
-    while (trav->curr_node->link[0] != NULL) {
-	trav->up[trav->top++] = trav->curr_node;
-	trav->curr_node = trav->curr_node->link[0];
-    }
-
-    return trav->curr_node->data;	/* return smallest item */
-}
-
-/* continue traversing the tree in ascending order
- * returns pointer to data item, NULL when finished
- */
-void *rbtree_next(struct RB_TRAV *trav)
-{
-    if (trav->curr_node->link[1] != NULL) {
-	/* something on the right side: larger item */
-	trav->up[trav->top++] = trav->curr_node;
-	trav->curr_node = trav->curr_node->link[1];
-
-	/* go down, find smallest item in this branch */
-	while (trav->curr_node->link[0] != NULL) {
-	    trav->up[trav->top++] = trav->curr_node;
-	    trav->curr_node = trav->curr_node->link[0];
-	}
-    }
-    else {
-	/* at smallest item in this branch, go back up */
-	struct RB_NODE *last;
-
-	do {
-	    if (trav->top == 0) {
-		trav->curr_node = NULL;
-		break;
-	    }
-	    last = trav->curr_node;
-	    trav->curr_node = trav->up[--trav->top];
-	} while (last == trav->curr_node->link[1]);
-    }
-
-    if (trav->curr_node != NULL) {
-	return trav->curr_node->data;
-    }
-    else
-	return NULL;		/* finished traversing */
-}
-
-/* destroy the tree */
-void rbtree_destroy(struct RB_TREE *tree)
-{
-    rbtree_destroy2(tree->root);
-    G_free(tree);
-}
-
-void rbtree_destroy2(struct RB_NODE *root)
-{
-    if (root != NULL) {
-	rbtree_destroy2(root->link[0]);
-	rbtree_destroy2(root->link[1]);
-	G_free(root->data);
-	G_free(root);
-    }
-}
-
-/* used for debugging: check for errors in tree structure */
-int rbtree_debug(struct RB_TREE *tree, struct RB_NODE *root)
-{
-    int lh, rh;
-
-    if (root == NULL)
-	return 1;
-    else {
-	struct RB_NODE *ln = root->link[0];
-	struct RB_NODE *rn = root->link[1];
-	int lcmp = 0, rcmp = 0;
-
-	/* Consecutive red links */
-	if (is_red(root)) {
-	    if (is_red(ln) || is_red(rn)) {
-		G_warning("Red Black Tree debugging: Red violation");
-		return 0;
-	    }
-	}
-
-	lh = rbtree_debug(tree, ln);
-	rh = rbtree_debug(tree, rn);
-
-	if (ln) {
-	    lcmp = tree->rb_compare(ln->data, root->data);
-	}
-
-	if (rn) {
-	    rcmp = tree->rb_compare(rn->data, root->data);
-	}
-
-	/* Invalid binary search tree:
-	 * left node >= parent or right node <= parent */
-	if ((ln != NULL && lcmp > -1)
-	    || (rn != NULL && rcmp < 1)) {
-	    G_warning("Red Black Tree debugging: Binary tree violation");
-	    return 0;
-	}
-
-	/* Black height mismatch */
-	if (lh != 0 && rh != 0 && lh != rh) {
-	    G_warning("Red Black Tree debugging: Black violation");
-	    return 0;
-	}
-
-	/* Only count black links */
-	if (lh != 0 && rh != 0)
-	    return is_red(root) ? lh : lh + 1;
-	else
-	    return 0;
-    }
-}
-
-/*******************************************************
- *                                                     *
- *  internal functions for Red Black Tree maintenance  *
- *                                                     *
- *******************************************************/
-
-/* add a new node to the tree */
-struct RB_NODE *rbtree_make_node(size_t datasize, void *data)
-{
-    struct RB_NODE *new_node = G_malloc(sizeof(*new_node));
-
-    if (new_node == NULL)
-	G_fatal_error("RB Search Tree: Out of memory!");
-
-    new_node->data = G_malloc(datasize);
-    if (new_node->data == NULL)
-	G_fatal_error("RB Search Tree: Out of memory!");
-
-    memcpy(new_node->data, data, datasize);
-    new_node->red = 1;		/* 1 is red, 0 is black */
-    new_node->link[0] = NULL;
-    new_node->link[1] = NULL;
-
-    return new_node;
-}
-
-/* check for red violation */
-int is_red(struct RB_NODE *root)
-{
-    if (root)
-	return root->red == 1;
-
-    return 0;
-}
-
-/* single rotation */
-struct RB_NODE *rbtree_single(struct RB_NODE *root, int dir)
-{
-    struct RB_NODE *newroot = root->link[!dir];
-
-    root->link[!dir] = newroot->link[dir];
-    newroot->link[dir] = root;
-
-    root->red = 1;
-    newroot->red = 0;
-
-    return newroot;
-}
-
-/* double rotation */
-struct RB_NODE *rbtree_double(struct RB_NODE *root, int dir)
-{
-    root->link[!dir] = rbtree_single(root->link[!dir], !dir);
-    return rbtree_single(root, dir);
-}

+ 0 - 112
lib/segment/rbtree.h

@@ -1,112 +0,0 @@
-/*************************************************************
- *                          USAGE                            *
- *************************************************************
- *
- * NOTE: duplicates are not supported
- *
- * custom compare function
- * extern int my_compare_fn(const void *, const void *);
- * int my_compare_fn(const void *a, const void *b) {
- *   if ((mydatastruct *) a < (mydatastruct *) b)
- *     return -1;
- *   else if ((mydatastruct *) a > (mydatastruct *) b)
- *     return 1;
- *   else if ((mydatastruct *) a == (mydatastruct *) b)
- *     return 0;
- * }
- * 
- * create and initialize tree:
- * struct RB_TREE *mytree = rbtree_create(my_compare_fn, item_size);
- *
- * insert items to tree:
- * struct mydatastruct data = <some data>;
- * if (rbtree_insert(mytree, &data) == 0)
- * 	 G_warning("could not insert data");
- *
- * find item in tree:
- * struct mydatastruct data = <some data>;
- * if (rbtree_find(mytree, &data) == 0)
- * 	 G_message("data not found");
- *
- * delete item from tree:
- * struct mydatastruct data = <some data>;
- * if (rbtree_remove(mytree, &data) == 0)
- * 	  G_warning("could not find data in tree");
- *
- * traverse tree (get all items in tree in ascending order):
- * struct RB_TRAV trav;
- * rbtree_init_trav(&trav, tree);
- * while ((data = rbtree_traverse(&trav)) != NULL) {
- *   if (my_compare_fn(data, threshold_data) == 0) break;
- * 	   <do something with data>;
- *  }
- *
- * get a selection of items: all data > data1 and < data2
- * start in tree where data is last smaller or first larger compared to data1
- * struct RB_TRAV trav;
- * rbtree_init_trav(&trav, tree);
- * data = rbtree_traverse_start(&trav, &data1);
- * 	 <do something with data>;
- * while ((data = rbtree_traverse(&trav)) != NULL) {
- *	 if (data > data2) break;
- *   <do something with data>;
- * }
- *
- * destroy tree:
- * rbtree_destroy(mytree);
- *
- * debug the whole tree with
- * rbtree_debug(mytree, mytree->root);
- * 
- *************************************************************/
-
-#include <stddef.h>
-
-/* maximum RB Tree height */
-#define RBTREE_MAX_HEIGHT 64        /* should be more than enough */
-
-/* routine to compare data items
- * return -1 if rb_a < rb_b
- * return  0 if rb_a == rb_b
- * return  1 if rb_a > rb_b
- */
-typedef int rb_compare_fn(const void *rb_a, const void *rb_b);
-
-struct RB_NODE
-{
-    unsigned char red;              /* 0 = black, 1 = red */
-    void *data;                     /* any kind of data */
-    struct RB_NODE *link[2];        /* link to children: link[0] for smaller, link[1] for larger */
-};
- 
-struct RB_TREE
-{
-    struct RB_NODE *root;           /* root node */
-    size_t datasize;                /* item size */
-    size_t count;                   /* number of items in tree. */
-    rb_compare_fn *rb_compare;      /* function to compare data */
-};
-
-struct RB_TRAV
-{
-    struct RB_TREE *tree;           /* tree being traversed */
-    struct RB_NODE *curr_node;      /* current node */
-    struct RB_NODE *up[RBTREE_MAX_HEIGHT];  /* stack of parent nodes */
-    int top;                        /* index for stack */
-    int first;                      /* little helper flag */
-};
-
-/* tree functions */
-struct RB_TREE *rbtree_create(rb_compare_fn *, size_t);
-void rbtree_destroy(struct RB_TREE *);
-int rbtree_insert(struct RB_TREE *, void *);
-int rbtree_remove(struct RB_TREE *, const void *);
-void *rbtree_find(struct RB_TREE *, const void *);
-
-/* tree traversal functions */
-int rbtree_init_trav(struct RB_TRAV *, struct RB_TREE *);
-void* rbtree_traverse(struct RB_TRAV *);
-void *rbtree_traverse_start(struct RB_TRAV *, const void *);
-
-/* debug tree from given node downwards */
-int rbtree_debug(struct RB_TREE *, struct RB_NODE *);

+ 1 - 1
lib/segment/release.c

@@ -14,7 +14,7 @@
 
 #include <stdlib.h>
 #include <grass/segment.h>
-#include "rbtree.h"
+#include <grass/rbtree.h>
 
 
 /**

+ 1 - 1
lib/segment/setup.c

@@ -17,7 +17,7 @@
 #include <math.h>
 #include <grass/gis.h>
 #include <grass/segment.h>
-#include "rbtree.h"
+#include <grass/rbtree.h>
 
 
 /**

+ 0 - 1
lib/vector/Vlib/break_polygons.c

@@ -21,7 +21,6 @@
 #include <math.h>
 #include <grass/gis.h>
 #include <grass/vector.h>
-#include <grass/vect/rbtree.h>
 #include <grass/glocale.h>
 
 /* TODO: 3D support

+ 0 - 1
lib/vector/Vlib/snap.c

@@ -20,7 +20,6 @@
 #include <grass/gis.h>
 #include <grass/vector.h>
 #include <grass/glocale.h>
-#include <grass/vect/rbtree.h>
 
 /* function prototypes */
 static int sort_new(const void *pa, const void *pb);

+ 0 - 536
lib/vector/diglib/rbtree.c

@@ -1,536 +0,0 @@
-/*!
- * \file rbtree.c
- *
- * \brief binary search tree 
- *
- * Generic balanced binary search tree (Red Black Tree) implementation
- *
- * (C) 2009 by the GRASS Development Team
- *
- * This program is free software under the GNU General Public License
- * (>=v2).  Read the file COPYING that comes with GRASS for details.
- *
- * \author Original author Julienne Walker 2003, 2008
- *         GRASS implementation Markus Metz, 2009
- */
-
-/* balanced binary search tree implementation
- * 
- * this one is a Red Black Tree, the bare version, no parent pointers, no threads
- * The core code comes from Julienne Walker's tutorials on binary search trees
- * original license: public domain
- * http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_rbtree.aspx
- * some ideas come from libavl (GPL >= 2)
- * I could have used some off-the-shelf solution, but that's boring
- *
- * Red Black Trees are used to maintain a data structure with
- * search, insertion and deletion in O(log N) time
- */
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <grass/gis.h>
-#include <grass/glocale.h>
-#include <grass/vect/rbtree.h>
-
-/* internal functions */
-void rbtree_destroy2(struct RB_NODE *);
-struct RB_NODE *rbtree_single(struct RB_NODE *, int);
-struct RB_NODE *rbtree_double(struct RB_NODE *, int);
-void *rbtree_first(struct RB_TRAV *);
-void *rbtree_next(struct RB_TRAV *);
-struct RB_NODE *rbtree_make_node(size_t, void *);
-int is_red(struct RB_NODE *);
-
-
-/* create new tree and initialize
- * returns pointer to new tree, NULL for memory allocation error
- */
-struct RB_TREE *rbtree_create(rb_compare_fn *compare, size_t rb_datasize)
-{
-    struct RB_TREE *tree = G_malloc(sizeof(*tree));
-
-    if (tree == NULL) {
-	G_warning("RB tree: Out of memory!");
-	return NULL;
-    }
-
-    assert(compare);
-
-    tree->datasize = rb_datasize;
-    tree->rb_compare = compare;
-    tree->count = 0;
-    tree->root = NULL;
-
-    return tree;
-} 
-
-/* add an item to a tree
- * non-recursive top-down insertion
- * the algorithm does not allow duplicates and also does not warn about a duplicate
- * returns 1 on success, 0 on failure
- */
-int rbtree_insert(struct RB_TREE *tree, void *data)
-{
-    assert(tree && data);
-    
-    if (tree->root == NULL) {
-	/* create a new root node for tree */
-	tree->root = rbtree_make_node(tree->datasize, data);
-	if (tree->root == NULL)
-	    return 0;
-    }
-    else {
-	struct RB_NODE head = {0}; /* False tree root */
-
-	struct RB_NODE *g, *t;     /* Grandparent & parent */
-	struct RB_NODE *p, *q;     /* Iterator & parent */
-	int dir = 0, last = 0;
-
-	/* Set up helpers */
-	t = &head;
-	g = p = NULL;
-	q = t->link[1] = tree->root;
-
-	/* Search down the tree */
-	for ( ; ; ) {
-	    if (q == NULL) {
-		/* Insert new node at the bottom */
-		p->link[dir] = q = rbtree_make_node(tree->datasize, data);
-		if (q == NULL)
-		    return 0;
-	    }
-	    else if (is_red(q->link[0]) && is_red(q->link[1])) {
-		/* Color flip */
-		q->red = 1;
-		q->link[0]->red = 0;
-		q->link[1]->red = 0;
-	    }
-
-	    /* Fix red violation */
-	    if (is_red(q) && is_red(p)) {
-		int dir2 = t->link[1] == g;
-
-		if (q == p->link[last])
-		    t->link[dir2] = rbtree_single(g, !last);
-		else
-		    t->link[dir2] = rbtree_double(g, !last);
-	    }
-
-	    last = dir;
-	    dir = tree->rb_compare(q->data, data);
-
-	    /* Stop if found. This check also disallows duplicates in the tree */
-	    if (dir == 0)
-		break;
-
-	    dir = dir < 0;
-
-	    /* Move the helpers down */
-	    if (g != NULL)
-		t = g;
-
-	    g = p, p = q;
-	    q = q->link[dir];
-	}
-
-	/* Update root */
-	tree->root = head.link[1];
-    }
-
-    /* Make root black */
-    tree->root->red = 0;
-
-    tree->count++;
-
-    return 1;
-}
-
-/* remove an item from a tree that matches given data
- * non-recursive top-down removal
- * returns 1 on successful removal
- * returns 0 if data item was not found
- */
-int rbtree_remove(struct RB_TREE *tree, const void *data)
-{
-    struct RB_NODE head = {0}; /* False tree root */
-    struct RB_NODE *q, *p, *g; /* Helpers */
-    struct RB_NODE *f = NULL;  /* Found item */
-    int dir = 1, removed = 0;
-
-    assert(tree && data);
-
-    if (tree->root == NULL) {
-	return 0; /* empty tree, nothing to remove */
-    }
-
-    /* Set up helpers */
-    q = &head;
-    g = p = NULL;
-    q->link[1] = tree->root;
-
-    /* Search and push a red down */
-    while (q->link[dir] != NULL) {
-	int last = dir;
-
-	/* Update helpers */
-	g = p, p = q;
-	q = q->link[dir];
-	dir = tree->rb_compare(q->data, data);
-
-	/* Save found node */
-	if (dir == 0)
-	    f = q;
-
-	dir = dir < 0;
-
-	/* Push the red node down */
-	if (!is_red(q) && !is_red(q->link[dir])) {
-	    if (is_red(q->link[!dir]))
-		p = p->link[last] = rbtree_single(q, dir);
-	    else if (!is_red(q->link[!dir])) {
-		struct RB_NODE *s = p->link[!last];
-
-		if (s != NULL) {
-		    if (!is_red(s->link[!last]) &&
-		        !is_red(s->link[last])) {
-			/* Color flip */
-			p->red = 0;
-			s->red = 1;
-			q->red = 1;
-		    }
-		    else {
-			int dir2 = g->link[1] == p;
-
-			if (is_red(s->link[last]))
-			    g->link[dir2] = rbtree_double(p, last);
-			else if (is_red(s->link[!last]))
-			    g->link[dir2] = rbtree_single(p, last);
-
-			/* Ensure correct coloring */
-			q->red = g->link[dir2]->red = 1;
-			g->link[dir2]->link[0]->red = 0;
-			g->link[dir2]->link[1]->red = 0;
-		    }
-		}
-	    }
-	}
-    }
-
-    /* Replace and remove if found */
-    if (f != NULL) {
-	G_free(f->data);
-	f->data = q->data;
-	p->link[p->link[1] == q] = q->link[q->link[0] == NULL];
-	G_free(q);
-	tree->count--;
-	removed = 1;
-    }
-    else
-	G_debug(2, "RB tree: data not found in search tree");
-
-    /* Update root and make it black */
-    tree->root = head.link[1];
-    if ( tree->root != NULL)
-	tree->root->red = 0;
-
-    return removed;
-}
-
-/* find data item in tree
- * returns pointer to data item if found else NULL
- */
-void *rbtree_find(struct RB_TREE *tree, const void *data)
-{
-    struct RB_NODE *curr_node = tree->root;
-    int cmp = 0;
-
-    assert(tree && data);
-
-    while (curr_node != NULL) {
-	cmp = tree->rb_compare(curr_node->data, data);
-	if (cmp == 0)
-	    return curr_node->data;   /* found */
-	else {
-	    curr_node = curr_node->link[cmp < 0];
-	}
-    }
-    return NULL;
-}
-
-/* initialize tree traversal
- * (re-)sets trav structure
- * returns 0
- */
-int rbtree_init_trav(struct RB_TRAV *trav, struct RB_TREE *tree)
-{
-    assert(trav && tree);
-
-    trav->tree = tree;
-    trav->curr_node = tree->root;
-    trav->first = 1;
-    trav->top = 0;
-
-    return 0;
-}
-
-/* traverse the tree in ascending order
- * useful to get all items in the tree non-recursively
- * struct RB_TRAV *trav needs to be initialized first
- * returns pointer to data, NULL when finished
- */
-void *rbtree_traverse(struct RB_TRAV *trav)
-{
-    assert(trav);
-    
-    if (trav->curr_node == NULL) {
-	if (trav->first)
-	    G_debug(1, "RB tree: empty tree");
-	else
-	    G_debug(1, "RB tree: finished traversing");
-
-	return NULL;
-    }
-	
-    if (!trav->first)
-	return rbtree_next(trav);
-    else {
-	trav->first = 0;
-	return rbtree_first(trav);
-    }
-}
-
-/* find start point to traverse the tree in ascending order
- * useful to get a selection of items in the tree
- * magnitudes faster than traversing the whole tree
- * may return first item that's smaller or first item that's larger
- * struct RB_TRAV *trav needs to be initialized first
- * returns pointer to data, NULL when finished
- */
-void *rbtree_traverse_start(struct RB_TRAV *trav, const void *data)
-{
-    int dir = 0;
-
-    assert(trav && data);
-
-    if (trav->curr_node == NULL) {
-	if (trav->first)
-	    G_warning("RB tree: empty tree");
-	else
-	    G_warning("RB tree: finished traversing");
-
-	return NULL;
-    }
-	
-    if (!trav->first)
-	return rbtree_next(trav);
-
-    /* else first time, get start node */
-
-    trav->first = 0;
-    trav->top = 0;
-
-    while (trav->curr_node != NULL) {
-	dir = trav->tree->rb_compare(trav->curr_node->data, data);
-	/* exact match, great! */
-	if (dir == 0)
-	    return trav->curr_node->data;
-	else {
-	    dir = dir < 0;
-	    /* end of branch, also reached if
-	     * smallest item is larger than search template or
-	     * largest item is smaller than search template */
-	    if (trav->curr_node->link[dir] == NULL)
-		return trav->curr_node->data;
-		
-	    trav->up[trav->top++] = trav->curr_node;
-	    trav->curr_node = trav->curr_node->link[dir];
-	}
-    }
-
-    return NULL; /* should not happen */
-}
-
-/* two functions needed to fully traverse the tree: initialize and continue
- * useful to get all items in the tree non-recursively
- * this one here uses a stack
- * parent pointers or threads would also be possible
- * but these would need to be added to RB_NODE
- * -> more memory needed for standard operations
- */
-
-/* start traversing the tree
- * returns pointer to smallest data item
- */
-void *rbtree_first(struct RB_TRAV *trav)
-{
-    /* get smallest item */
-    while (trav->curr_node->link[0] != NULL) {
-	trav->up[trav->top++] = trav->curr_node;
-	trav->curr_node = trav->curr_node->link[0];
-    }
-
-    return trav->curr_node->data; /* return smallest item */
-}
-
-/* continue traversing the tree in ascending order
- * returns pointer to data item, NULL when finished
- */
-void *rbtree_next(struct RB_TRAV *trav)
-{
-    if (trav->curr_node->link[1] != NULL) {
-	/* something on the right side: larger item */
-	trav->up[trav->top++] = trav->curr_node;
-	trav->curr_node = trav->curr_node->link[1];
-
-	/* go down, find smallest item in this branch */
-	while (trav->curr_node->link[0] != NULL) {
-	    trav->up[trav->top++] = trav->curr_node;
-	    trav->curr_node = trav->curr_node->link[0];
-	}
-    }
-    else {
-	/* at smallest item in this branch, go back up */
-	struct RB_NODE *last;
-	do {
-	    if (trav->top == 0) {
-		trav->curr_node = NULL;
-		break;
-	    }
-	    last = trav->curr_node;
-	    trav->curr_node = trav->up[--trav->top];
-	} while (last == trav->curr_node->link[1]);
-    }
-
-    if (trav->curr_node != NULL) {
-	return trav->curr_node->data;
-    }
-    else	
-	return NULL; /* finished traversing */
-}
-
-/* destroy the tree */
-void rbtree_destroy(struct RB_TREE *tree) {
-    rbtree_destroy2(tree->root);
-    G_free(tree);
-}
-
-void rbtree_destroy2(struct RB_NODE *root)
-{
-    if (root != NULL) {
-	rbtree_destroy2(root->link[0]);
-	rbtree_destroy2(root->link[1]);
-	G_free(root->data);
-	G_free(root);
-    }
-}
-
-/* used for debugging: check for errors in tree structure */
-int rbtree_debug(struct RB_TREE *tree, struct RB_NODE *root)
-{
-    int lh, rh;
- 
-    if (root == NULL)
-	return 1;
-    else {
-	struct RB_NODE *ln = root->link[0];
-	struct RB_NODE *rn = root->link[1];
-	int lcmp = 0, rcmp = 0;
-
-	/* Consecutive red links */
-	if (is_red(root)) {
-	    if (is_red(ln) || is_red(rn)) {
-		G_warning("Red Black Tree debugging: Red violation");
-		return 0;
-	    }
-	}
-
-	lh = rbtree_debug(tree, ln);
-	rh = rbtree_debug(tree, rn);
-
-	if (ln) {
-	    lcmp = tree->rb_compare(ln->data, root->data);
-	}
-	
-	if (rn) {
-	    rcmp = tree->rb_compare(rn->data, root->data);
-	}
-
-	/* Invalid binary search tree:
-	 * left node >= parent or right node <= parent */
-	if ((ln != NULL && lcmp > -1)
-	 || (rn != NULL && rcmp < 1)) {
-	    G_warning("Red Black Tree debugging: Binary tree violation" );
-	    return 0;
-	}
-
-	/* Black height mismatch */
-	if (lh != 0 && rh != 0 && lh != rh) {
-	    G_warning("Red Black Tree debugging: Black violation");
-	    return 0;
-	}
-
-	/* Only count black links */
-	if (lh != 0 && rh != 0)
-	    return is_red(root) ? lh : lh + 1;
-	else
-	    return 0;
-    }
-}
-
-/*******************************************************
- *                                                     *
- *  internal functions for Red Black Tree maintenance  *
- *                                                     *
- *******************************************************/
-
-/* add a new node to the tree */
-struct RB_NODE *rbtree_make_node(size_t datasize, void *data)
-{
-    struct RB_NODE *new_node = G_malloc(sizeof(*new_node));
-
-    if (new_node == NULL)
-	G_fatal_error("RB Search Tree: Out of memory!");
-
-    new_node->data = G_malloc(datasize);
-    if (new_node->data == NULL)
-	G_fatal_error("RB Search Tree: Out of memory!");
-	
-    memcpy(new_node->data, data, datasize);
-    new_node->red = 1;            /* 1 is red, 0 is black */
-    new_node->link[0] = NULL;
-    new_node->link[1] = NULL;
-
-    return new_node;
-}
-
-/* check for red violation */
-int is_red(struct RB_NODE *root)
-{
-    if (root)
-	return root->red == 1;
-
-    return 0;
-}
-
-/* single rotation */
-struct RB_NODE *rbtree_single(struct RB_NODE *root, int dir)
-{
-    struct RB_NODE *newroot = root->link[!dir];
-
-    root->link[!dir] = newroot->link[dir];
-    newroot->link[dir] = root;
-
-    root->red = 1;
-    newroot->red = 0;
-
-    return newroot;
-}
- 
-/* double rotation */
-struct RB_NODE *rbtree_double(struct RB_NODE *root, int dir)
-{
-    root->link[!dir] = rbtree_single(root->link[!dir], !dir);
-    return rbtree_single(root, dir);
-}

+ 1 - 1
raster/r.watershed/ram/Makefile

@@ -2,7 +2,7 @@ MODULE_TOPDIR = ../../..
 
 PGM = r.watershed.ram
 
-LIBES = $(RASTERLIB) $(GISLIB) $(MATHLIB)
+LIBES = $(RASTERLIB) $(GISLIB) $(MATHLIB) $(BTREE2LIB)
 DEPENDENCIES = $(RASTERDEP) $(GISDEP)
 
 include $(MODULE_TOPDIR)/include/Make/Etc.make

+ 1 - 1
raster/r.watershed/ram/do_flatarea.c

@@ -16,9 +16,9 @@
 #include <assert.h>
 #include <grass/gis.h>
 #include <grass/glocale.h>
+#include <grass/rbtree.h>
 #include "Gwater.h"
 #include "do_astar.h"
-#include "rbtree.h"
 
 struct pq_node
 {

+ 0 - 112
raster/r.watershed/ram/rbtree.h

@@ -1,112 +0,0 @@
-/*************************************************************
- *                          USAGE                            *
- *************************************************************
- *
- * NOTE: duplicates are not supported
- *
- * custom compare function
- * extern int my_compare_fn(const void *, const void *);
- * int my_compare_fn(const void *a, const void *b) {
- *   if ((mydatastruct *) a < (mydatastruct *) b)
- *     return -1;
- *   else if ((mydatastruct *) a > (mydatastruct *) b)
- *     return 1;
- *   else if ((mydatastruct *) a == (mydatastruct *) b)
- *     return 0;
- * }
- * 
- * create and initialize tree:
- * struct RB_TREE *mytree = rbtree_create(my_compare_fn, item_size);
- *
- * insert items to tree:
- * struct mydatastruct data = <some data>;
- * if (rbtree_insert(mytree, &data) == 0)
- * 	 G_warning("could not insert data");
- *
- * find item in tree:
- * struct mydatastruct data = <some data>;
- * if (rbtree_find(mytree, &data) == 0)
- * 	 G_message("data not found");
- *
- * delete item from tree:
- * struct mydatastruct data = <some data>;
- * if (rbtree_remove(mytree, &data) == 0)
- * 	  G_warning("could not find data in tree");
- *
- * traverse tree (get all items in tree in ascending order):
- * struct RB_TRAV trav;
- * rbtree_init_trav(&trav, tree);
- * while ((data = rbtree_traverse(&trav)) != NULL) {
- *   if (my_compare_fn(data, threshold_data) == 0) break;
- * 	   <do something with data>;
- *  }
- *
- * get a selection of items: all data > data1 and < data2
- * start in tree where data is last smaller or first larger compared to data1
- * struct RB_TRAV trav;
- * rbtree_init_trav(&trav, tree);
- * data = rbtree_traverse_start(&trav, &data1);
- * 	 <do something with data>;
- * while ((data = rbtree_traverse(&trav)) != NULL) {
- *	 if (data > data2) break;
- *   <do something with data>;
- * }
- *
- * destroy tree:
- * rbtree_destroy(mytree);
- *
- * debug the whole tree with
- * rbtree_debug(mytree, mytree->root);
- * 
- *************************************************************/
-
-#include <stddef.h>
-
-/* maximum RB Tree height */
-#define RBTREE_MAX_HEIGHT 64        /* should be more than enough */
-
-/* routine to compare data items
- * return -1 if rb_a < rb_b
- * return  0 if rb_a == rb_b
- * return  1 if rb_a > rb_b
- */
-typedef int rb_compare_fn(const void *rb_a, const void *rb_b);
-
-struct RB_NODE
-{
-    unsigned char red;              /* 0 = black, 1 = red */
-    void *data;                     /* any kind of data */
-    struct RB_NODE *link[2];        /* link to children: link[0] for smaller, link[1] for larger */
-};
- 
-struct RB_TREE
-{
-    struct RB_NODE *root;           /* root node */
-    size_t datasize;                /* item size */
-    size_t count;                   /* number of items in tree. */
-    rb_compare_fn *rb_compare;      /* function to compare data */
-};
-
-struct RB_TRAV
-{
-    struct RB_TREE *tree;           /* tree being traversed */
-    struct RB_NODE *curr_node;      /* current node */
-    struct RB_NODE *up[RBTREE_MAX_HEIGHT];  /* stack of parent nodes */
-    int top;                        /* index for stack */
-    int first;                      /* little helper flag */
-};
-
-/* tree functions */
-struct RB_TREE *rbtree_create(rb_compare_fn *, size_t);
-void rbtree_destroy(struct RB_TREE *);
-int rbtree_insert(struct RB_TREE *, void *);
-int rbtree_remove(struct RB_TREE *, const void *);
-void *rbtree_find(struct RB_TREE *, const void *);
-
-/* tree traversal functions */
-int rbtree_init_trav(struct RB_TRAV *, struct RB_TREE *);
-void* rbtree_traverse(struct RB_TRAV *);
-void *rbtree_traverse_start(struct RB_TRAV *, const void *);
-
-/* debug tree from given node downwards */
-int rbtree_debug(struct RB_TREE *, struct RB_NODE *);