diff --git a/src/Makefile.am b/src/Makefile.am index 66f35a2f..822a80f5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -54,8 +54,6 @@ EVHTTP_SRC= RTSP_SRC=evrtsp/rtsp.c evrtp/evrtsp.h evrtsp/rtsp-internal.h evrtsp/log.h endif -AVL_SRC=avl/avl.c avl/avl.h - GPERF_FILES = \ daap_query.gperf \ rsp_query.gperf \ @@ -102,7 +100,6 @@ forked_daapd_SOURCES = main.c \ logger.c logger.h \ conffile.c conffile.h \ cache.c cache.h \ - $(AVL_SRC) \ filescanner.c filescanner.h \ filescanner_ffmpeg.c filescanner_playlist.c filescanner_icy.c $(ITUNES_SRC) \ mdns_avahi.c mdns.h \ diff --git a/src/avl/README b/src/avl/README deleted file mode 100644 index 668ec7b5..00000000 --- a/src/avl/README +++ /dev/null @@ -1,91 +0,0 @@ -======================================================================== - -WHAT IS AVLTREE? - -AVLTree is a small implementation of AVL trees for the C programming -language. It is distributed under the Library GNU Public License. - -This library does the basic stuff. It allows for inserts, searches, and -deletes in O(log n) time. It also allows the tree to be used as a linked -indexable list (search/insert functions cannot be used in that case). - -If you find a bug, you should mail Wessel Dankers , -who produced this version of the library and therefore is to blame. - -The original author is Michael H. Buselli , who can -be reached at the following address: - - Michael H. Buselli - 4334 N. Hazel St. #515 - Chicago, IL 60613-1456 - -======================================================================== - -COMPILING THE LIBRARY - -There is a Makefile included in the distribution. - -======================================================================== - -USING THE LIBRARIES - -There are no real usage documents yet. Look at avl.h (you need to -include these headers in your programs to use the library) to see what -functions and structures are available. As a small example: - - #define BUFSIZE 8192 - - int main(void) { - char *buf[BUFSIZE]; - AVLTree *tree; - AVLTree *node; - - tree = avl_alloc_tree((avl_compare_t)strcmp, (avl_freeitem_t)free); - - while(fgets(buf, BUFSIZE, stdin)) - avl_insert(tree, strdup(buf)); - - for(node = tree->head; node; node = node->next) - printf("%s", node->item); - - avl_free_tree(tree, free); - } - -A real implementation would check the return values of avl_alloc_tree, -avl_insert and strdup of course. - -======================================================================== - -HISTORY - -Version 0.1.0 (alpha): - This is the initial alpha version of AVLTree. It's already fully - functional for many applications, including the one that I developed it - for. I've only tested it on my Linux 2.0.35/glibc2 system, so I have no - idea what it will do anywhere else so far. Let me know if you have good - results or bad if you try a platform that I don't mention above. - - This version is considered alpha because it does not yet contain - all of the features that I plan for version 1.0.0. It should not - contain any bugs as it is. - -Version 0.2.0 2000-11-28 Wessel Dankers - Modifications to support fast traversal and accessing by index. - The tree is generalized to allow arbitrary comparison functions. - Fixed bug: when deleting, in some cases rebalancing would not occur - -Version 0.3.0 2001-01-07 Wessel Dankers - Tree can now be balanced on count or depth (but depth works better). - Fixed bug: balancing on count now is done correctly. - -Version 0.3.1 2001-07-17 Wessel Dankers - Node initialization is moved to make matters a bit more robust - -Version 0.3.4 2002-06-11 Wessel Dankers - Fixed a bug in the node counting. - -Version 0.3.5 2002-11-15 Wessel Dankers - Added avl_node_fixup() and avl_clear_tree(). - Removed obsolete files from source tree. - -======================================================================== diff --git a/src/avl/avl.c b/src/avl/avl.c deleted file mode 100644 index fe9c5a0c..00000000 --- a/src/avl/avl.c +++ /dev/null @@ -1,590 +0,0 @@ -/***************************************************************************** - - avl.c - Source code for the AVL-tree library. - - Copyright (C) 1998 Michael H. Buselli - Copyright (C) 2000-2002 Wessel Dankers - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Augmented AVL-tree. Original by Michael H. Buselli . - - Modified by Wessel Dankers to add a bunch of bloat to - the sourcecode, change the interface and squash a few bugs. - Mail him if you find new bugs. - -*****************************************************************************/ - -#include -#include -#include -#include "avl.h" - -static void avl_rebalance(avl_tree_t *, avl_node_t *); - -#ifdef AVL_COUNT -#define NODE_COUNT(n) ((n) ? (n)->count : 0) -#define L_COUNT(n) (NODE_COUNT((n)->left)) -#define R_COUNT(n) (NODE_COUNT((n)->right)) -#define CALC_COUNT(n) (L_COUNT(n) + R_COUNT(n) + 1) -#endif - -#ifdef AVL_DEPTH -#define NODE_DEPTH(n) ((n) ? (n)->depth : 0) -#define L_DEPTH(n) (NODE_DEPTH((n)->left)) -#define R_DEPTH(n) (NODE_DEPTH((n)->right)) -#define CALC_DEPTH(n) ((L_DEPTH(n)>R_DEPTH(n)?L_DEPTH(n):R_DEPTH(n)) + 1) -#endif - -#ifndef AVL_DEPTH -/* Also known as ffs() (from BSD) */ -static int lg(unsigned int u) { - int r = 1; - if(!u) return 0; - if(u & 0xffff0000) { u >>= 16; r += 16; } - if(u & 0x0000ff00) { u >>= 8; r += 8; } - if(u & 0x000000f0) { u >>= 4; r += 4; } - if(u & 0x0000000c) { u >>= 2; r += 2; } - if(u & 0x00000002) r++; - return r; -} -#endif - -static int avl_check_balance(avl_node_t *avlnode) { -#ifdef AVL_DEPTH - int d; - d = R_DEPTH(avlnode) - L_DEPTH(avlnode); - return d<-1?-1:d>1?1:0; -#else -/* int d; - * d = lg(R_COUNT(avlnode)) - lg(L_COUNT(avlnode)); - * d = d<-1?-1:d>1?1:0; - */ -#ifdef AVL_COUNT - int pl, r; - - pl = lg(L_COUNT(avlnode)); - r = R_COUNT(avlnode); - - if(r>>pl+1) - return 1; - if(pl<2 || r>>pl-2) - return 0; - return -1; -#else -#error No balancing possible. -#endif -#endif -} - -#ifdef AVL_COUNT -unsigned int avl_count(const avl_tree_t *avltree) { - return NODE_COUNT(avltree->top); -} - -avl_node_t *avl_at(const avl_tree_t *avltree, unsigned int index) { - avl_node_t *avlnode; - unsigned int c; - - avlnode = avltree->top; - - while(avlnode) { - c = L_COUNT(avlnode); - - if(index < c) { - avlnode = avlnode->left; - } else if(index > c) { - avlnode = avlnode->right; - index -= c+1; - } else { - return avlnode; - } - } - return NULL; -} - -unsigned int avl_index(const avl_node_t *avlnode) { - avl_node_t *next; - unsigned int c; - - c = L_COUNT(avlnode); - - while((next = avlnode->parent)) { - if(avlnode == next->right) - c += L_COUNT(next) + 1; - avlnode = next; - } - - return c; -} -#endif - -int avl_search_closest(const avl_tree_t *avltree, const void *item, avl_node_t **avlnode) { - avl_node_t *node; - avl_compare_t cmp; - int c; - - if(!avlnode) - avlnode = &node; - - node = avltree->top; - - if(!node) - return *avlnode = NULL, 0; - - cmp = avltree->cmp; - - for(;;) { - c = cmp(item, node->item); - - if(c < 0) { - if(node->left) - node = node->left; - else - return *avlnode = node, -1; - } else if(c > 0) { - if(node->right) - node = node->right; - else - return *avlnode = node, 1; - } else { - return *avlnode = node, 0; - } - } -} - -/* - * avl_search: - * Return a pointer to a node with the given item in the tree. - * If no such item is in the tree, then NULL is returned. - */ -avl_node_t *avl_search(const avl_tree_t *avltree, const void *item) { - avl_node_t *node; - return avl_search_closest(avltree, item, &node) ? NULL : node; -} - -avl_tree_t *avl_init_tree(avl_tree_t *rc, avl_compare_t cmp, avl_freeitem_t freeitem) { - if(rc) { - rc->head = NULL; - rc->tail = NULL; - rc->top = NULL; - rc->cmp = cmp; - rc->freeitem = freeitem; - } - return rc; -} - -avl_tree_t *avl_alloc_tree(avl_compare_t cmp, avl_freeitem_t freeitem) { - return avl_init_tree(malloc(sizeof(avl_tree_t)), cmp, freeitem); -} - -void avl_clear_tree(avl_tree_t *avltree) { - avltree->top = avltree->head = avltree->tail = NULL; -} - -void avl_free_nodes(avl_tree_t *avltree) { - avl_node_t *node, *next; - avl_freeitem_t freeitem; - - freeitem = avltree->freeitem; - - for(node = avltree->head; node; node = next) { - next = node->next; - if(freeitem) - freeitem(node->item); - free(node); - } - - return avl_clear_tree(avltree); -} - -/* - * avl_free_tree: - * Free all memory used by this tree. If freeitem is not NULL, then - * it is assumed to be a destructor for the items referenced in the avl_ - * tree, and they are deleted as well. - */ -void avl_free_tree(avl_tree_t *avltree) { - avl_free_nodes(avltree); - free(avltree); -} - -static void avl_clear_node(avl_node_t *newnode) { - newnode->left = newnode->right = NULL; - #ifdef AVL_COUNT - newnode->count = 1; - #endif - #ifdef AVL_DEPTH - newnode->depth = 1; - #endif -} - -avl_node_t *avl_init_node(avl_node_t *newnode, void *item) { - if(newnode) { -/* avl_clear_node(newnode); */ - newnode->item = item; - } - return newnode; -} - -avl_node_t *avl_insert_top(avl_tree_t *avltree, avl_node_t *newnode) { - avl_clear_node(newnode); - newnode->prev = newnode->next = newnode->parent = NULL; - avltree->head = avltree->tail = avltree->top = newnode; - return newnode; -} - -avl_node_t *avl_insert_before(avl_tree_t *avltree, avl_node_t *node, avl_node_t *newnode) { - if(!node) - return avltree->tail - ? avl_insert_after(avltree, avltree->tail, newnode) - : avl_insert_top(avltree, newnode); - - if(node->left) - return avl_insert_after(avltree, node->prev, newnode); - - avl_clear_node(newnode); - - newnode->next = node; - newnode->parent = node; - - newnode->prev = node->prev; - if(node->prev) - node->prev->next = newnode; - else - avltree->head = newnode; - node->prev = newnode; - - node->left = newnode; - avl_rebalance(avltree, node); - return newnode; -} - -avl_node_t *avl_insert_after(avl_tree_t *avltree, avl_node_t *node, avl_node_t *newnode) { - if(!node) - return avltree->head - ? avl_insert_before(avltree, avltree->head, newnode) - : avl_insert_top(avltree, newnode); - - if(node->right) - return avl_insert_before(avltree, node->next, newnode); - - avl_clear_node(newnode); - - newnode->prev = node; - newnode->parent = node; - - newnode->next = node->next; - if(node->next) - node->next->prev = newnode; - else - avltree->tail = newnode; - node->next = newnode; - - node->right = newnode; - avl_rebalance(avltree, node); - return newnode; -} - -avl_node_t *avl_insert_node(avl_tree_t *avltree, avl_node_t *newnode) { - avl_node_t *node; - - if(!avltree->top) - return avl_insert_top(avltree, newnode); - - switch(avl_search_closest(avltree, newnode->item, &node)) { - case -1: - return avl_insert_before(avltree, node, newnode); - case 1: - return avl_insert_after(avltree, node, newnode); - } - - return NULL; -} - -/* - * avl_insert: - * Create a new node and insert an item there. - * Returns the new node on success or NULL if no memory could be allocated. - */ -avl_node_t *avl_insert(avl_tree_t *avltree, void *item) { - avl_node_t *newnode; - - newnode = avl_init_node(malloc(sizeof(avl_node_t)), item); - if(newnode) { - if(avl_insert_node(avltree, newnode)) - return newnode; - free(newnode); - errno = EEXIST; - } - return NULL; -} - -/* - * avl_unlink_node: - * Removes the given node. Does not delete the item at that node. - * The item of the node may be freed before calling avl_unlink_node. - * (In other words, it is not referenced by this function.) - */ -void avl_unlink_node(avl_tree_t *avltree, avl_node_t *avlnode) { - avl_node_t *parent; - avl_node_t **superparent; - avl_node_t *subst, *left, *right; - avl_node_t *balnode; - - if(avlnode->prev) - avlnode->prev->next = avlnode->next; - else - avltree->head = avlnode->next; - - if(avlnode->next) - avlnode->next->prev = avlnode->prev; - else - avltree->tail = avlnode->prev; - - parent = avlnode->parent; - - superparent = parent - ? avlnode == parent->left ? &parent->left : &parent->right - : &avltree->top; - - left = avlnode->left; - right = avlnode->right; - if(!left) { - *superparent = right; - if(right) - right->parent = parent; - balnode = parent; - } else if(!right) { - *superparent = left; - left->parent = parent; - balnode = parent; - } else { - subst = avlnode->prev; - if(subst == left) { - balnode = subst; - } else { - balnode = subst->parent; - balnode->right = subst->left; - if(balnode->right) - balnode->right->parent = balnode; - subst->left = left; - left->parent = subst; - } - subst->right = right; - subst->parent = parent; - right->parent = subst; - *superparent = subst; - } - - avl_rebalance(avltree, balnode); -} - -void *avl_delete_node(avl_tree_t *avltree, avl_node_t *avlnode) { - void *item = NULL; - if(avlnode) { - item = avlnode->item; - avl_unlink_node(avltree, avlnode); - if(avltree->freeitem) - avltree->freeitem(item); - free(avlnode); - } - return item; -} - -void *avl_delete(avl_tree_t *avltree, const void *item) { - return avl_delete_node(avltree, avl_search(avltree, item)); -} - -avl_node_t *avl_fixup_node(avl_tree_t *avltree, avl_node_t *newnode) { - avl_node_t *oldnode = NULL, *node; - - if(!avltree || !newnode) - return NULL; - - node = newnode->prev; - if(node) { - oldnode = node->next; - node->next = newnode; - } else { - avltree->head = newnode; - } - - node = newnode->next; - if(node) { - oldnode = node->prev; - node->prev = newnode; - } else { - avltree->tail = newnode; - } - - node = newnode->parent; - if(node) { - if(node->left == oldnode) - node->left = newnode; - else - node->right = newnode; - } else { - oldnode = avltree->top; - avltree->top = newnode; - } - - return oldnode; -} - -/* - * avl_rebalance: - * Rebalances the tree if one side becomes too heavy. This function - * assumes that both subtrees are AVL-trees with consistant data. The - * function has the additional side effect of recalculating the count of - * the tree at this node. It should be noted that at the return of this - * function, if a rebalance takes place, the top of this subtree is no - * longer going to be the same node. - */ -void avl_rebalance(avl_tree_t *avltree, avl_node_t *avlnode) { - avl_node_t *child; - avl_node_t *gchild; - avl_node_t *parent; - avl_node_t **superparent; - - parent = avlnode; - - while(avlnode) { - parent = avlnode->parent; - - superparent = parent - ? avlnode == parent->left ? &parent->left : &parent->right - : &avltree->top; - - switch(avl_check_balance(avlnode)) { - case -1: - child = avlnode->left; - #ifdef AVL_DEPTH - if(L_DEPTH(child) >= R_DEPTH(child)) { - #else - #ifdef AVL_COUNT - if(L_COUNT(child) >= R_COUNT(child)) { - #else - #error No balancing possible. - #endif - #endif - avlnode->left = child->right; - if(avlnode->left) - avlnode->left->parent = avlnode; - child->right = avlnode; - avlnode->parent = child; - *superparent = child; - child->parent = parent; - #ifdef AVL_COUNT - avlnode->count = CALC_COUNT(avlnode); - child->count = CALC_COUNT(child); - #endif - #ifdef AVL_DEPTH - avlnode->depth = CALC_DEPTH(avlnode); - child->depth = CALC_DEPTH(child); - #endif - } else { - gchild = child->right; - avlnode->left = gchild->right; - if(avlnode->left) - avlnode->left->parent = avlnode; - child->right = gchild->left; - if(child->right) - child->right->parent = child; - gchild->right = avlnode; - if(gchild->right) - gchild->right->parent = gchild; - gchild->left = child; - if(gchild->left) - gchild->left->parent = gchild; - *superparent = gchild; - gchild->parent = parent; - #ifdef AVL_COUNT - avlnode->count = CALC_COUNT(avlnode); - child->count = CALC_COUNT(child); - gchild->count = CALC_COUNT(gchild); - #endif - #ifdef AVL_DEPTH - avlnode->depth = CALC_DEPTH(avlnode); - child->depth = CALC_DEPTH(child); - gchild->depth = CALC_DEPTH(gchild); - #endif - } - break; - case 1: - child = avlnode->right; - #ifdef AVL_DEPTH - if(R_DEPTH(child) >= L_DEPTH(child)) { - #else - #ifdef AVL_COUNT - if(R_COUNT(child) >= L_COUNT(child)) { - #else - #error No balancing possible. - #endif - #endif - avlnode->right = child->left; - if(avlnode->right) - avlnode->right->parent = avlnode; - child->left = avlnode; - avlnode->parent = child; - *superparent = child; - child->parent = parent; - #ifdef AVL_COUNT - avlnode->count = CALC_COUNT(avlnode); - child->count = CALC_COUNT(child); - #endif - #ifdef AVL_DEPTH - avlnode->depth = CALC_DEPTH(avlnode); - child->depth = CALC_DEPTH(child); - #endif - } else { - gchild = child->left; - avlnode->right = gchild->left; - if(avlnode->right) - avlnode->right->parent = avlnode; - child->left = gchild->right; - if(child->left) - child->left->parent = child; - gchild->left = avlnode; - if(gchild->left) - gchild->left->parent = gchild; - gchild->right = child; - if(gchild->right) - gchild->right->parent = gchild; - *superparent = gchild; - gchild->parent = parent; - #ifdef AVL_COUNT - avlnode->count = CALC_COUNT(avlnode); - child->count = CALC_COUNT(child); - gchild->count = CALC_COUNT(gchild); - #endif - #ifdef AVL_DEPTH - avlnode->depth = CALC_DEPTH(avlnode); - child->depth = CALC_DEPTH(child); - gchild->depth = CALC_DEPTH(gchild); - #endif - } - break; - default: - #ifdef AVL_COUNT - avlnode->count = CALC_COUNT(avlnode); - #endif - #ifdef AVL_DEPTH - avlnode->depth = CALC_DEPTH(avlnode); - #endif - } - avlnode = parent; - } -} diff --git a/src/avl/avl.h b/src/avl/avl.h deleted file mode 100644 index 9662816e..00000000 --- a/src/avl/avl.h +++ /dev/null @@ -1,186 +0,0 @@ -/***************************************************************************** - - avl.h - Source code for the AVL-tree library. - - Copyright (C) 1998 Michael H. Buselli - Copyright (C) 2000-2002 Wessel Dankers - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Augmented AVL-tree. Original by Michael H. Buselli . - - Modified by Wessel Dankers to add a bunch of bloat to - the sourcecode, change the interface and squash a few bugs. - Mail him if you find new bugs. - -*****************************************************************************/ - -#ifndef _AVL_H -#define _AVL_H - -/* We need either depths, counts or both (the latter being the default) */ -#if !defined(AVL_DEPTH) && !defined(AVL_COUNT) -#define AVL_DEPTH -#define AVL_COUNT -#endif - -/* User supplied function to compare two items like strcmp() does. - * For example: cmp(a,b) will return: - * -1 if a < b - * 0 if a = b - * 1 if a > b - */ -typedef int (*avl_compare_t)(const void *, const void *); - -/* User supplied function to delete an item when a node is free()d. - * If NULL, the item is not free()d. - */ -typedef void (*avl_freeitem_t)(void *); - -typedef struct avl_node_t { - struct avl_node_t *next; - struct avl_node_t *prev; - struct avl_node_t *parent; - struct avl_node_t *left; - struct avl_node_t *right; - void *item; -#ifdef AVL_COUNT - unsigned int count; -#endif -#ifdef AVL_DEPTH - unsigned char depth; -#endif -} avl_node_t; - -typedef struct avl_tree_t { - avl_node_t *head; - avl_node_t *tail; - avl_node_t *top; - avl_compare_t cmp; - avl_freeitem_t freeitem; -} avl_tree_t; - -/* Initializes a new tree for elements that will be ordered using - * the supplied strcmp()-like function. - * Returns the value of avltree (even if it's NULL). - * O(1) */ -extern avl_tree_t *avl_init_tree(avl_tree_t *avltree, avl_compare_t, avl_freeitem_t); - -/* Allocates and initializes a new tree for elements that will be - * ordered using the supplied strcmp()-like function. - * Returns NULL if memory could not be allocated. - * O(1) */ -extern avl_tree_t *avl_alloc_tree(avl_compare_t, avl_freeitem_t); - -/* Frees the entire tree efficiently. Nodes will be free()d. - * If the tree's freeitem is not NULL it will be invoked on every item. - * O(n) */ -extern void avl_free_tree(avl_tree_t *); - -/* Reinitializes the tree structure for reuse. Nothing is free()d. - * Compare and freeitem functions are left alone. - * O(1) */ -extern void avl_clear_tree(avl_tree_t *); - -/* Free()s all nodes in the tree but leaves the tree itself. - * If the tree's freeitem is not NULL it will be invoked on every item. - * O(n) */ -extern void avl_free_nodes(avl_tree_t *); - -/* Initializes memory for use as a node. Returns NULL if avlnode is NULL. - * O(1) */ -extern avl_node_t *avl_init_node(avl_node_t *avlnode, void *item); - -/* Insert an item into the tree and return the new node. - * Returns NULL and sets errno if memory for the new node could not be - * allocated or if the node is already in the tree (EEXIST). - * O(lg n) */ -extern avl_node_t *avl_insert(avl_tree_t *, void *item); - -/* Insert a node into the tree and return it. - * Returns NULL if the node is already in the tree. - * O(lg n) */ -extern avl_node_t *avl_insert_node(avl_tree_t *, avl_node_t *); - -/* Insert a node in an empty tree. If avlnode is NULL, the tree will be - * cleared and ready for re-use. - * If the tree is not empty, the old nodes are left dangling. - * O(1) */ -extern avl_node_t *avl_insert_top(avl_tree_t *, avl_node_t *avlnode); - -/* Insert a node before another node. Returns the new node. - * If old is NULL, the item is appended to the tree. - * O(lg n) */ -extern avl_node_t *avl_insert_before(avl_tree_t *, avl_node_t *old, avl_node_t *new); - -/* Insert a node after another node. Returns the new node. - * If old is NULL, the item is prepended to the tree. - * O(lg n) */ -extern avl_node_t *avl_insert_after(avl_tree_t *, avl_node_t *old, avl_node_t *new); - -/* Deletes a node from the tree. Returns immediately if the node is NULL. - * The item will not be free()d regardless of the tree's freeitem handler. - * This function comes in handy if you need to update the search key. - * O(lg n) */ -extern void avl_unlink_node(avl_tree_t *, avl_node_t *); - -/* Deletes a node from the tree. Returns immediately if the node is NULL. - * If the tree's freeitem is not NULL, it is invoked on the item. - * If it is, returns the item. - * O(lg n) */ -extern void *avl_delete_node(avl_tree_t *, avl_node_t *); - -/* Searches for an item in the tree and deletes it if found. - * If the tree's freeitem is not NULL, it is invoked on the item. - * If it is, returns the item. - * O(lg n) */ -extern void *avl_delete(avl_tree_t *, const void *item); - -/* If exactly one node is moved in memory, this will fix the pointers - * in the tree that refer to it. It must be an exact shallow copy. - * Returns the pointer to the old position. - * O(1) */ -extern avl_node_t *avl_fixup_node(avl_tree_t *, avl_node_t *new); - -/* Searches for a node with the key closest (or equal) to the given item. - * If avlnode is not NULL, *avlnode will be set to the node found or NULL - * if the tree is empty. Return values: - * -1 if the returned node is smaller - * 0 if the returned node is equal or if the tree is empty - * 1 if the returned node is greater - * O(lg n) */ -extern int avl_search_closest(const avl_tree_t *, const void *item, avl_node_t **avlnode); - -/* Searches for the item in the tree and returns a matching node if found - * or NULL if not. - * O(lg n) */ -extern avl_node_t *avl_search(const avl_tree_t *, const void *item); - -#ifdef AVL_COUNT -/* Returns the number of nodes in the tree. - * O(1) */ -extern unsigned int avl_count(const avl_tree_t *); - -/* Searches a node by its rank in the list. Counting starts at 0. - * Returns NULL if the index exceeds the number of nodes in the tree. - * O(lg n) */ -extern avl_node_t *avl_at(const avl_tree_t *, unsigned int); - -/* Returns the rank of a node in the list. Counting starts at 0. - * O(lg n) */ -extern unsigned int avl_index(const avl_node_t *); -#endif - -#endif