summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2013-02-13 22:16:21 +0000
committerIgor Pashev <pashev.igor@gmail.com>2013-02-13 22:16:21 +0000
commit92473db50fb063177854655e24d544dc5941bc1e (patch)
tree92f356cd618e4cc90ddfb7eb2136484ea53b9407
parentc1d04a3502f317a653c80690a94c7d1c3797c8c1 (diff)
parent08b970a5aba99783337d8c577323573125019fd9 (diff)
downloadlibsunavl-92473db50fb063177854655e24d544dc5941bc1e.tar.gz
Merge upstream/1.1
-rw-r--r--Makefile.am8
-rw-r--r--Makefile.in8
-rw-r--r--avl_data.h (renamed from usr/src/uts/common/sys/avl_impl.h)33
-rwxr-xr-xconfigure36
-rw-r--r--configure.ac2
-rw-r--r--libsunavl.h226
-rw-r--r--ltmain.sh4
-rw-r--r--m4/libtool.m416
-rw-r--r--usr/src/common/avl/avl.c8
-rw-r--r--usr/src/uts/common/sys/avl.h307
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 */
+
diff --git a/configure b/configure
index 9a8de27..6a37c6f 100755
--- a/configure
+++ b/configure
@@ -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
diff --git a/ltmain.sh b/ltmain.sh
index 33f642a..5b05f5a 100644
--- a/ltmain.sh
+++ b/ltmain.sh
@@ -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 */
-