X-Git-Url: https://www.tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=lib%2Favl_tree.c;h=a4f005182a0051d6f33e1a90d7b6186778a9f1bc;hp=341ffeb63e77a396f220c7814512981700e09d52;hb=4252ae83a43ea81382ce71ba614e2d1655f2e189;hpb=e5e1c20a99b0d72792f28e9a075a9f4a7e8b2c95 diff --git a/lib/avl_tree.c b/lib/avl_tree.c index 341ffeb6..a4f00518 100644 --- a/lib/avl_tree.c +++ b/lib/avl_tree.c @@ -26,10 +26,10 @@ the code. Mail me if you found a bug. Cleaned up and incorporated some of the ideas from the red-black tree - library for inclusion into tinc (http://tinc.nl.linux.org) by + library for inclusion into tinc (http://tinc.nl.linux.org/) by Guus Sliepen . - $Id: avl_tree.c,v 1.1.2.4 2001/01/08 21:32:00 guus Exp $ + $Id: avl_tree.c,v 1.1.2.8 2002/02/10 21:57:51 guus Exp $ */ #include @@ -406,12 +406,43 @@ avl_node_t *avl_search_closest_greater_node(const avl_tree_t *tree, const void * avl_node_t *avl_insert(avl_tree_t *tree, void *data) { - avl_node_t *node; + avl_node_t *closest, *new; + int result; - node = avl_alloc_node(); - node->data = data; + if (!tree->root) + { + new = avl_alloc_node(); + new->data = data; + avl_insert_top(tree, new); + } + else + { + closest = avl_search_closest_node(tree, data, &result); + switch(result) + { + case -1: + new = avl_alloc_node(); + new->data = data; + avl_insert_before(tree, closest, new); + break; + case 1: + new = avl_alloc_node(); + new->data = data; + avl_insert_after(tree, closest, new); + break; + default: + return NULL; + } + } + +#ifdef AVL_COUNT + new->count = 1; +#endif +#ifdef AVL_DEPTH + new->depth = 1; +#endif - return avl_insert_node(tree, node); + return new; } avl_node_t *avl_insert_node(avl_tree_t *tree, avl_node_t *node) @@ -433,7 +464,7 @@ avl_node_t *avl_insert_node(avl_tree_t *tree, avl_node_t *node) avl_insert_after(tree, closest, node); break; case 0: - return closest; + return NULL; } } @@ -462,6 +493,9 @@ void avl_insert_before(avl_tree_t *tree, avl_node_t *before, avl_node_t *node) node->parent = before; node->prev = before->prev; + if(before->left) + return avl_insert_after(tree, before->prev, node); + if (before->prev) before->prev->next = node; else @@ -478,6 +512,9 @@ void avl_insert_after(avl_tree_t *tree, avl_node_t *after, avl_node_t *node) if (!after) return tree->head ? avl_insert_before(tree, tree->head, node) : avl_insert_top(tree, node); + if(after->right) + return avl_insert_before(tree, after->next, node); + node->prev = after; node->parent = after; node->next = after->next; @@ -560,6 +597,15 @@ void avl_unlink_node(avl_tree_t *tree, avl_node_t *node) } avl_rebalance(tree, balnode); + + node->next = node->prev = node->parent = node->left = node->right = NULL; + +#ifdef AVL_COUNT + node->count = 0; +#endif +#ifdef AVL_DEPTH + node->depth = 0; +#endif } void avl_delete_node(avl_tree_t *tree, avl_node_t *node)