Blame src/avl/avl.h

Packit eed494
/*
Packit eed494
 * Copyright (C) 1995 by Sam Rushing <rushing@nightmare.com>
Packit eed494
 */
Packit eed494
Packit eed494
/* $Id: avl.h,v 1.7 2003/07/07 01:10:14 brendan Exp $ */
Packit eed494
Packit eed494
#ifndef __AVL_H
Packit eed494
#define __AVL_H
Packit eed494
Packit eed494
#ifdef __cplusplus
Packit eed494
extern "C" {
Packit eed494
#endif
Packit eed494
Packit eed494
#ifndef NO_THREAD
Packit eed494
#include <thread/thread.h>
Packit eed494
#else
Packit eed494
#define thread_rwlock_create(x) do{}while(0)
Packit eed494
#define thread_rwlock_destroy(x) do{}while(0)
Packit eed494
#define thread_rwlock_rlock(x) do{}while(0)
Packit eed494
#define thread_rwlock_wlock(x) do{}while(0)
Packit eed494
#define thread_rwlock_unlock(x) do{}while(0)
Packit eed494
#endif
Packit eed494
Packit eed494
typedef struct avl_node_tag {
Packit eed494
  void *        key;
Packit eed494
  struct avl_node_tag *    left;
Packit eed494
  struct avl_node_tag *    right;  
Packit eed494
  struct avl_node_tag *    parent;
Packit eed494
  /*
Packit eed494
   * The lower 2 bits of <rank_and_balance> specify the balance
Packit eed494
   * factor: 00==-1, 01==0, 10==+1.
Packit eed494
   * The rest of the bits are used for <rank>
Packit eed494
   */
Packit eed494
  unsigned long        rank_and_balance;
Packit eed494
#ifndef NO_THREAD
Packit eed494
  rwlock_t rwlock;
Packit eed494
#endif
Packit eed494
} avl_node;
Packit eed494
Packit eed494
#define AVL_GET_BALANCE(n)    ((int)(((n)->rank_and_balance & 3) - 1))
Packit eed494
Packit eed494
#define AVL_GET_RANK(n)    (((n)->rank_and_balance >> 2))
Packit eed494
Packit eed494
#define AVL_SET_BALANCE(n,b) \
Packit eed494
  ((n)->rank_and_balance) = \
Packit eed494
    (((n)->rank_and_balance & (~3)) | ((int)((b) + 1)))
Packit eed494
Packit eed494
#define AVL_SET_RANK(n,r) \
Packit eed494
  ((n)->rank_and_balance) = \
Packit eed494
    (((n)->rank_and_balance & 3) | (r << 2))
Packit eed494
Packit eed494
struct _avl_tree;
Packit eed494
Packit eed494
typedef int (*avl_key_compare_fun_type)    (void * compare_arg, void * a, void * b);
Packit eed494
typedef int (*avl_iter_fun_type)    (void * key, void * iter_arg);
Packit eed494
typedef int (*avl_iter_index_fun_type)    (unsigned long index, void * key, void * iter_arg);
Packit eed494
typedef int (*avl_free_key_fun_type)    (void * key);
Packit eed494
typedef int (*avl_key_printer_fun_type)    (char *, void *);
Packit eed494
Packit eed494
/*
Packit eed494
 * <compare_fun> and <compare_arg> let us associate a particular compare
Packit eed494
 * function with each tree, separately.
Packit eed494
 */
Packit eed494
Packit eed494
#ifdef _mangle
Packit eed494
# define avl_tree_new _mangle(avl_tree_new)
Packit eed494
# define avl_node_new _mangle(avl_node_new)
Packit eed494
# define avl_tree_free _mangle(avl_tree_free)
Packit eed494
# define avl_insert _mangle(avl_insert)
Packit eed494
# define avl_delete _mangle(avl_delete)
Packit eed494
# define avl_get_by_index _mangle(avl_get_by_index)
Packit eed494
# define avl_get_by_key _mangle(avl_get_by_key)
Packit eed494
# define avl_iterate_inorder _mangle(avl_iterate_inorder)
Packit eed494
# define avl_iterate_index_range _mangle(avl_iterate_index_range)
Packit eed494
# define avl_tree_rlock _mangle(avl_tree_rlock)
Packit eed494
# define avl_tree_wlock _mangle(avl_tree_wlock)
Packit eed494
# define avl_tree_wlock _mangle(avl_tree_wlock)
Packit eed494
# define avl_tree_unlock _mangle(avl_tree_unlock)
Packit eed494
# define avl_node_rlock _mangle(avl_node_rlock)
Packit eed494
# define avl_node_wlock _mangle(avl_node_wlock)
Packit eed494
# define avl_node_unlock _mangle(avl_node_unlock)
Packit eed494
# define avl_get_span_by_key _mangle(avl_get_span_by_key)
Packit eed494
# define avl_get_span_by_two_keys _mangle(avl_get_span_by_two_keys)
Packit eed494
# define avl_verify _mangle(avl_verify)
Packit eed494
# define avl_print_tree _mangle(avl_print_tree)
Packit eed494
# define avl_get_first _mangle(avl_get_first)
Packit eed494
# define avl_get_prev _mangle(avl_get_prev)
Packit eed494
# define avl_get_next _mangle(avl_get_next)
Packit eed494
# define avl_get_item_by_key_most _mangle(avl_get_item_by_key_most)
Packit eed494
# define avl_get_item_by_key_least _mangle(avl_get_item_by_key_least)
Packit eed494
#endif
Packit eed494
Packit eed494
typedef struct _avl_tree {
Packit eed494
  avl_node *            root;
Packit eed494
  unsigned long            height;
Packit eed494
  unsigned long            length;
Packit eed494
  avl_key_compare_fun_type    compare_fun;
Packit eed494
  void *             compare_arg;
Packit eed494
#ifndef NO_THREAD
Packit eed494
  rwlock_t rwlock;
Packit eed494
#endif
Packit eed494
} avl_tree;
Packit eed494
Packit eed494
avl_tree * avl_tree_new (avl_key_compare_fun_type compare_fun, void * compare_arg);
Packit eed494
avl_node * avl_node_new (void * key, avl_node * parent);
Packit eed494
Packit eed494
void avl_tree_free (
Packit eed494
  avl_tree *        tree,
Packit eed494
  avl_free_key_fun_type    free_key_fun
Packit eed494
  );
Packit eed494
Packit eed494
int avl_insert (
Packit eed494
  avl_tree *        ob,
Packit eed494
  void *        key
Packit eed494
  );
Packit eed494
Packit eed494
int avl_delete (
Packit eed494
  avl_tree *        tree,
Packit eed494
  void *        key,
Packit eed494
  avl_free_key_fun_type    free_key_fun
Packit eed494
  );
Packit eed494
Packit eed494
int avl_get_by_index (
Packit eed494
  avl_tree *        tree,
Packit eed494
  unsigned long        index,
Packit eed494
  void **        value_address
Packit eed494
  );
Packit eed494
Packit eed494
int avl_get_by_key (
Packit eed494
  avl_tree *        tree,
Packit eed494
  void *        key,
Packit eed494
  void **        value_address
Packit eed494
  );
Packit eed494
Packit eed494
int avl_iterate_inorder (
Packit eed494
  avl_tree *        tree,
Packit eed494
  avl_iter_fun_type    iter_fun,
Packit eed494
  void *        iter_arg
Packit eed494
  );
Packit eed494
Packit eed494
int avl_iterate_index_range (
Packit eed494
  avl_tree *        tree,
Packit eed494
  avl_iter_index_fun_type iter_fun,
Packit eed494
  unsigned long        low,
Packit eed494
  unsigned long        high,
Packit eed494
  void *        iter_arg
Packit eed494
  );
Packit eed494
Packit eed494
int avl_get_span_by_key (
Packit eed494
  avl_tree *        tree,
Packit eed494
  void *        key,
Packit eed494
  unsigned long *    low,
Packit eed494
  unsigned long *    high
Packit eed494
  );
Packit eed494
Packit eed494
int avl_get_span_by_two_keys (
Packit eed494
  avl_tree *        tree,
Packit eed494
  void *        key_a,
Packit eed494
  void *        key_b,
Packit eed494
  unsigned long *    low,
Packit eed494
  unsigned long *    high
Packit eed494
  );
Packit eed494
Packit eed494
int avl_verify (avl_tree * tree);
Packit eed494
Packit eed494
void avl_print_tree (
Packit eed494
  avl_tree *        tree,
Packit eed494
  avl_key_printer_fun_type key_printer
Packit eed494
  );
Packit eed494
Packit eed494
avl_node *avl_get_first(avl_tree *tree);
Packit eed494
Packit eed494
avl_node *avl_get_prev(avl_node * node);
Packit eed494
Packit eed494
avl_node *avl_get_next(avl_node * node);
Packit eed494
Packit eed494
/* These two are from David Ascher <david_ascher@brown.edu> */
Packit eed494
Packit eed494
int avl_get_item_by_key_most (
Packit eed494
  avl_tree *        tree,
Packit eed494
  void *        key,
Packit eed494
  void **        value_address
Packit eed494
  );
Packit eed494
Packit eed494
int avl_get_item_by_key_least (
Packit eed494
  avl_tree *        tree,
Packit eed494
  void *        key,
Packit eed494
  void **        value_address
Packit eed494
  );
Packit eed494
Packit eed494
/* optional locking stuff */
Packit eed494
void avl_tree_rlock(avl_tree *tree);
Packit eed494
void avl_tree_wlock(avl_tree *tree);
Packit eed494
void avl_tree_unlock(avl_tree *tree);
Packit eed494
void avl_node_rlock(avl_node *node);
Packit eed494
void avl_node_wlock(avl_node *node);
Packit eed494
void avl_node_unlock(avl_node *node);
Packit eed494
Packit eed494
#ifdef __cplusplus
Packit eed494
}
Packit eed494
#endif
Packit eed494
Packit eed494
#endif /* __AVL_H */