diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2013-02-13 22:03:54 +0000 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2013-02-13 22:03:54 +0000 |
commit | 08b970a5aba99783337d8c577323573125019fd9 (patch) | |
tree | 0cd849b178a51eb0698a674e23ec3112401c090e | |
parent | 7acd59db885896d5819cdef30d630901c1344e1f (diff) | |
download | libsunavl-08b970a5aba99783337d8c577323573125019fd9.tar.gz |
libsunavl version 1.1upstream/1.1
Fixed conflicts with system sys/avl.h header
(which in turn should be patched too)
-rw-r--r-- | Makefile.am | 8 | ||||
-rw-r--r-- | Makefile.in | 8 | ||||
-rw-r--r-- | avl_data.h (renamed from usr/src/uts/common/sys/avl_impl.h) | 33 | ||||
-rwxr-xr-x | configure | 36 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | libsunavl.h | 226 | ||||
-rw-r--r-- | ltmain.sh | 4 | ||||
-rw-r--r-- | m4/libtool.m4 | 16 | ||||
-rw-r--r-- | usr/src/common/avl/avl.c | 8 | ||||
-rw-r--r-- | usr/src/uts/common/sys/avl.h | 307 |
10 files changed, 293 insertions, 355 deletions
diff --git a/Makefile.am b/Makefile.am index fcc2fbe..985640d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,8 +4,8 @@ lib_LTLIBRARIES = libsunavl.la libsunavl_la_SOURCES = \ usr/src/common/avl/avl.c \ -usr/src/uts/common/sys/avl.h \ -usr/src/uts/common/sys/avl_impl.h +libsunavl.h \ +avl_data.h # VERSION_SCRIPT is defined in linker supports # symbol versioning and versioning is enabled. @@ -17,13 +17,11 @@ libsunavl_la_LDFLAGS += $(VERSION_SCRIPT_FLAGS)$(top_srcdir)/libsunavl.vers endif AM_CPPFLAGS = \ --I$(top_srcdir)/usr/src/uts/common/sys \ $(CPPFLAGS_DEBUG) libsunavldir = $(includedir)/libsunavl libsunavl_HEADERS = \ -usr/src/uts/common/sys/avl.h \ -usr/src/uts/common/sys/avl_impl.h +avl_data.h include_HEADERS = libsunavl.h diff --git a/Makefile.in b/Makefile.in index e98963d..f8ddbf6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -262,8 +262,8 @@ ACLOCAL_AMFLAGS = -I m4 lib_LTLIBRARIES = libsunavl.la libsunavl_la_SOURCES = \ usr/src/common/avl/avl.c \ -usr/src/uts/common/sys/avl.h \ -usr/src/uts/common/sys/avl_impl.h +libsunavl.h \ +avl_data.h # VERSION_SCRIPT is defined in linker supports @@ -271,13 +271,11 @@ usr/src/uts/common/sys/avl_impl.h # Otherwise VERSION_SCRIPT is empty. libsunavl_la_LDFLAGS = -version-info 2:0:0 $(am__append_1) AM_CPPFLAGS = \ --I$(top_srcdir)/usr/src/uts/common/sys \ $(CPPFLAGS_DEBUG) libsunavldir = $(includedir)/libsunavl libsunavl_HEADERS = \ -usr/src/uts/common/sys/avl.h \ -usr/src/uts/common/sys/avl_impl.h +avl_data.h include_HEADERS = libsunavl.h EXTRA_DIST = libsunavl.vers LICENSE diff --git a/usr/src/uts/common/sys/avl_impl.h b/avl_data.h index 6a2cc08..17ec7a3 100644 --- a/usr/src/uts/common/sys/avl_impl.h +++ b/avl_data.h @@ -23,22 +23,23 @@ * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - -#ifndef _LIBSUNAVL_AVL_IMPL_H -#define _LIBSUNAVL_AVL_IMPL_H - /* - * This is a private header file. Applications should not directly include - * this file. + * Portions copyright 2013 Igor Pashev <pashev.igor@gmail.com> */ +#ifndef _LIBSUNAVL_AVL_DATA_H +#define _LIBSUNAVL_AVL_DATA_H + +#include <stddef.h> +#include <inttypes.h> + #ifdef __cplusplus extern "C" { #endif /* - * generic AVL tree implementation for kernel use + * generic AVL tree implementation * * There are 5 pieces of information stored for each node in an AVL tree * @@ -147,14 +148,26 @@ struct avl_tree { size_t avl_size; /* sizeof user type struct */ }; +/* + * Type used for the root of the AVL tree. + */ +typedef struct avl_tree avl_tree_t; /* - * This will only by used via AVL_NEXT() or AVL_PREV() + * The data nodes in the AVL tree must have a field of this type. */ -extern void *avl_walk(struct avl_tree *, void *, int); +typedef struct avl_node avl_node_t; + +/* + * An opaque type used to locate a position in the tree where a node + * would be inserted. + */ +typedef uintptr_t avl_index_t; + #ifdef __cplusplus } #endif -#endif /* _LIBSUNAVL_AVL_IMPL_H */ +#endif /* _LIBSUNAVL_AVL_DATA_H */ + @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for libsunavl 1.0. +# Generated by GNU Autoconf 2.69 for libsunavl 1.1. # # Report bugs to <pashev.igor@gmail.com>. # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libsunavl' PACKAGE_TARNAME='libsunavl' -PACKAGE_VERSION='1.0' -PACKAGE_STRING='libsunavl 1.0' +PACKAGE_VERSION='1.1' +PACKAGE_STRING='libsunavl 1.1' PACKAGE_BUGREPORT='pashev.igor@gmail.com' PACKAGE_URL='' @@ -1309,7 +1309,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures libsunavl 1.0 to adapt to many kinds of systems. +\`configure' configures libsunavl 1.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1379,7 +1379,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libsunavl 1.0:";; + short | recursive ) echo "Configuration of libsunavl 1.1:";; esac cat <<\_ACEOF @@ -1481,7 +1481,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libsunavl configure 1.0 +libsunavl configure 1.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1759,7 +1759,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libsunavl $as_me 1.0, which was +It was created by libsunavl $as_me 1.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2576,7 +2576,7 @@ fi # Define the identity of the package. PACKAGE='libsunavl' - VERSION='1.0' + VERSION='1.1' cat >>confdefs.h <<_ACEOF @@ -4677,7 +4677,8 @@ else ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len"; then + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else @@ -6214,7 +6215,14 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) - LD="${LD-ld} -m elf_i386" + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" @@ -6311,7 +6319,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; } case $lt_cv_prog_gnu_ld in yes*) case $host in - i?86-*-solaris*) + i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) @@ -8671,7 +8679,7 @@ _LT_EOF archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; - gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu | solaris*) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in @@ -11968,7 +11976,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libsunavl $as_me 1.0, which was +This file was extended by libsunavl $as_me 1.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12025,7 +12033,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -libsunavl config.status 1.0 +libsunavl config.status 1.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 6f7aded..e401135 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) -AC_INIT([libsunavl], [1.0], [pashev.igor@gmail.com]) +AC_INIT([libsunavl], [1.1], [pashev.igor@gmail.com]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_SRCDIR([usr/src/common/avl/avl.c]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) diff --git a/libsunavl.h b/libsunavl.h index 868cc23..4e0a2b4 100644 --- a/libsunavl.h +++ b/libsunavl.h @@ -1,3 +1,33 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * Portions copyright 2013 Igor Pashev <pashev.igor@gmail.com> + */ + /* Just a wrapper, but intended to be the only public interface */ #ifndef _LIBSUNAVL_H @@ -6,8 +36,200 @@ #include <stddef.h> #include <inttypes.h> -#include <libsunavl/avl_impl.h> -#include <libsunavl/avl.h> +/* To avoid conflicts with sys/avl.h */ +#ifndef _AVL_DATA_DEFINED +# define _AVL_DATA_DEFINED +# include <libsunavl/avl_data.h> +#endif + +/* + * Prototypes + * + * Where not otherwise mentioned, "void *" arguments are a pointer to the + * user data structure which must contain a field of type avl_node_t. + * + * Also assume the user data structures looks like: + * stuct my_type { + * ... + * avl_node_t my_link; + * ... + * }; + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Initialize an AVL tree. Arguments are: + * + * tree - the tree to be initialized + * compar - function to compare two nodes, it must return exactly: -1, 0, or +1 + * -1 for <, 0 for ==, and +1 for > + * size - the value of sizeof(struct my_type) + * offset - the value of OFFSETOF(struct my_type, my_link) + */ +extern void avl_create(avl_tree_t *tree, + int (*compar) (const void *, const void *), size_t size, size_t offset); + + +/* + * Find a node with a matching value in the tree. Returns the matching node + * found. If not found, it returns NULL and then if "where" is not NULL it sets + * "where" for use with avl_insert() or avl_nearest(). + * + * node - node that has the value being looked for + * where - position for use with avl_nearest() or avl_insert(), may be NULL + */ +extern void *avl_find(avl_tree_t *tree, const void *node, avl_index_t *where); + +/* + * Insert a node into the tree. + * + * node - the node to insert + * where - position as returned from avl_find() + */ +extern void avl_insert(avl_tree_t *tree, void *node, avl_index_t where); + +/* + * Insert "new_data" in "tree" in the given "direction" either after + * or before the data "here". + * + * This might be usefull for avl clients caching recently accessed + * data to avoid doing avl_find() again for insertion. + * + * new_data - new data to insert + * here - existing node in "tree" + * direction - either AVL_AFTER or AVL_BEFORE the data "here". + */ +extern void avl_insert_here(avl_tree_t *tree, void *new_data, void *here, + int direction); + + +/* + * Return the first or last valued node in the tree. Will return NULL + * if the tree is empty. + * + */ +extern void *avl_first(avl_tree_t *tree); +extern void *avl_last(avl_tree_t *tree); + + +/* + * Return the next or previous valued node in the tree. + * AVL_NEXT() will return NULL if at the last node. + * AVL_PREV() will return NULL if at the first node. + * + * node - the node from which the next or previous node is found + */ +/* + * Direction constants used for avl_nearest(). + */ +#define AVL_BEFORE (0) +#define AVL_AFTER (1) +#define AVL_NEXT(tree, node) avl_walk(tree, node, AVL_AFTER) +#define AVL_PREV(tree, node) avl_walk(tree, node, AVL_BEFORE) +extern void *avl_walk(struct avl_tree *, void *, int); + +/* + * Find the node with the nearest value either greater or less than + * the value from a previous avl_find(). Returns the node or NULL if + * there isn't a matching one. + * + * where - position as returned from avl_find() + * direction - either AVL_BEFORE or AVL_AFTER + * + * EXAMPLE get the greatest node that is less than a given value: + * + * avl_tree_t *tree; + * struct my_data look_for_value = {....}; + * struct my_data *node; + * struct my_data *less; + * avl_index_t where; + * + * node = avl_find(tree, &look_for_value, &where); + * if (node != NULL) + * less = AVL_PREV(tree, node); + * else + * less = avl_nearest(tree, where, AVL_BEFORE); + */ +extern void *avl_nearest(avl_tree_t *tree, avl_index_t where, int direction); + + +/* + * Add a single node to the tree. + * The node must not be in the tree, and it must not + * compare equal to any other node already in the tree. + * + * node - the node to add + */ +extern void avl_add(avl_tree_t *tree, void *node); + + +/* + * Remove a single node from the tree. The node must be in the tree. + * + * node - the node to remove + */ +extern void avl_remove(avl_tree_t *tree, void *node); + +/* + * Reinsert a node only if its order has changed relative to its nearest + * neighbors. To optimize performance avl_update_lt() checks only the previous + * node and avl_update_gt() checks only the next node. Use avl_update_lt() and + * avl_update_gt() only if you know the direction in which the order of the + * node may change. + */ +extern int avl_update(avl_tree_t *, void *); +extern int avl_update_lt(avl_tree_t *, void *); +extern int avl_update_gt(avl_tree_t *, void *); + +/* + * Return the number of nodes in the tree + */ +extern size_t avl_numnodes(avl_tree_t *tree); + +/* + * Return 1 if there are zero nodes in the tree, 0 otherwise. + */ +extern int avl_is_empty(avl_tree_t *tree); + +/* + * Used to destroy any remaining nodes in a tree. The cookie argument should + * be initialized to NULL before the first call. Returns a node that has been + * removed from the tree and may be free()'d. Returns NULL when the tree is + * empty. + * + * Once you call avl_destroy_nodes(), you can only continuing calling it and + * finally avl_destroy(). No other AVL routines will be valid. + * + * cookie - a "void *" used to save state between calls to avl_destroy_nodes() + * + * EXAMPLE: + * avl_tree_t *tree; + * struct my_data *node; + * void *cookie; + * + * cookie = NULL; + * while ((node = avl_destroy_nodes(tree, &cookie)) != NULL) + * free(node); + * avl_destroy(tree); + */ +extern void *avl_destroy_nodes(avl_tree_t *tree, void **cookie); + + +/* + * Final destroy of an AVL tree. Arguments are: + * + * tree - the empty tree to destroy + */ +extern void avl_destroy(avl_tree_t *tree); + + + +#ifdef __cplusplus +} +#endif #endif @@ -70,7 +70,7 @@ # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) -# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1.1 +# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1.2+dyson1 # automake: $automake_version # autoconf: $autoconf_version # @@ -80,7 +80,7 @@ PROGRAM=libtool PACKAGE=libtool -VERSION="2.4.2 Debian-2.4.2-1.1" +VERSION="2.4.2 Debian-2.4.2-1.2+dyson1" TIMESTAMP="" package_revision=1.3337 diff --git a/m4/libtool.m4 b/m4/libtool.m4 index 534d1cc..a8fd50e 100644 --- a/m4/libtool.m4 +++ b/m4/libtool.m4 @@ -1324,7 +1324,14 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) - LD="${LD-ld} -m elf_i386" + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" @@ -1383,7 +1390,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) case $lt_cv_prog_gnu_ld in yes*) case $host in - i?86-*-solaris*) + i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) @@ -1688,7 +1695,8 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len"; then + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else @@ -4790,7 +4798,7 @@ _LT_EOF _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; - gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu | solaris*) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diff --git a/usr/src/common/avl/avl.c b/usr/src/common/avl/avl.c index 00cf2fa..fdb96bb 100644 --- a/usr/src/common/avl/avl.c +++ b/usr/src/common/avl/avl.c @@ -95,11 +95,9 @@ #define B_TRUE (1) #define B_FALSE (0) -#include <stddef.h> -#include <inttypes.h> - -#include "avl_impl.h" -#include "avl.h" +#include "avl_data.h" +#define _AVL_DATA_DEFINED +#include "libsunavl.h" /* * Small arrays to translate between balance (or diff) values and child indeces. diff --git a/usr/src/uts/common/sys/avl.h b/usr/src/uts/common/sys/avl.h deleted file mode 100644 index d7f0341..0000000 --- a/usr/src/uts/common/sys/avl.h +++ /dev/null @@ -1,307 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _LIBSUNAVL_AVL_H -#define _LIBSUNAVL_AVL_H - -/* - * This is a private header file. Applications should not directly include - * this file. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * This is a generic implemenatation of AVL trees for use in the Solaris kernel. - * The interfaces provide an efficient way of implementing an ordered set of - * data structures. - * - * AVL trees provide an alternative to using an ordered linked list. Using AVL - * trees will usually be faster, however they requires more storage. An ordered - * linked list in general requires 2 pointers in each data structure. The - * AVL tree implementation uses 3 pointers. The following chart gives the - * approximate performance of operations with the different approaches: - * - * Operation Link List AVL tree - * --------- -------- -------- - * lookup O(n) O(log(n)) - * - * insert 1 node constant constant - * - * delete 1 node constant between constant and O(log(n)) - * - * delete all nodes O(n) O(n) - * - * visit the next - * or prev node constant between constant and O(log(n)) - * - * - * The data structure nodes are anchored at an "avl_tree_t" (the equivalent - * of a list header) and the individual nodes will have a field of - * type "avl_node_t" (corresponding to list pointers). - * - * The type "avl_index_t" is used to indicate a position in the list for - * certain calls. - * - * The usage scenario is generally: - * - * 1. Create the list/tree with: avl_create() - * - * followed by any mixture of: - * - * 2a. Insert nodes with: avl_add(), or avl_find() and avl_insert() - * - * 2b. Visited elements with: - * avl_first() - returns the lowest valued node - * avl_last() - returns the highest valued node - * AVL_NEXT() - given a node go to next higher one - * AVL_PREV() - given a node go to previous lower one - * - * 2c. Find the node with the closest value either less than or greater - * than a given value with avl_nearest(). - * - * 2d. Remove individual nodes from the list/tree with avl_remove(). - * - * and finally when the list is being destroyed - * - * 3. Use avl_destroy_nodes() to quickly process/free up any remaining nodes. - * Note that once you use avl_destroy_nodes(), you can no longer - * use any routine except avl_destroy_nodes() and avl_destoy(). - * - * 4. Use avl_destroy() to destroy the AVL tree itself. - * - * Any locking for multiple thread access is up to the user to provide, just - * as is needed for any linked list implementation. - */ - - -/* - * Type used for the root of the AVL tree. - */ -typedef struct avl_tree avl_tree_t; - -/* - * The data nodes in the AVL tree must have a field of this type. - */ -typedef struct avl_node avl_node_t; - -/* - * An opaque type used to locate a position in the tree where a node - * would be inserted. - */ -typedef uintptr_t avl_index_t; - - -/* - * Direction constants used for avl_nearest(). - */ -#define AVL_BEFORE (0) -#define AVL_AFTER (1) - - -/* - * Prototypes - * - * Where not otherwise mentioned, "void *" arguments are a pointer to the - * user data structure which must contain a field of type avl_node_t. - * - * Also assume the user data structures looks like: - * stuct my_type { - * ... - * avl_node_t my_link; - * ... - * }; - */ - -/* - * Initialize an AVL tree. Arguments are: - * - * tree - the tree to be initialized - * compar - function to compare two nodes, it must return exactly: -1, 0, or +1 - * -1 for <, 0 for ==, and +1 for > - * size - the value of sizeof(struct my_type) - * offset - the value of OFFSETOF(struct my_type, my_link) - */ -extern void avl_create(avl_tree_t *tree, - int (*compar) (const void *, const void *), size_t size, size_t offset); - - -/* - * Find a node with a matching value in the tree. Returns the matching node - * found. If not found, it returns NULL and then if "where" is not NULL it sets - * "where" for use with avl_insert() or avl_nearest(). - * - * node - node that has the value being looked for - * where - position for use with avl_nearest() or avl_insert(), may be NULL - */ -extern void *avl_find(avl_tree_t *tree, const void *node, avl_index_t *where); - -/* - * Insert a node into the tree. - * - * node - the node to insert - * where - position as returned from avl_find() - */ -extern void avl_insert(avl_tree_t *tree, void *node, avl_index_t where); - -/* - * Insert "new_data" in "tree" in the given "direction" either after - * or before the data "here". - * - * This might be usefull for avl clients caching recently accessed - * data to avoid doing avl_find() again for insertion. - * - * new_data - new data to insert - * here - existing node in "tree" - * direction - either AVL_AFTER or AVL_BEFORE the data "here". - */ -extern void avl_insert_here(avl_tree_t *tree, void *new_data, void *here, - int direction); - - -/* - * Return the first or last valued node in the tree. Will return NULL - * if the tree is empty. - * - */ -extern void *avl_first(avl_tree_t *tree); -extern void *avl_last(avl_tree_t *tree); - - -/* - * Return the next or previous valued node in the tree. - * AVL_NEXT() will return NULL if at the last node. - * AVL_PREV() will return NULL if at the first node. - * - * node - the node from which the next or previous node is found - */ -#define AVL_NEXT(tree, node) avl_walk(tree, node, AVL_AFTER) -#define AVL_PREV(tree, node) avl_walk(tree, node, AVL_BEFORE) - - -/* - * Find the node with the nearest value either greater or less than - * the value from a previous avl_find(). Returns the node or NULL if - * there isn't a matching one. - * - * where - position as returned from avl_find() - * direction - either AVL_BEFORE or AVL_AFTER - * - * EXAMPLE get the greatest node that is less than a given value: - * - * avl_tree_t *tree; - * struct my_data look_for_value = {....}; - * struct my_data *node; - * struct my_data *less; - * avl_index_t where; - * - * node = avl_find(tree, &look_for_value, &where); - * if (node != NULL) - * less = AVL_PREV(tree, node); - * else - * less = avl_nearest(tree, where, AVL_BEFORE); - */ -extern void *avl_nearest(avl_tree_t *tree, avl_index_t where, int direction); - - -/* - * Add a single node to the tree. - * The node must not be in the tree, and it must not - * compare equal to any other node already in the tree. - * - * node - the node to add - */ -extern void avl_add(avl_tree_t *tree, void *node); - - -/* - * Remove a single node from the tree. The node must be in the tree. - * - * node - the node to remove - */ -extern void avl_remove(avl_tree_t *tree, void *node); - -/* - * Reinsert a node only if its order has changed relative to its nearest - * neighbors. To optimize performance avl_update_lt() checks only the previous - * node and avl_update_gt() checks only the next node. Use avl_update_lt() and - * avl_update_gt() only if you know the direction in which the order of the - * node may change. - */ -extern int avl_update(avl_tree_t *, void *); -extern int avl_update_lt(avl_tree_t *, void *); -extern int avl_update_gt(avl_tree_t *, void *); - -/* - * Return the number of nodes in the tree - */ -extern size_t avl_numnodes(avl_tree_t *tree); - -/* - * Return 1 if there are zero nodes in the tree, 0 otherwise. - */ -extern int avl_is_empty(avl_tree_t *tree); - -/* - * Used to destroy any remaining nodes in a tree. The cookie argument should - * be initialized to NULL before the first call. Returns a node that has been - * removed from the tree and may be free()'d. Returns NULL when the tree is - * empty. - * - * Once you call avl_destroy_nodes(), you can only continuing calling it and - * finally avl_destroy(). No other AVL routines will be valid. - * - * cookie - a "void *" used to save state between calls to avl_destroy_nodes() - * - * EXAMPLE: - * avl_tree_t *tree; - * struct my_data *node; - * void *cookie; - * - * cookie = NULL; - * while ((node = avl_destroy_nodes(tree, &cookie)) != NULL) - * free(node); - * avl_destroy(tree); - */ -extern void *avl_destroy_nodes(avl_tree_t *tree, void **cookie); - - -/* - * Final destroy of an AVL tree. Arguments are: - * - * tree - the empty tree to destroy - */ -extern void avl_destroy(avl_tree_t *tree); - - - -#ifdef __cplusplus -} -#endif - -#endif /* _LIBSUNAVL_AVL_H */ - |