/*
avl_tree.c -- avl_ tree and linked list convenience
Copyright (C) 1998 Michael H. Buselli
- 2000-2003 Ivo Timmermans <ivo@o2w.nl>,
- 2000-2003 Guus Sliepen <guus@sliepen.eu.org>
- 2000-2003 Wessel Dankers <wsl@nl.linux.org>
+ 2000-2005 Ivo Timmermans,
+ 2000-2006 Guus Sliepen <guus@tinc-vpn.org>
+ 2000-2005 Wessel Dankers <wsl@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Original AVL tree library by Michael H. Buselli <cosine@cosine.org>.
- Modified 2000-11-28 by Wessel Dankers <wsl@nl.linux.org> to use counts
+ Modified 2000-11-28 by Wessel Dankers <wsl@tinc-vpn.org> to use counts
instead of depths, to add the ->next and ->prev and to generally obfuscate
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
- Guus Sliepen <guus@sliepen.eu.org>.
+ library for inclusion into tinc (http://www.tinc-vpn.org/) by
+ Guus Sliepen <guus@tinc-vpn.org>.
- $Id: avl_tree.c,v 1.1.2.15 2003/07/12 17:48:38 guus Exp $
+ $Id$
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <xalloc.h>
+#include "system.h"
#include "avl_tree.h"
+#include "xalloc.h"
#ifdef AVL_COUNT
#define AVL_NODE_COUNT(n) ((n) ? (n)->count : 0)
#endif
#ifndef AVL_DEPTH
-static int lg(unsigned int u) __attribute__ ((const));
+static int lg(unsigned int u) __attribute__ ((__const__));
-static int lg(unsigned int u)
-{
+static int lg(unsigned int u) {
int r = 1;
if(!u)
/* Internal helper functions */
-static int avl_check_balance(avl_node_t *node)
-{
+static int avl_check_balance(const avl_node_t *node) {
#ifdef AVL_DEPTH
int d;
#endif
}
-static void avl_rebalance(avl_tree_t *tree, avl_node_t *node)
-{
+static void avl_rebalance(avl_tree_t *tree, avl_node_t *node) {
avl_node_t *child;
avl_node_t *gchild;
avl_node_t *parent;
/* (De)constructors */
-avl_tree_t *avl_alloc_tree(avl_compare_t compare, avl_action_t delete)
-{
+avl_tree_t *avl_alloc_tree(avl_compare_t compare, avl_action_t delete) {
avl_tree_t *tree;
tree = xmalloc_and_zero(sizeof(avl_tree_t));
return tree;
}
-void avl_free_tree(avl_tree_t *tree)
-{
+void avl_free_tree(avl_tree_t *tree) {
free(tree);
}
-avl_node_t *avl_alloc_node(void)
-{
- return (avl_node_t *)xmalloc_and_zero(sizeof(avl_node_t));
+avl_node_t *avl_alloc_node(void) {
+ return xmalloc_and_zero(sizeof(avl_node_t));
}
-void avl_free_node(avl_tree_t *tree, avl_node_t *node)
-{
+void avl_free_node(avl_tree_t *tree, avl_node_t *node) {
if(node->data && tree->delete)
tree->delete(node->data);
/* Searching */
-void *avl_search(const avl_tree_t *tree, const void *data)
-{
+void *avl_search(const avl_tree_t *tree, const void *data) {
avl_node_t *node;
node = avl_search_node(tree, data);
return node ? node->data : NULL;
}
-void *avl_search_closest(const avl_tree_t *tree, const void *data, int *result)
-{
+void *avl_search_closest(const avl_tree_t *tree, const void *data, int *result) {
avl_node_t *node;
node = avl_search_closest_node(tree, data, result);
return node ? node->data : NULL;
}
-void *avl_search_closest_smaller(const avl_tree_t *tree, const void *data)
-{
+void *avl_search_closest_smaller(const avl_tree_t *tree, const void *data) {
avl_node_t *node;
node = avl_search_closest_smaller_node(tree, data);
return node ? node->data : NULL;
}
-void *avl_search_closest_greater(const avl_tree_t *tree, const void *data)
-{
+void *avl_search_closest_greater(const avl_tree_t *tree, const void *data) {
avl_node_t *node;
node = avl_search_closest_greater_node(tree, data);
return node ? node->data : NULL;
}
-avl_node_t *avl_search_node(const avl_tree_t *tree, const void *data)
-{
+avl_node_t *avl_search_node(const avl_tree_t *tree, const void *data) {
avl_node_t *node;
int result;
}
avl_node_t *avl_search_closest_node(const avl_tree_t *tree, const void *data,
- int *result)
-{
+ int *result) {
avl_node_t *node;
int c;
}
avl_node_t *avl_search_closest_smaller_node(const avl_tree_t *tree,
- const void *data)
-{
+ const void *data) {
avl_node_t *node;
int result;
}
avl_node_t *avl_search_closest_greater_node(const avl_tree_t *tree,
- const void *data)
-{
+ const void *data) {
avl_node_t *node;
int result;
/* Insertion and deletion */
-avl_node_t *avl_insert(avl_tree_t *tree, void *data)
-{
+avl_node_t *avl_insert(avl_tree_t *tree, void *data) {
avl_node_t *closest, *new;
int result;
return new;
}
-avl_node_t *avl_insert_node(avl_tree_t *tree, avl_node_t *node)
-{
+avl_node_t *avl_insert_node(avl_tree_t *tree, avl_node_t *node) {
avl_node_t *closest;
int result;
return node;
}
-void avl_insert_top(avl_tree_t *tree, avl_node_t *node)
-{
+void avl_insert_top(avl_tree_t *tree, avl_node_t *node) {
node->prev = node->next = node->parent = NULL;
tree->head = tree->tail = tree->root = node;
}
void avl_insert_before(avl_tree_t *tree, avl_node_t *before,
- avl_node_t *node)
-{
+ avl_node_t *node) {
if(!before) {
if(tree->tail)
avl_insert_after(tree, tree->tail, node);
avl_rebalance(tree, before);
}
-void avl_insert_after(avl_tree_t *tree, avl_node_t *after, avl_node_t *node)
-{
+void avl_insert_after(avl_tree_t *tree, avl_node_t *after, avl_node_t *node) {
if(!after) {
if(tree->head)
avl_insert_before(tree, tree->head, node);
avl_rebalance(tree, after);
}
-avl_node_t *avl_unlink(avl_tree_t *tree, void *data)
-{
+avl_node_t *avl_unlink(avl_tree_t *tree, void *data) {
avl_node_t *node;
node = avl_search_node(tree, data);
return node;
}
-void avl_unlink_node(avl_tree_t *tree, avl_node_t *node)
-{
+void avl_unlink_node(avl_tree_t *tree, avl_node_t *node) {
avl_node_t *parent;
avl_node_t **superparent;
avl_node_t *subst, *left, *right;
#endif
}
-void avl_delete_node(avl_tree_t *tree, avl_node_t *node)
-{
+void avl_delete_node(avl_tree_t *tree, avl_node_t *node) {
avl_unlink_node(tree, node);
avl_free_node(tree, node);
}
-void avl_delete(avl_tree_t *tree, void *data)
-{
+void avl_delete(avl_tree_t *tree, void *data) {
avl_node_t *node;
node = avl_search_node(tree, data);
/* Fast tree cleanup */
-void avl_delete_tree(avl_tree_t *tree)
-{
+void avl_delete_tree(avl_tree_t *tree) {
avl_node_t *node, *next;
- for(node = tree->root; node; node = next) {
+ for(node = tree->head; node; node = next) {
next = node->next;
avl_free_node(tree, node);
}
/* Tree walking */
-void avl_foreach(avl_tree_t *tree, avl_action_t action)
-{
+void avl_foreach(const avl_tree_t *tree, avl_action_t action) {
avl_node_t *node, *next;
for(node = tree->head; node; node = next) {
}
}
-void avl_foreach_node(avl_tree_t *tree, avl_action_t action)
-{
+void avl_foreach_node(const avl_tree_t *tree, avl_action_t action) {
avl_node_t *node, *next;
for(node = tree->head; node; node = next) {
/* Indexing */
#ifdef AVL_COUNT
-unsigned int avl_count(avl_tree_t *tree)
-{
+unsigned int avl_count(const avl_tree_t *tree) {
return AVL_NODE_COUNT(tree->root);
}
-avl_node_t *avl_get_node(const avl_tree_t *tree, unsigned int index)
-{
+avl_node_t *avl_get_node(const avl_tree_t *tree, unsigned int index) {
avl_node_t *node;
unsigned int c;
return NULL;
}
-unsigned int avl_index(const avl_node_t *node)
-{
+unsigned int avl_index(const avl_node_t *node) {
avl_node_t *next;
unsigned int index;
}
#endif
#ifdef AVL_DEPTH
-unsigned int avl_depth(avl_tree_t *tree)
-{
+unsigned int avl_depth(const avl_tree_t *tree) {
return AVL_NODE_DEPTH(tree->root);
}
#endif