]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
Rework rbtree to fit into unbound, doxygen comments.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 31 Jan 2007 12:25:06 +0000 (12:25 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 31 Jan 2007 12:25:06 +0000 (12:25 +0000)
git-svn-id: file:///svn/unbound/trunk@47 be551aaa-1e26-0410-a405-d3ace91eadb9

util/rbtree.c
util/rbtree.h

index aaca1a043cdc3118d4242eacfbad08ed0df5bfc0..76cef3df1045a46a3770a3dbc08dd6a0b34b83ee 100644 (file)
  *
  */
 
-#include <config.h>
-
-#include <assert.h>
-#include <stdlib.h>
+/**
+ * \file
+ * Implementation of a redblack tree.
+ */
 
-#include "rbtree.h"
+#include "config.h"
+#include "log.h"
+#include "util/rbtree.h"
 
+/** Node colour black */
 #define        BLACK   0
+/** Node colour red */
 #define        RED     1
 
+/** the NULL node, global alloc */
 rbnode_t       rbtree_null_node = {
        RBTREE_NULL,            /* Parent.  */
        RBTREE_NULL,            /* Left.  */
@@ -54,9 +59,13 @@ rbnode_t     rbtree_null_node = {
        BLACK                   /* Color.  */
 };
 
+/** rotate subtree left (to preserve redblack property). */
 static void rbtree_rotate_left(rbtree_t *rbtree, rbnode_t *node);
+/** rotate subtree right (to preserve redblack property). */
 static void rbtree_rotate_right(rbtree_t *rbtree, rbnode_t *node);
+/** Fixup node colours when insert happened */
 static void rbtree_insert_fixup(rbtree_t *rbtree, rbnode_t *node);
+/** Fixup node colours when delete happened */
 static void rbtree_delete_fixup(rbtree_t* rbtree, rbnode_t* child, rbnode_t* child_parent);
 
 /*
@@ -66,12 +75,12 @@ static void rbtree_delete_fixup(rbtree_t* rbtree, rbnode_t* child, rbnode_t* chi
  *
  */
 rbtree_t *
-rbtree_create (region_type *region, int (*cmpf)(const void *, const void *))
+rbtree_create (int (*cmpf)(const void *, const void *))
 {
        rbtree_t *rbtree;
 
        /* Allocate memory for it */
-       rbtree = (rbtree_t *) region_alloc(region, sizeof(rbtree_t));
+       rbtree = (rbtree_t *) malloc(sizeof(rbtree_t));
        if (!rbtree) {
                return NULL;
        }
@@ -79,7 +88,6 @@ rbtree_create (region_type *region, int (*cmpf)(const void *, const void *))
        /* Initialize it */
        rbtree->root = RBTREE_NULL;
        rbtree->count = 0;
-       rbtree->region = region;
        rbtree->cmp = cmpf;
 
        return rbtree;
@@ -273,34 +281,37 @@ rbtree_search (rbtree_t *rbtree, const void *key)
        }
 }
 
-/* helpers for delete */
+/** helpers for delete: swap node colours */
 static void swap_int8(uint8_t* x, uint8_t* y) 
 { 
        uint8_t t = *x; *x = *y; *y = t; 
 }
 
+/** helpers for delete: swap node pointers */
 static void swap_np(rbnode_t** x, rbnode_t** y) 
 {
        rbnode_t* t = *x; *x = *y; *y = t; 
 }
 
+/** Update parent pointers of child trees of 'parent'. */
 static void change_parent_ptr(rbtree_t* rbtree, rbnode_t* parent, rbnode_t* old, rbnode_t* new)
 {
        if(parent == RBTREE_NULL)
        {
-               assert(rbtree->root == old);
+               log_assert(rbtree->root == old);
                if(rbtree->root == old) rbtree->root = new;
                return;
        }
-       assert(parent->left == old || parent->right == old
+       log_assert(parent->left == old || parent->right == old
                || parent->left == new || parent->right == new);
        if(parent->left == old) parent->left = new;
        if(parent->right == old) parent->right = new;
 }
+/** Update parent pointer of a node 'child'. */
 static void change_child_ptr(rbnode_t* child, rbnode_t* old, rbnode_t* new)
 {
        if(child == RBTREE_NULL) return;
-       assert(child->parent == old || child->parent == new);
+       log_assert(child->parent == old || child->parent == new);
        if(child->parent == old) child->parent = new;
 }
 
@@ -354,7 +365,7 @@ rbtree_delete(rbtree_t *rbtree, const void *key)
 
                /* now delete to_delete (which is at the location where the smright previously was) */
        }
-       assert(to_delete->left == RBTREE_NULL || to_delete->right == RBTREE_NULL);
+       log_assert(to_delete->left == RBTREE_NULL || to_delete->right == RBTREE_NULL);
 
        if(to_delete->left != RBTREE_NULL) child = to_delete->left;
        else child = to_delete->right;
@@ -439,7 +450,7 @@ static void rbtree_delete_fixup(rbtree_t* rbtree, rbnode_t* child, rbnode_t* chi
                child_parent->color = BLACK;
                return;
        }
-       assert(sibling != RBTREE_NULL);
+       log_assert(sibling != RBTREE_NULL);
 
        /* get a new sibling, by rotating at sibling. See which child
           of sibling is red */
@@ -473,13 +484,13 @@ static void rbtree_delete_fixup(rbtree_t* rbtree, rbnode_t* child, rbnode_t* chi
        child_parent->color = BLACK;
        if(child_parent->right == child)
        {
-               assert(sibling->left->color == RED);
+               log_assert(sibling->left->color == RED);
                sibling->left->color = BLACK;
                rbtree_rotate_right(rbtree, child_parent);
        }
        else
        {
-               assert(sibling->right->color == RED);
+               log_assert(sibling->right->color == RED);
                sibling->right->color = BLACK;
                rbtree_rotate_left(rbtree, child_parent);
        }
@@ -491,7 +502,7 @@ rbtree_find_less_equal(rbtree_t *rbtree, const void *key, rbnode_t **result)
        int r;
        rbnode_t *node;
 
-       assert(result);
+       log_assert(result);
        
        /* We start at root... */
        node = rbtree->root;
index c95f24301c98f2e4ec5605bb8ce11992b8366e14..e2353e8c2f82efec0f5091b926ac886464da4382 100644 (file)
  *
  */
 
-#ifndef _RBTREE_H_
-#define        _RBTREE_H_
+/**
+ * Red black tree. Implementation taken from NSD 3.0.5, adjusted for use
+ * in unbound (memory allocation, logging and so on).
+ */
 
-#include "region-allocator.h"
+#ifndef UTIL_RBTREE_H_
+#define        UTIL_RBTREE_H_
 
-/*
+/**
  * This structure must be the first member of the data structure in
  * the rbtree.  This allows easy casting between an rbnode_t and the
  * user data (poor man's inheritance).
  */
 typedef struct rbnode_t rbnode_t;
+/**
+ * The rbnore_t struct definition.
+ */
 struct rbnode_t {
+       /** parent in rbtree, RBTREE_NULL for root */
        rbnode_t   *parent;
+       /** left node (smaller items) */
        rbnode_t   *left;
+       /** right node (larger items) */
        rbnode_t   *right;
+       /** pointer to sorting key */
        const void *key;
+       /** colour of this node */
        uint8_t     color;
 };
 
+/** The nullpointer, points to empty node */
 #define        RBTREE_NULL &rbtree_null_node
+/** the global empty node */
 extern rbnode_t        rbtree_null_node;
 
+/** An entire red black tree */
 typedef struct rbtree_t rbtree_t;
+/** definition for tree struct */
 struct rbtree_t {
-       region_type *region;
-       
-       /* The root of the red-black tree */
+       /** The root of the red-black tree */
        rbnode_t    *root;
 
-       /* The number of the nodes in the tree */
+       /** The number of the nodes in the tree */
        size_t       count;
 
-       /* Current node for walks... */
+       /** Current node for walks... */
        rbnode_t    *_node;
 
-       /* Key compare function. <0,0,>0 like strcmp. Return 0 on two NULL ptrs. */
+       /** 
+        * Key compare function. <0,0,>0 like strcmp. 
+        * Return 0 on two NULL ptrs. 
+        */
        int (*cmp) (const void *, const void *);
 };
 
-/* rbtree.c */
-rbtree_t *rbtree_create(region_type *region, int (*cmpf)(const void *, const void *));
+/** 
+ * Create new tree (malloced) with given key compare function. 
+ * @param cmpf: compare function (like strcmp) takes pointers to two keys.
+ * @return: new tree, empty.
+ */
+rbtree_t *rbtree_create(int (*cmpf)(const void *, const void *));
+
+/** 
+ * Insert data into the tree. 
+ * @param rbtree: tree to insert to.
+ * @param data: element to insert. 
+ * @return: data ptr or NULL if key already present. 
+ */
 rbnode_t *rbtree_insert(rbtree_t *rbtree, rbnode_t *data);
-/* returns node that is now unlinked from the tree. User to delete it. 
- * returns 0 if node not present */
+
+/**
+ * Delete element from tree.
+ * @param rbtree: tree to delete from.
+ * @param key: key of item to delete.
+ * @return: node that is now unlinked from the tree. User to delete it. 
+ * returns 0 if node not present 
+ */
 rbnode_t *rbtree_delete(rbtree_t *rbtree, const void *key);
+
+/**
+ * Find key in tree. Returns NULL if not found.
+ * @param rbtree: tree to find in.
+ * @param key: key that must match.
+ * @return: node that fits or NULL.
+ */
 rbnode_t *rbtree_search(rbtree_t *rbtree, const void *key);
-/* returns true if exact match in result. Else result points to <= element,
-   or NULL if key is smaller than the smallest key. */
-int rbtree_find_less_equal(rbtree_t *rbtree, const void *key, rbnode_t **result);
+
+/**
+ * Find, but match does not have to be exact.
+ * @param rbtree: tree to find in.
+ * @param key: key to find position of.
+ * @param result: set to the exact node if present, otherwise to element that
+ *   precedes the position of key in the tree. NULL if no smaller element.
+ * @return: true if exact match in result. Else result points to <= element,
+ * or NULL if key is smaller than the smallest key. 
+ */
+int rbtree_find_less_equal(rbtree_t *rbtree, const void *key, 
+       rbnode_t **result);
+
+/**
+ * Returns first (smallest) node in the tree
+ * @param rbtree: tree
+ * @return: smallest element or NULL if tree empty.
+ */
 rbnode_t *rbtree_first(rbtree_t *rbtree);
+
+/**
+ * Returns last (largest) node in the tree
+ * @param rbtree: tree
+ * @return: largest element or NULL if tree empty.
+ */
 rbnode_t *rbtree_last(rbtree_t *rbtree);
+
+/**
+ * Returns next larger node in the tree
+ * @param rbtree: tree
+ * @return: next larger element or NULL if no larger in tree.
+ */
 rbnode_t *rbtree_next(rbnode_t *rbtree);
+
+/**
+ * Returns previous smaller node in the tree
+ * @param rbtree: tree
+ * @return: previous smaller element or NULL if no previous in tree.
+ */
 rbnode_t *rbtree_previous(rbnode_t *rbtree);
 
+/**
+ * Macro to walk through the tree, sets k to key, d to data, for every element.
+ */
 #define        RBTREE_WALK(rbtree, k, d) \
        for((rbtree)->_node = rbtree_first(rbtree);\
                (rbtree)->_node != RBTREE_NULL && ((k) = (rbtree)->_node->key) && \
                ((d) = (void *) (rbtree)->_node); (rbtree)->_node = rbtree_next((rbtree)->_node))
 
-/* call with node=variable of struct* with rbnode_t as first element.
-   with type is the type of a pointer to that struct. */
+/**
+ * call with node=variable of struct* with rbnode_t as first element.
+ * with type is the type of a pointer to that struct. 
+ */
 #define RBTREE_FOR(node, type, rbtree) \
        for(node=(type)rbtree_first(rbtree); \
                (rbnode_t*)node != RBTREE_NULL; \
                node = (type)rbtree_next((rbnode_t*)node))
 
-#endif /* _RBTREE_H_ */
+#endif /* UTIL_RBTREE_H_ */