/* * Copyright (C) 1995 Sam Rushing <rushing@nightmare.com>, * Copyright (C) 2012-2018 Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org> */ /* $Id: avl.h,v 1.7 2003/07/07 01:10:14 brendan Exp $ */ #ifndef _LIBIGLOO__AVL_H_ #define _LIBIGLOO__AVL_H_ #ifdef __cplusplus extern "C" { #endif #include <igloo/config.h> #define AVL_KEY_PRINTER_BUFLEN (256) #include <igloo/thread.h> typedef struct igloo_avl_node_tag { void * key; struct igloo_avl_node_tag * left; struct igloo_avl_node_tag * right; struct igloo_avl_node_tag * parent; /* * The lower 2 bits of <rank_and_balance> specify the balance * factor: 00==-1, 01==0, 10==+1. * The rest of the bits are used for <rank> */ unsigned int rank_and_balance; #if defined(IGLOO_CTC_HAVE_AVL_NODE_LOCK) igloo_rwlock_t rwlock; #endif } igloo_avl_node; #define AVL_GET_BALANCE(n) ((int)(((n)->rank_and_balance & 3) - 1)) #define AVL_GET_RANK(n) (((n)->rank_and_balance >> 2)) #define AVL_SET_BALANCE(n,b) \ ((n)->rank_and_balance) = \ (((n)->rank_and_balance & (~3)) | ((int)((b) + 1))) #define AVL_SET_RANK(n,r) \ ((n)->rank_and_balance) = \ (((n)->rank_and_balance & 3) | (r << 2)) struct igloo__avl_tree; typedef int (*igloo_avl_key_compare_fun_type) (void * compare_arg, void * a, void * b); typedef int (*igloo_avl_iter_fun_type) (void * key, void * iter_arg); typedef int (*igloo_avl_iter_index_fun_type) (unsigned long index, void * key, void * iter_arg); typedef int (*igloo_avl_free_key_fun_type) (void * key); typedef int (*igloo_avl_key_printer_fun_type) (char *, void *); /* * <compare_fun> and <compare_arg> let us associate a particular compare * function with each tree, separately. */ typedef struct igloo__avl_tree { igloo_avl_node * root; unsigned int height; unsigned int length; igloo_avl_key_compare_fun_type compare_fun; void * compare_arg; igloo_rwlock_t rwlock; } igloo_avl_tree; igloo_avl_tree * igloo_avl_tree_new (igloo_avl_key_compare_fun_type compare_fun, void * compare_arg); igloo_avl_node * igloo_avl_node_new (void * key, igloo_avl_node * parent); void igloo_avl_tree_free ( igloo_avl_tree * tree, igloo_avl_free_key_fun_type free_key_fun ); int igloo_avl_insert ( igloo_avl_tree * ob, void * key ); int igloo_avl_delete ( igloo_avl_tree * tree, void * key, igloo_avl_free_key_fun_type free_key_fun ); int igloo_avl_get_by_index ( igloo_avl_tree * tree, unsigned long index, void ** value_address ); int igloo_avl_get_by_key ( igloo_avl_tree * tree, void * key, void ** value_address ); int igloo_avl_iterate_inorder ( igloo_avl_tree * tree, igloo_avl_iter_fun_type iter_fun, void * iter_arg ); int igloo_avl_iterate_index_range ( igloo_avl_tree * tree, igloo_avl_iter_index_fun_type iter_fun, unsigned long low, unsigned long high, void * iter_arg ); int igloo_avl_get_span_by_key ( igloo_avl_tree * tree, void * key, unsigned long * low, unsigned long * high ); int igloo_avl_get_span_by_two_keys ( igloo_avl_tree * tree, void * key_a, void * key_b, unsigned long * low, unsigned long * high ); int igloo_avl_verify (igloo_avl_tree * tree); void igloo_avl_print_tree ( igloo_avl_tree * tree, igloo_avl_key_printer_fun_type key_printer ); igloo_avl_node *igloo_avl_get_first(igloo_avl_tree *tree); igloo_avl_node *igloo_avl_get_prev(igloo_avl_node * node); igloo_avl_node *igloo_avl_get_next(igloo_avl_node * node); /* These two are from David Ascher <david_ascher@brown.edu> */ int igloo_avl_get_item_by_key_most ( igloo_avl_tree * tree, void * key, void ** value_address ); int igloo_avl_get_item_by_key_least ( igloo_avl_tree * tree, void * key, void ** value_address ); /* optional locking stuff */ void igloo_avl_tree_rlock(igloo_avl_tree *tree); void igloo_avl_tree_wlock(igloo_avl_tree *tree); void igloo_avl_tree_unlock(igloo_avl_tree *tree); void avl_node_rlock(igloo_avl_node *node); void avl_node_wlock(igloo_avl_node *node); void avl_node_unlock(igloo_avl_node *node); #ifdef __cplusplus } #endif #endif /* __AVL_H */