diff --git a/lib/isc/include/isc/rbtgen.h b/lib/isc/include/isc/rbtgen.h deleted file mode 100644 index 5b51323c37..0000000000 --- a/lib/isc/include/isc/rbtgen.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 1998, 1999, 2000 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Note that we do not do the usual #ifdef ... #endif protection since this - * file is used as a template. - */ - -#include - -typedef struct _isc_rbt_node { - enum { red, black } color; - void *data; - struct _isc_rbt_node *parent; - struct _isc_rbt_node *right; - struct _isc_rbt_node *left; -} RBT_NODE; - -isc_result_t RBT_INSERT(RBT_NODE *, RBT_NODE **, - int (*compare)(void *, void*)); -isc_result_t RBT_DELETE(RBT_NODE *, RBT_NODE **); -RBT_NODE *RBT_SEARCH(RBT_NODE *, void *, int (*compare)(void *, void*)); -void RBT_PRINT(RBT_NODE *, void (*print_key)(void *)); diff --git a/lib/isc/rbtgen.c b/lib/isc/rbtgen.c deleted file mode 100644 index 14e595f9ef..0000000000 --- a/lib/isc/rbtgen.c +++ /dev/null @@ -1,530 +0,0 @@ -/* - * Copyright (C) 1998, 1999, 2000 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * This file is a generic template that can be used to create a red-black - * tree library for a specified node type. - */ - -/* - * Red-Black Tree algorithms adapted from: - * - * _Introduction to Algorithms_, Cormen, Leiserson, and Rivest, - * MIT Press / McGraw Hill, 1990, ISBN 0-262-03141-8, chapter 14. - */ - -#include - -#include -#include -#include - -#include -#include -#include - -#ifdef RBT_TRACE -#define TRACE_CASE(n) printf("case %d\n", (n)) -#define TRACE_NODE(n) \ - do { \ - printf("%p ", (n)); \ - PRINT_KEY(KEY(n)); \ - printf(" (%s)\n", IS_RED((n)) ? "red" : "black"); \ - } while (0) -#else -#define TRACE_CASE(n) -#define TRACE_NODE(n) -#endif - -#define COLOR(node) ((node)->color) -#define KEY(node) ((node)->data) -#define LEFT(node) ((node)->left) -#define RIGHT(node) ((node)->right) -#define PARENT(node) ((node)->parent) - -#define SET_COLOR(node, value) ((node)->color = (value)) -#define SET_KEY(node, value) ((node)->data = (value)) -#define SET_LEFT(node, child) ((node)->left = (child)) -#define SET_RIGHT(node, child) ((node)->right = (child)) -#define SET_PARENT(node, child) ((node)->parent = (child)) - -#define IS_RED(node) ((node) != NULL && (node)->color == red) -#define IS_BLACK(node) ((node) == NULL || (node)->color == black) -#define MAKE_RED(node) ((node)->color = red) -#define MAKE_BLACK(node) ((node)->color = black) - -static inline void -rotate_left(RBT_NODE *node, RBT_NODE **rootp) { - RBT_NODE *child; - - REQUIRE(node != NULL); - REQUIRE(rootp != NULL); - - child = RIGHT(node); - REQUIRE(child != NULL); - - SET_RIGHT(node, LEFT(child)); - if (LEFT(child) != NULL) - SET_PARENT(LEFT(child), node); - - SET_LEFT(child, node); - SET_PARENT(child, PARENT(node)); - if (PARENT(node) != NULL) { - if (LEFT(PARENT(node)) == node) - SET_LEFT(PARENT(node), child); - else { - SET_RIGHT(PARENT(node), child); - } - } else - *rootp = child; - - SET_PARENT(node, child); -} - -static inline void -rotate_right(RBT_NODE *node, RBT_NODE **rootp) { - RBT_NODE *child; - - REQUIRE(node != NULL); - REQUIRE(rootp != NULL); - - child = LEFT(node); - REQUIRE(child != NULL); - - SET_LEFT(node, RIGHT(child)); - if (RIGHT(child) != NULL) - SET_PARENT(RIGHT(child), node); - - SET_RIGHT(child, node); - SET_PARENT(child, PARENT(node)); - if (PARENT(node) != NULL) { - if (LEFT(PARENT(node)) == node) - SET_LEFT(PARENT(node), child); - else - SET_RIGHT(PARENT(node), child); - } else - *rootp = child; - - SET_PARENT(node, child); -} - -isc_result_t -RBT_INSERT(RBT_NODE *node, RBT_NODE **rootp, int (*compare)(void *, void *)) { - RBT_NODE *current, *child, *root, *parent, *grandparent; - int i; - - REQUIRE(rootp != NULL); - REQUIRE(LEFT(node) == NULL && RIGHT(node) == NULL); - REQUIRE(KEY(node) != NULL); - - root = *rootp; - if (root == NULL) { - MAKE_BLACK(node); - *rootp = node; - return (ISC_R_SUCCESS); - } - - current = NULL; - child = root; - do { - current = child; - i = compare(KEY(node), KEY(current)); - if (i == 0) - return (ISC_R_EXISTS); - if (i < 0) - child = LEFT(current); - else - child = RIGHT(current); - } while (child != NULL); - if (i < 0) - SET_LEFT(current, node); - else - SET_RIGHT(current, node); - MAKE_RED(node); - SET_PARENT(node, current); - - while (node != root && IS_RED(PARENT(node))) { - parent = PARENT(node); - grandparent = PARENT(PARENT(node)); - - TRACE_NODE(n); - - if (parent == LEFT(grandparent)) { - child = RIGHT(grandparent); - if (child != NULL && IS_RED(child)) { - TRACE_CASE(1); - MAKE_BLACK(parent); - MAKE_BLACK(child); - MAKE_RED(grandparent); - node = grandparent; - } else { - if (node == RIGHT(parent)) { - TRACE_CASE(2); - node = parent; - rotate_left(node, &root); - parent = PARENT(node); - grandparent = PARENT(PARENT(node)); - } - TRACE_CASE(3); - MAKE_BLACK(parent); - MAKE_RED(grandparent); - rotate_right(grandparent, &root); - } - } else { - child = LEFT(grandparent); - if (child != NULL && IS_RED(child)) { - TRACE_CASE(4); - MAKE_BLACK(parent); - MAKE_BLACK(child); - MAKE_RED(grandparent); - node = grandparent; - } else { - if (node == LEFT(parent)) { - TRACE_CASE(5); - node = parent; - rotate_right(node, &root); - parent = PARENT(node); - grandparent = PARENT(PARENT(node)); - } - TRACE_CASE(6); - MAKE_BLACK(parent); - MAKE_RED(grandparent); - rotate_left(grandparent, &root); - } - } - } - - MAKE_BLACK(root); - *rootp = root; - - return (ISC_R_SUCCESS); -} - -/* node must belong to a pointer in the tree; how could this be ensured? */ -isc_result_t -RBT_DELETE(RBT_NODE *delete, RBT_NODE **rootp) { - RBT_NODE *successor, *sibling, *child = NULL; - - REQUIRE(rootp != NULL); - REQUIRE(delete); - - if (LEFT(delete) == NULL) - if (RIGHT(delete) == NULL) { - if (*rootp == delete) { - /* this is the only item in the tree */ - *rootp = NULL; - return(ISC_R_SUCCESS); - } - } else - /* this node has one child, on the right */ - child = RIGHT(delete); - - else if (RIGHT(delete) == NULL) - /* this node has one child, on the left */ - child = LEFT(delete); - - else { - RBT_NODE holder, *tmp = &holder; - - /* this node has two children, so it cannot be directly - deleted. find its immediate in-order successor and - move it to this location, then do the deletion at the - old site of the successor */ - successor = RIGHT(delete); - while (LEFT(successor) != NULL) - successor = LEFT(successor); - - /* the successor cannot possibly have a left child; - if there is any child, it is on the right */ - if (RIGHT(successor)) - child = RIGHT(successor); - - /* swap the two nodes; it would be simpler to just replace - the value being deleted with that of the successor, - but this rigamarole is done so the caller has complete - control over the pointers (and memory allocation) of - all of nodes. if just the key value were removed from - the tree, the pointer to the node would would be - unchanged. */ - - /* first, put the successor in the tree location of the - node to be deleted */ - - memcpy(tmp, successor, sizeof(RBT_NODE)); - - if (LEFT(PARENT(delete)) == delete) - SET_LEFT(PARENT(delete), successor); - else - SET_RIGHT(PARENT(delete), successor); - - SET_PARENT(successor, PARENT(delete)); - - if (LEFT(delete) != NULL) - SET_PARENT(LEFT(delete), successor); - - if (RIGHT(delete) != NULL && RIGHT(delete) != successor) - SET_PARENT(RIGHT(delete), successor); - - SET_COLOR(successor, COLOR(delete)); - SET_LEFT(successor, LEFT(delete)); - SET_RIGHT(successor, RIGHT(delete)); - - /* now relink the node to be deleted into the - successor's previous tree location */ - if (PARENT(tmp) != delete) { - if (LEFT(PARENT(tmp)) == successor) - SET_LEFT(PARENT(tmp), delete); - else - SET_RIGHT(PARENT(tmp), delete); - SET_PARENT(delete, PARENT(tmp)); - } else - SET_PARENT(delete, successor); - - /* original successor node has no left */ - if (RIGHT(tmp) != NULL) - SET_PARENT(RIGHT(tmp), delete); - - SET_COLOR(delete, COLOR(tmp)); - SET_LEFT(delete, LEFT(tmp)); - SET_RIGHT(delete, RIGHT(tmp)); - - } - - - /* fix the parent chain if a non-leaf is being deleted */ - if (PARENT(delete) != NULL) { - if (LEFT(PARENT(delete)) == delete) { - SET_LEFT(PARENT(delete), child); - sibling = RIGHT(PARENT(delete)); - } else { - SET_RIGHT(PARENT(delete), child); - sibling = LEFT(PARENT(delete)); - } - - if (child != NULL) - SET_PARENT(child, PARENT(delete)); - } else { - /* this is the root being deleted, with just one child */ - SET_PARENT(child, NULL); - sibling= NULL; - *rootp = child; - } - - /* fix color violations */ - if (IS_BLACK(delete)) { - RBT_NODE *parent; - parent = PARENT(delete); - - while (child != *rootp && IS_BLACK(child)) { - /* parent = PARENT(parent_pointer); */ - - if (LEFT(parent) == child) { - sibling = RIGHT(parent); - if (IS_RED(sibling)) { - MAKE_BLACK(sibling); - MAKE_RED(parent); - rotate_left(parent, rootp); - sibling = RIGHT(parent); - } - if (IS_BLACK(LEFT(sibling)) && - IS_BLACK(RIGHT(sibling))) { - MAKE_RED(sibling); - child = parent; - } else { - if (IS_BLACK(RIGHT(sibling))) { - MAKE_BLACK(LEFT(sibling)); - MAKE_RED(sibling); - rotate_right(sibling, rootp); - sibling = RIGHT(parent); - } - SET_COLOR(sibling, COLOR(parent)); - MAKE_BLACK(parent); - MAKE_BLACK(RIGHT(sibling)); - rotate_left(parent, rootp); - child = *rootp; - } - } else { - sibling = LEFT(parent); - if (IS_RED(sibling)) { - MAKE_BLACK(sibling); - MAKE_RED(parent); - rotate_right(parent, rootp); - sibling = LEFT(parent); - } - if (IS_BLACK(LEFT(sibling)) && - IS_BLACK(RIGHT(sibling))) { - MAKE_RED(sibling); - child = parent; - } else { - if (IS_BLACK(LEFT(sibling))) { - MAKE_BLACK(RIGHT(sibling)); - MAKE_RED(sibling); - rotate_left(sibling, rootp); - sibling = LEFT(parent); - } - SET_COLOR(sibling, COLOR(parent)); - MAKE_BLACK(parent); - MAKE_BLACK(LEFT(sibling)); - rotate_right(parent, rootp); - child = *rootp; - } - } - - parent = PARENT(child); - } - - if (IS_RED(child)) - MAKE_BLACK(child); - } - - return(ISC_R_SUCCESS); -} - -RBT_NODE * -RBT_SEARCH(RBT_NODE *current, void *key, int (*compare)(void *, void *)) { - int i; - - while (current != NULL) { - i = compare(key, KEY(current)); - if (i == 0) - break; - if (i < 0) - current = LEFT(current); - else - current = RIGHT(current); - } - - return(current); -} - -static inline void -print_tree(RBT_NODE *root, void (*print_key)(void *), int depth) { - int i; - - for (i = 0; i < depth; i++) - putchar('\t'); - if (root != NULL) { - print_key(KEY(root)); - printf(" (%s", IS_RED(root) ? "RED" : "black"); - if (root->parent) { - printf(" from "); - print_key(KEY(root->parent)); - } - printf(")\n"); - depth++; - - if (IS_RED(root) && IS_RED(LEFT(root))) - printf("** Red/Red color violation on left\n"); - print_tree(LEFT(root), print_key, depth); - - if (IS_RED(root) && IS_RED(RIGHT(root))) - printf("** Red/Red color violation on right\n"); - print_tree(RIGHT(root), print_key, depth); - } else - printf("NULL\n"); -} - -void -RBT_PRINT(RBT_NODE *root, void (*print_key)(void *)) { - print_tree(root, print_key, 0); -} - -#ifdef WANT_RBTGEN_MAIN - -int compare_int(void *, void *); -void print_int(void *); - -int ints[] = { 12679, 26804, 7389, 20562, 24355, 23584, - 10713, 8094, 19071, 6732, 2709, 6058, - 3995, 3896, 15121, 1142, 2679, 26340, - 30541, 29186, -#if 0 - 6584, 13201, 21238, 30455, 6500, 30669, - 10370, 2963, 26576, 17353, 19150, 19951, - 12540, 21381, 17882, 23051, 24808, 8961, - 26022, 3047, 9108, 28221, 13874, 32643, - 25856, 12601, 894, 4319, 20780, 10229, -#endif - 0 }; - -int -compare_int(void *a, void *b) { - int i = *(int *)a, j = *(int *)b; - return(i == j ? 0 : (i < j ? -1 : 1)); -} - -void -print_int(void *num) { - int i = *(int *)num; - (void)printf("%d", i); -} - -#define KEY_VALUE(node, type) (*(type *)((node)->data)) - -void -main() { - RBT_NODE nodes[sizeof(ints)/sizeof(int)], *p, *root; - int *i, j; - - setbuf(stdout, NULL); - - printf("For any two successive numbers at the same depth, the\n"); - printf("first number (and all its descendants) should be less than\n"); - printf("the number which immediately precedes it one depth level\n"); - printf("higher, and the second number (and all its descendants)\n"); - printf("should be greater than that preceding number\n\n"); - - for (i = &ints[0], p = &nodes[0]; *i != 0; i++, p++) { - printf("inserting %d\n", *i); - KEY(p) = i; - RBT_INSERT(p, &root, compare_int); - - RBT_PRINT(root, print_int); - } - - j = 2679; - i = &j; - - printf("searching for %d ...", j); - p = RBT_SEARCH(root, i, compare_int); - if (p != NULL) { - printf("found %d\n", KEY_VALUE(p, int)); - } else { - printf("not found!\n"); - } - - j = 9999; - i = &j; - - printf("searching for %d ...", j); - p = RBT_SEARCH(root, i, compare_int); - if (p != NULL) { - printf("found %d\n", KEY_VALUE(p, int)); - } else { - printf("not found!\n"); - } - - p = &nodes[sizeof(ints) / sizeof(int) - 2]; - do { - printf("deleting %d\n", KEY_VALUE(p, int)); - RBT_DELETE(p, &root); - RBT_PRINT(root, print_int); - } while (p-- != &nodes[0]); - - exit(0); -} -#endif