* Makefile.am (LIB_OBJECTLISTS): Add
libc/search/objectlist.awk.in. * libc/Makefile.am (SUBDIRS): Add search. (SUBLIBS): Add search/libsearch.la. * libc/configure.in (AC_OUTPUT): Add search/Makefile. * libc/search: New directory. * libc/search/Makefile.am: New file. * libc/search/extern.h: New file. * libc/search/hash.c: New file. * libc/search/hash.h: New file. * libc/search/hash_bigkey.c: New file. * libc/search/hash_buf.c: New file. * libc/search/hash_func.c: New file. * libc/search/hash_log2.c: New file. * libc/search/hash_page.c: New file. * libc/search/hcreate.3: New file. * libc/search/hcreate.c: New file. * libc/search/hcreate.c~: New file. * libc/search/hcreate_r.c: New file. * libc/search/ndbm.c: New file. * libc/search/page.h: New file. * libc/search/tdelete.c: New file. * libc/search/tdestroy.c: New file. * libc/search/tfind.c: New file. * libc/search/tsearch.3: New file. * libc/search/tsearch.c: New file. * libc/search/twalk.c: New file. * libc/include/db.h: New file. * libc/include/ndbm.h: New file. * libc/include/search.h: New file. * libc/include/sys/queue.h: New file. * libc/include/sys/cdefs.h: New file. * libc/include/sys/param.h [__IEEE_LITTLE_ENDIAN,__IEEE_BIG_ENDIAN]: Set BYTE_ORDER to LITTLE_ENDIAN or BIG_ENDIAN. * libc/include/sys/errno.h (EFTYPE): New macro. * libc/search/bsearch.c: Move from libc/stdlib. * libc/search/qsort.c: Likewise. * libc/stdlib/Makefile.am (LIB_SOURCES): Remove bsearch.c and qsort.c. (CHEWOUT_FILES): Remove bsearch.def and qsort.def. * libc/stdlib/stdlib.tex: Remove references to bsearch and qsort.
This commit is contained in:
parent
c25ebbaf55
commit
a7b23a8f11
@ -1,3 +1,48 @@
|
|||||||
|
2002-06-20 Thomas Fitzsimmons <fitzsim@redhat.com>
|
||||||
|
|
||||||
|
* Makefile.am (LIB_OBJECTLISTS): Add
|
||||||
|
libc/search/objectlist.awk.in.
|
||||||
|
* libc/Makefile.am (SUBDIRS): Add search.
|
||||||
|
(SUBLIBS): Add search/libsearch.la.
|
||||||
|
* libc/configure.in (AC_OUTPUT): Add search/Makefile.
|
||||||
|
* libc/search: New directory.
|
||||||
|
* libc/search/Makefile.am: New file.
|
||||||
|
* libc/search/extern.h: New file.
|
||||||
|
* libc/search/hash.c: New file.
|
||||||
|
* libc/search/hash.h: New file.
|
||||||
|
* libc/search/hash_bigkey.c: New file.
|
||||||
|
* libc/search/hash_buf.c: New file.
|
||||||
|
* libc/search/hash_func.c: New file.
|
||||||
|
* libc/search/hash_log2.c: New file.
|
||||||
|
* libc/search/hash_page.c: New file.
|
||||||
|
* libc/search/hcreate.3: New file.
|
||||||
|
* libc/search/hcreate.c: New file.
|
||||||
|
* libc/search/hcreate.c~: New file.
|
||||||
|
* libc/search/hcreate_r.c: New file.
|
||||||
|
* libc/search/ndbm.c: New file.
|
||||||
|
* libc/search/page.h: New file.
|
||||||
|
* libc/search/tdelete.c: New file.
|
||||||
|
* libc/search/tdestroy.c: New file.
|
||||||
|
* libc/search/tfind.c: New file.
|
||||||
|
* libc/search/tsearch.3: New file.
|
||||||
|
* libc/search/tsearch.c: New file.
|
||||||
|
* libc/search/twalk.c: New file.
|
||||||
|
* libc/include/db.h: New file.
|
||||||
|
* libc/include/ndbm.h: New file.
|
||||||
|
* libc/include/search.h: New file.
|
||||||
|
* libc/include/sys/queue.h: New file.
|
||||||
|
* libc/include/sys/cdefs.h: New file.
|
||||||
|
* libc/include/sys/param.h
|
||||||
|
[__IEEE_LITTLE_ENDIAN,__IEEE_BIG_ENDIAN]: Set BYTE_ORDER to
|
||||||
|
LITTLE_ENDIAN or BIG_ENDIAN.
|
||||||
|
* libc/include/sys/errno.h (EFTYPE): New macro.
|
||||||
|
* libc/search/bsearch.c: Move from libc/stdlib.
|
||||||
|
* libc/search/qsort.c: Likewise.
|
||||||
|
* libc/stdlib/Makefile.am (LIB_SOURCES): Remove bsearch.c and
|
||||||
|
qsort.c.
|
||||||
|
(CHEWOUT_FILES): Remove bsearch.def and qsort.def.
|
||||||
|
* libc/stdlib/stdlib.tex: Remove references to bsearch and qsort.
|
||||||
|
|
||||||
2002-06-19 Jeff Johnston <jjohnstn@redhat.com>
|
2002-06-19 Jeff Johnston <jjohnstn@redhat.com>
|
||||||
|
|
||||||
* libc/sys/linux/Makefile.am: Add support for message queue routines,
|
* libc/sys/linux/Makefile.am: Add support for message queue routines,
|
||||||
|
@ -107,6 +107,7 @@ LIBC_OBJECTLISTS = \
|
|||||||
libc/stdlib/objectlist.awk.in \
|
libc/stdlib/objectlist.awk.in \
|
||||||
libc/time/objectlist.awk.in \
|
libc/time/objectlist.awk.in \
|
||||||
libc/ctype/objectlist.awk.in \
|
libc/ctype/objectlist.awk.in \
|
||||||
|
libc/search/objectlist.awk.in \
|
||||||
libc/string/objectlist.awk.in \
|
libc/string/objectlist.awk.in \
|
||||||
libc/locale/objectlist.awk.in \
|
libc/locale/objectlist.awk.in \
|
||||||
libc/misc/objectlist.awk.in \
|
libc/misc/objectlist.awk.in \
|
||||||
|
@ -205,6 +205,7 @@ LIBC_OBJECTLISTS = \
|
|||||||
libc/stdlib/objectlist.awk.in \
|
libc/stdlib/objectlist.awk.in \
|
||||||
libc/time/objectlist.awk.in \
|
libc/time/objectlist.awk.in \
|
||||||
libc/ctype/objectlist.awk.in \
|
libc/ctype/objectlist.awk.in \
|
||||||
|
libc/search/objectlist.awk.in \
|
||||||
libc/string/objectlist.awk.in \
|
libc/string/objectlist.awk.in \
|
||||||
libc/locale/objectlist.awk.in \
|
libc/locale/objectlist.awk.in \
|
||||||
libc/misc/objectlist.awk.in \
|
libc/misc/objectlist.awk.in \
|
||||||
|
@ -20,7 +20,7 @@ endif
|
|||||||
|
|
||||||
# The order of SUBDIRS is important for the integrated documentation.
|
# The order of SUBDIRS is important for the integrated documentation.
|
||||||
# Do not change the order without considering the doc impact.
|
# Do not change the order without considering the doc impact.
|
||||||
SUBDIRS = argz stdlib ctype stdio string $(SIGNAL_SUBDIR) time locale sys reent \
|
SUBDIRS = argz stdlib ctype search stdio string $(SIGNAL_SUBDIR) time locale sys reent \
|
||||||
$(extra_dir) errno misc machine $(UNIX_SUBDIR) $(POSIX_SUBDIR) $(SYSCALLS_SUBDIR) .
|
$(extra_dir) errno misc machine $(UNIX_SUBDIR) $(POSIX_SUBDIR) $(SYSCALLS_SUBDIR) .
|
||||||
|
|
||||||
noinst_DATA = $(CRT0)
|
noinst_DATA = $(CRT0)
|
||||||
@ -31,6 +31,7 @@ SUBLIBS = \
|
|||||||
argz/libargz.$(aext) \
|
argz/libargz.$(aext) \
|
||||||
stdlib/libstdlib.$(aext) \
|
stdlib/libstdlib.$(aext) \
|
||||||
ctype/libctype.$(aext) \
|
ctype/libctype.$(aext) \
|
||||||
|
search/libsearch.$(aext) \
|
||||||
stdio/libstdio.$(aext) \
|
stdio/libstdio.$(aext) \
|
||||||
string/libstring.$(aext) \
|
string/libstring.$(aext) \
|
||||||
$(LIBC_SIGNAL_LIB) \
|
$(LIBC_SIGNAL_LIB) \
|
||||||
@ -51,6 +52,7 @@ SUBLIBS = \
|
|||||||
argz/lib.$(aext) \
|
argz/lib.$(aext) \
|
||||||
stdlib/lib.$(aext) \
|
stdlib/lib.$(aext) \
|
||||||
ctype/lib.$(aext) \
|
ctype/lib.$(aext) \
|
||||||
|
search/lib.$(aext) \
|
||||||
stdio/lib.$(aext) \
|
stdio/lib.$(aext) \
|
||||||
string/lib.$(aext) \
|
string/lib.$(aext) \
|
||||||
$(LIBC_SIGNAL_LIB) \
|
$(LIBC_SIGNAL_LIB) \
|
||||||
|
@ -115,7 +115,7 @@ AUTOMAKE_OPTIONS = cygnus
|
|||||||
|
|
||||||
# The order of SUBDIRS is important for the integrated documentation.
|
# The order of SUBDIRS is important for the integrated documentation.
|
||||||
# Do not change the order without considering the doc impact.
|
# Do not change the order without considering the doc impact.
|
||||||
SUBDIRS = argz stdlib ctype stdio string $(SIGNAL_SUBDIR) time locale sys reent \
|
SUBDIRS = argz stdlib ctype search stdio string $(SIGNAL_SUBDIR) time locale sys reent \
|
||||||
$(extra_dir) errno misc machine $(UNIX_SUBDIR) $(POSIX_SUBDIR) $(SYSCALLS_SUBDIR) .
|
$(extra_dir) errno misc machine $(UNIX_SUBDIR) $(POSIX_SUBDIR) $(SYSCALLS_SUBDIR) .
|
||||||
|
|
||||||
|
|
||||||
@ -126,6 +126,7 @@ noinst_DATA = $(CRT0)
|
|||||||
@USE_LIBTOOL_TRUE@ argz/libargz.$(aext) \
|
@USE_LIBTOOL_TRUE@ argz/libargz.$(aext) \
|
||||||
@USE_LIBTOOL_TRUE@ stdlib/libstdlib.$(aext) \
|
@USE_LIBTOOL_TRUE@ stdlib/libstdlib.$(aext) \
|
||||||
@USE_LIBTOOL_TRUE@ ctype/libctype.$(aext) \
|
@USE_LIBTOOL_TRUE@ ctype/libctype.$(aext) \
|
||||||
|
@USE_LIBTOOL_TRUE@ search/libsearch.$(aext) \
|
||||||
@USE_LIBTOOL_TRUE@ stdio/libstdio.$(aext) \
|
@USE_LIBTOOL_TRUE@ stdio/libstdio.$(aext) \
|
||||||
@USE_LIBTOOL_TRUE@ string/libstring.$(aext) \
|
@USE_LIBTOOL_TRUE@ string/libstring.$(aext) \
|
||||||
@USE_LIBTOOL_TRUE@ $(LIBC_SIGNAL_LIB) \
|
@USE_LIBTOOL_TRUE@ $(LIBC_SIGNAL_LIB) \
|
||||||
@ -144,6 +145,7 @@ noinst_DATA = $(CRT0)
|
|||||||
@USE_LIBTOOL_FALSE@ argz/lib.$(aext) \
|
@USE_LIBTOOL_FALSE@ argz/lib.$(aext) \
|
||||||
@USE_LIBTOOL_FALSE@ stdlib/lib.$(aext) \
|
@USE_LIBTOOL_FALSE@ stdlib/lib.$(aext) \
|
||||||
@USE_LIBTOOL_FALSE@ ctype/lib.$(aext) \
|
@USE_LIBTOOL_FALSE@ ctype/lib.$(aext) \
|
||||||
|
@USE_LIBTOOL_FALSE@ search/lib.$(aext) \
|
||||||
@USE_LIBTOOL_FALSE@ stdio/lib.$(aext) \
|
@USE_LIBTOOL_FALSE@ stdio/lib.$(aext) \
|
||||||
@USE_LIBTOOL_FALSE@ string/lib.$(aext) \
|
@USE_LIBTOOL_FALSE@ string/lib.$(aext) \
|
||||||
@USE_LIBTOOL_FALSE@ $(LIBC_SIGNAL_LIB) \
|
@USE_LIBTOOL_FALSE@ $(LIBC_SIGNAL_LIB) \
|
||||||
@ -206,10 +208,10 @@ LTLIBRARIES = $(noinst_LTLIBRARIES)
|
|||||||
|
|
||||||
@USE_LIBTOOL_TRUE@libc_la_DEPENDENCIES = argz/libargz.$(aext) \
|
@USE_LIBTOOL_TRUE@libc_la_DEPENDENCIES = argz/libargz.$(aext) \
|
||||||
@USE_LIBTOOL_TRUE@stdlib/libstdlib.$(aext) ctype/libctype.$(aext) \
|
@USE_LIBTOOL_TRUE@stdlib/libstdlib.$(aext) ctype/libctype.$(aext) \
|
||||||
@USE_LIBTOOL_TRUE@stdio/libstdio.$(aext) string/libstring.$(aext) \
|
@USE_LIBTOOL_TRUE@search/libsearch.$(aext) stdio/libstdio.$(aext) \
|
||||||
@USE_LIBTOOL_TRUE@time/libtime.$(aext) locale/liblocale.$(aext) \
|
@USE_LIBTOOL_TRUE@string/libstring.$(aext) time/libtime.$(aext) \
|
||||||
@USE_LIBTOOL_TRUE@reent/libreent.$(aext) errno/liberrno.$(aext) \
|
@USE_LIBTOOL_TRUE@locale/liblocale.$(aext) reent/libreent.$(aext) \
|
||||||
@USE_LIBTOOL_TRUE@misc/libmisc.$(aext)
|
@USE_LIBTOOL_TRUE@errno/liberrno.$(aext) misc/libmisc.$(aext)
|
||||||
@USE_LIBTOOL_TRUE@libc_la_OBJECTS =
|
@USE_LIBTOOL_TRUE@libc_la_OBJECTS =
|
||||||
CFLAGS = @CFLAGS@
|
CFLAGS = @CFLAGS@
|
||||||
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||||
@ -230,8 +232,8 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
|||||||
|
|
||||||
TAR = gtar
|
TAR = gtar
|
||||||
GZIP_ENV = --best
|
GZIP_ENV = --best
|
||||||
DIST_SUBDIRS = argz stdlib ctype stdio string signal time locale sys \
|
DIST_SUBDIRS = argz stdlib ctype search stdio string signal time locale \
|
||||||
reent @extra_dir@ errno misc machine unix posix syscalls .
|
sys reent @extra_dir@ errno misc machine unix posix syscalls .
|
||||||
SOURCES = libc.a.c $(libc_la_SOURCES)
|
SOURCES = libc.a.c $(libc_la_SOURCES)
|
||||||
OBJECTS = libc.a.$(OBJEXT) $(libc_la_OBJECTS)
|
OBJECTS = libc.a.$(OBJEXT) $(libc_la_OBJECTS)
|
||||||
|
|
||||||
|
4
newlib/libc/configure
vendored
4
newlib/libc/configure
vendored
@ -3143,7 +3143,7 @@ done
|
|||||||
ac_given_srcdir=$srcdir
|
ac_given_srcdir=$srcdir
|
||||||
ac_given_INSTALL="$INSTALL"
|
ac_given_INSTALL="$INSTALL"
|
||||||
|
|
||||||
trap 'rm -fr `echo "Makefile argz/Makefile ctype/Makefile errno/Makefile locale/Makefile misc/Makefile reent/Makefile stdio/Makefile stdlib/Makefile string/Makefile time/Makefile posix/Makefile signal/Makefile syscalls/Makefile unix/Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
|
trap 'rm -fr `echo "Makefile argz/Makefile ctype/Makefile errno/Makefile locale/Makefile misc/Makefile reent/Makefile search/Makefile stdio/Makefile stdlib/Makefile string/Makefile time/Makefile posix/Makefile signal/Makefile syscalls/Makefile unix/Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
|
||||||
EOF
|
EOF
|
||||||
cat >> $CONFIG_STATUS <<EOF
|
cat >> $CONFIG_STATUS <<EOF
|
||||||
|
|
||||||
@ -3285,7 +3285,7 @@ EOF
|
|||||||
|
|
||||||
cat >> $CONFIG_STATUS <<EOF
|
cat >> $CONFIG_STATUS <<EOF
|
||||||
|
|
||||||
CONFIG_FILES=\${CONFIG_FILES-"Makefile argz/Makefile ctype/Makefile errno/Makefile locale/Makefile misc/Makefile reent/Makefile stdio/Makefile stdlib/Makefile string/Makefile time/Makefile posix/Makefile signal/Makefile syscalls/Makefile unix/Makefile"}
|
CONFIG_FILES=\${CONFIG_FILES-"Makefile argz/Makefile ctype/Makefile errno/Makefile locale/Makefile misc/Makefile reent/Makefile search/Makefile stdio/Makefile stdlib/Makefile string/Makefile time/Makefile posix/Makefile signal/Makefile syscalls/Makefile unix/Makefile"}
|
||||||
EOF
|
EOF
|
||||||
cat >> $CONFIG_STATUS <<\EOF
|
cat >> $CONFIG_STATUS <<\EOF
|
||||||
for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
|
for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
|
||||||
|
@ -110,4 +110,4 @@ fi
|
|||||||
AC_SUBST(LIBC_MACHINE_LIB)
|
AC_SUBST(LIBC_MACHINE_LIB)
|
||||||
AC_SUBST(machine_dir)
|
AC_SUBST(machine_dir)
|
||||||
|
|
||||||
AC_OUTPUT(Makefile argz/Makefile ctype/Makefile errno/Makefile locale/Makefile misc/Makefile reent/Makefile stdio/Makefile stdlib/Makefile string/Makefile time/Makefile posix/Makefile signal/Makefile syscalls/Makefile unix/Makefile)
|
AC_OUTPUT(Makefile argz/Makefile ctype/Makefile errno/Makefile locale/Makefile misc/Makefile reent/Makefile search/Makefile stdio/Makefile stdlib/Makefile string/Makefile time/Makefile posix/Makefile signal/Makefile syscalls/Makefile unix/Makefile)
|
||||||
|
218
newlib/libc/include/db.h
Normal file
218
newlib/libc/include/db.h
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1990, 1993, 1994
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the University of
|
||||||
|
* California, Berkeley and its contributors.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)db.h 8.7 (Berkeley) 6/16/94
|
||||||
|
* $FreeBSD: src/include/db.h,v 1.5 2002/03/26 01:35:05 bde Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _DB_H_
|
||||||
|
#define _DB_H_
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#include <sys/config.h>
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#define RET_ERROR -1 /* Return values. */
|
||||||
|
#define RET_SUCCESS 0
|
||||||
|
#define RET_SPECIAL 1
|
||||||
|
|
||||||
|
#define MAX_PAGE_NUMBER 0xffffffff /* >= # of pages in a file */
|
||||||
|
typedef __uint32_t pgno_t;
|
||||||
|
#define MAX_PAGE_OFFSET 65535 /* >= # of bytes in a page */
|
||||||
|
typedef __uint16_t indx_t;
|
||||||
|
#define MAX_REC_NUMBER 0xffffffff /* >= # of records in a tree */
|
||||||
|
typedef __uint32_t recno_t;
|
||||||
|
|
||||||
|
/* Key/data structure -- a Data-Base Thang. */
|
||||||
|
typedef struct {
|
||||||
|
void *data; /* data */
|
||||||
|
size_t size; /* data length */
|
||||||
|
} DBT;
|
||||||
|
|
||||||
|
/* Routine flags. */
|
||||||
|
#define R_CURSOR 1 /* del, put, seq */
|
||||||
|
#define __R_UNUSED 2 /* UNUSED */
|
||||||
|
#define R_FIRST 3 /* seq */
|
||||||
|
#define R_IAFTER 4 /* put (RECNO) */
|
||||||
|
#define R_IBEFORE 5 /* put (RECNO) */
|
||||||
|
#define R_LAST 6 /* seq (BTREE, RECNO) */
|
||||||
|
#define R_NEXT 7 /* seq */
|
||||||
|
#define R_NOOVERWRITE 8 /* put */
|
||||||
|
#define R_PREV 9 /* seq (BTREE, RECNO) */
|
||||||
|
#define R_SETCURSOR 10 /* put (RECNO) */
|
||||||
|
#define R_RECNOSYNC 11 /* sync (RECNO) */
|
||||||
|
|
||||||
|
typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* !!!
|
||||||
|
* The following flags are included in the dbopen(3) call as part of the
|
||||||
|
* open(2) flags. In order to avoid conflicts with the open flags, start
|
||||||
|
* at the top of the 16 or 32-bit number space and work our way down. If
|
||||||
|
* the open flags were significantly expanded in the future, it could be
|
||||||
|
* a problem. Wish I'd left another flags word in the dbopen call.
|
||||||
|
*
|
||||||
|
* !!!
|
||||||
|
* None of this stuff is implemented yet. The only reason that it's here
|
||||||
|
* is so that the access methods can skip copying the key/data pair when
|
||||||
|
* the DB_LOCK flag isn't set.
|
||||||
|
*/
|
||||||
|
#if UINT_MAX > 65535
|
||||||
|
#define DB_LOCK 0x20000000 /* Do locking. */
|
||||||
|
#define DB_SHMEM 0x40000000 /* Use shared memory. */
|
||||||
|
#define DB_TXN 0x80000000 /* Do transactions. */
|
||||||
|
#else
|
||||||
|
#define DB_LOCK 0x2000 /* Do locking. */
|
||||||
|
#define DB_SHMEM 0x4000 /* Use shared memory. */
|
||||||
|
#define DB_TXN 0x8000 /* Do transactions. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Access method description structure. */
|
||||||
|
typedef struct __db {
|
||||||
|
DBTYPE type; /* Underlying db type. */
|
||||||
|
int (*close)(struct __db *);
|
||||||
|
int (*del)(const struct __db *, const DBT *, u_int);
|
||||||
|
int (*get)(const struct __db *, const DBT *, DBT *, u_int);
|
||||||
|
int (*put)(const struct __db *, DBT *, const DBT *, u_int);
|
||||||
|
int (*seq)(const struct __db *, DBT *, DBT *, u_int);
|
||||||
|
int (*sync)(const struct __db *, u_int);
|
||||||
|
void *internal; /* Access method private. */
|
||||||
|
int (*fd)(const struct __db *);
|
||||||
|
} DB;
|
||||||
|
|
||||||
|
#define BTREEMAGIC 0x053162
|
||||||
|
#define BTREEVERSION 3
|
||||||
|
|
||||||
|
/* Structure used to pass parameters to the btree routines. */
|
||||||
|
typedef struct {
|
||||||
|
#define R_DUP 0x01 /* duplicate keys */
|
||||||
|
u_long flags;
|
||||||
|
u_int cachesize; /* bytes to cache */
|
||||||
|
int maxkeypage; /* maximum keys per page */
|
||||||
|
int minkeypage; /* minimum keys per page */
|
||||||
|
u_int psize; /* page size */
|
||||||
|
int (*compare) /* comparison function */
|
||||||
|
(const DBT *, const DBT *);
|
||||||
|
size_t (*prefix) /* prefix function */
|
||||||
|
(const DBT *, const DBT *);
|
||||||
|
int lorder; /* byte order */
|
||||||
|
} BTREEINFO;
|
||||||
|
|
||||||
|
#define HASHMAGIC 0x061561
|
||||||
|
#define HASHVERSION 2
|
||||||
|
|
||||||
|
/* Structure used to pass parameters to the hashing routines. */
|
||||||
|
typedef struct {
|
||||||
|
u_int bsize; /* bucket size */
|
||||||
|
u_int ffactor; /* fill factor */
|
||||||
|
u_int nelem; /* number of elements */
|
||||||
|
u_int cachesize; /* bytes to cache */
|
||||||
|
__uint32_t /* hash function */
|
||||||
|
(*hash)(const void *, size_t);
|
||||||
|
int lorder; /* byte order */
|
||||||
|
} HASHINFO;
|
||||||
|
|
||||||
|
/* Structure used to pass parameters to the record routines. */
|
||||||
|
typedef struct {
|
||||||
|
#define R_FIXEDLEN 0x01 /* fixed-length records */
|
||||||
|
#define R_NOKEY 0x02 /* key not required */
|
||||||
|
#define R_SNAPSHOT 0x04 /* snapshot the input */
|
||||||
|
u_long flags;
|
||||||
|
u_int cachesize; /* bytes to cache */
|
||||||
|
u_int psize; /* page size */
|
||||||
|
int lorder; /* byte order */
|
||||||
|
size_t reclen; /* record length (fixed-length records) */
|
||||||
|
u_char bval; /* delimiting byte (variable-length records */
|
||||||
|
char *bfname; /* btree file name */
|
||||||
|
} RECNOINFO;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Little endian <==> big endian 32-bit swap macros.
|
||||||
|
* M_32_SWAP swap a memory location
|
||||||
|
* P_32_SWAP swap a referenced memory location
|
||||||
|
* P_32_COPY swap from one location to another
|
||||||
|
*/
|
||||||
|
#define M_32_SWAP(a) { \
|
||||||
|
__uint32_t _tmp = a; \
|
||||||
|
((char *)&a)[0] = ((char *)&_tmp)[3]; \
|
||||||
|
((char *)&a)[1] = ((char *)&_tmp)[2]; \
|
||||||
|
((char *)&a)[2] = ((char *)&_tmp)[1]; \
|
||||||
|
((char *)&a)[3] = ((char *)&_tmp)[0]; \
|
||||||
|
}
|
||||||
|
#define P_32_SWAP(a) { \
|
||||||
|
__uint32_t _tmp = *(__uint32_t *)a; \
|
||||||
|
((char *)a)[0] = ((char *)&_tmp)[3]; \
|
||||||
|
((char *)a)[1] = ((char *)&_tmp)[2]; \
|
||||||
|
((char *)a)[2] = ((char *)&_tmp)[1]; \
|
||||||
|
((char *)a)[3] = ((char *)&_tmp)[0]; \
|
||||||
|
}
|
||||||
|
#define P_32_COPY(a, b) { \
|
||||||
|
((char *)&(b))[0] = ((char *)&(a))[3]; \
|
||||||
|
((char *)&(b))[1] = ((char *)&(a))[2]; \
|
||||||
|
((char *)&(b))[2] = ((char *)&(a))[1]; \
|
||||||
|
((char *)&(b))[3] = ((char *)&(a))[0]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Little endian <==> big endian 16-bit swap macros.
|
||||||
|
* M_16_SWAP swap a memory location
|
||||||
|
* P_16_SWAP swap a referenced memory location
|
||||||
|
* P_16_COPY swap from one location to another
|
||||||
|
*/
|
||||||
|
#define M_16_SWAP(a) { \
|
||||||
|
__uint16_t _tmp = a; \
|
||||||
|
((char *)&a)[0] = ((char *)&_tmp)[1]; \
|
||||||
|
((char *)&a)[1] = ((char *)&_tmp)[0]; \
|
||||||
|
}
|
||||||
|
#define P_16_SWAP(a) { \
|
||||||
|
__uint16_t _tmp = *(__uint16_t *)a; \
|
||||||
|
((char *)a)[0] = ((char *)&_tmp)[1]; \
|
||||||
|
((char *)a)[1] = ((char *)&_tmp)[0]; \
|
||||||
|
}
|
||||||
|
#define P_16_COPY(a, b) { \
|
||||||
|
((char *)&(b))[0] = ((char *)&(a))[1]; \
|
||||||
|
((char *)&(b))[1] = ((char *)&(a))[0]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
DB *dbopen(const char *, int, int, DBTYPE, const void *);
|
||||||
|
|
||||||
|
#ifdef __DBINTERFACE_PRIVATE
|
||||||
|
DB *__bt_open(const char *, int, int, const BTREEINFO *, int);
|
||||||
|
DB *__hash_open(const char *, int, int, const HASHINFO *, int);
|
||||||
|
DB *__rec_open(const char *, int, int, const RECNOINFO *, int);
|
||||||
|
void __dbpanic(DB *dbp);
|
||||||
|
#endif
|
||||||
|
__END_DECLS
|
||||||
|
#endif /* !_DB_H_ */
|
80
newlib/libc/include/ndbm.h
Normal file
80
newlib/libc/include/ndbm.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1990, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Margo Seltzer.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the University of
|
||||||
|
* California, Berkeley and its contributors.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)ndbm.h 8.1 (Berkeley) 6/2/93
|
||||||
|
* $FreeBSD: src/include/ndbm.h,v 1.4 2002/03/23 17:24:53 imp Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _NDBM_H_
|
||||||
|
#define _NDBM_H_
|
||||||
|
|
||||||
|
#include <db.h>
|
||||||
|
|
||||||
|
/* Map dbm interface onto db(3). */
|
||||||
|
#define DBM_RDONLY O_RDONLY
|
||||||
|
|
||||||
|
/* Flags to dbm_store(). */
|
||||||
|
#define DBM_INSERT 0
|
||||||
|
#define DBM_REPLACE 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The db(3) support for ndbm always appends this suffix to the
|
||||||
|
* file name to avoid overwriting the user's original database.
|
||||||
|
*/
|
||||||
|
#define DBM_SUFFIX ".db"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *dptr;
|
||||||
|
int dsize;
|
||||||
|
} datum;
|
||||||
|
|
||||||
|
typedef DB DBM;
|
||||||
|
#define dbm_pagfno(a) DBM_PAGFNO_NOT_AVAILABLE
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
int dbm_clearerr(DBM *);
|
||||||
|
void dbm_close(DBM *);
|
||||||
|
int dbm_delete(DBM *, datum);
|
||||||
|
int dbm_error(DBM *);
|
||||||
|
datum dbm_fetch(DBM *, datum);
|
||||||
|
datum dbm_firstkey(DBM *);
|
||||||
|
long dbm_forder(DBM *, datum);
|
||||||
|
datum dbm_nextkey(DBM *);
|
||||||
|
DBM *dbm_open(const char *, int, int);
|
||||||
|
int dbm_store(DBM *, datum, datum, int);
|
||||||
|
int dbm_dirfno(DBM *);
|
||||||
|
__END_DECLS
|
||||||
|
|
||||||
|
#endif /* !_NDBM_H_ */
|
59
newlib/libc/include/search.h
Normal file
59
newlib/libc/include/search.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/* $NetBSD: search.h,v 1.12 1999/02/22 10:34:28 christos Exp $ */
|
||||||
|
/* $FreeBSD: src/include/search.h,v 1.4 2002/03/23 17:24:53 imp Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Written by J.T. Conklin <jtc@netbsd.org>
|
||||||
|
* Public domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SEARCH_H_
|
||||||
|
#define _SEARCH_H_
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#include <machine/ansi.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
typedef struct entry {
|
||||||
|
char *key;
|
||||||
|
void *data;
|
||||||
|
} ENTRY;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
FIND, ENTER
|
||||||
|
} ACTION;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
preorder,
|
||||||
|
postorder,
|
||||||
|
endorder,
|
||||||
|
leaf
|
||||||
|
} VISIT;
|
||||||
|
|
||||||
|
#ifdef _SEARCH_PRIVATE
|
||||||
|
typedef struct node {
|
||||||
|
char *key;
|
||||||
|
struct node *llink, *rlink;
|
||||||
|
} node_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct hsearch_data
|
||||||
|
{
|
||||||
|
struct internal_head *htable;
|
||||||
|
size_t htablesize;
|
||||||
|
};
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
int hcreate(size_t);
|
||||||
|
void hdestroy(void);
|
||||||
|
ENTRY *hsearch(ENTRY, ACTION);
|
||||||
|
int hcreate_r(size_t, struct hsearch_data *);
|
||||||
|
void hdestroy_r(struct hsearch_data *);
|
||||||
|
int hsearch_r(ENTRY, ACTION, ENTRY **, struct hsearch_data *);
|
||||||
|
void *tdelete(const void *, void **, int (*)(const void *, const void *));
|
||||||
|
void tdestroy (void *, void (*)(void *));
|
||||||
|
void *tfind(const void *, void **, int (*)(const void *, const void *));
|
||||||
|
void *tsearch(const void *, void **, int (*)(const void *, const void *));
|
||||||
|
void twalk(const void *, void (*)(const void *, VISIT, int));
|
||||||
|
__END_DECLS
|
||||||
|
|
||||||
|
#endif /* !_SEARCH_H_ */
|
123
newlib/libc/include/sys/cdefs.h
Normal file
123
newlib/libc/include/sys/cdefs.h
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
/* libc/sys/linux/sys/cdefs.h - Helper macros for K&R vs. ANSI C compat. */
|
||||||
|
|
||||||
|
/* Written 2000 by Werner Almesberger */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1991, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Berkeley Software Design, Inc.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the University of
|
||||||
|
* California, Berkeley and its contributors.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)cdefs.h 8.8 (Berkeley) 1/9/95
|
||||||
|
* $FreeBSD: src/sys/sys/cdefs.h,v 1.54 2002/05/11 03:58:24 alfred Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SYS_CDEFS_H
|
||||||
|
#define _SYS_CDEFS_H
|
||||||
|
|
||||||
|
#define __FBSDID(x) /* nothing */
|
||||||
|
/*
|
||||||
|
* Note: the goal here is not compatibility to K&R C. Since we know that we
|
||||||
|
* have GCC which understands ANSI C perfectly well, we make use of this.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define __P(args) args
|
||||||
|
#define __PMT(args) args
|
||||||
|
#define __const const
|
||||||
|
#define __signed signed
|
||||||
|
#define __volatile volatile
|
||||||
|
#define __DOTS , ...
|
||||||
|
#define __THROW
|
||||||
|
|
||||||
|
#define __ptr_t void *
|
||||||
|
#define __long_double_t long double
|
||||||
|
|
||||||
|
#define __attribute_malloc__
|
||||||
|
#define __attribute_pure__
|
||||||
|
#define __attribute_format_strfmon__(a,b)
|
||||||
|
#define __flexarr [0]
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
# define __BEGIN_DECLS extern "C" {
|
||||||
|
# define __END_DECLS }
|
||||||
|
#else
|
||||||
|
# define __BEGIN_DECLS
|
||||||
|
# define __END_DECLS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __BOUNDED_POINTERS__
|
||||||
|
# define __bounded /* nothing */
|
||||||
|
# define __unbounded /* nothing */
|
||||||
|
# define __ptrvalue /* nothing */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define __strong_reference(sym,aliassym) \
|
||||||
|
extern __typeof (sym) aliassym __attribute__ ((__alias__ (#sym)));
|
||||||
|
#ifdef __ELF__
|
||||||
|
#ifdef __STDC__
|
||||||
|
#define __weak_reference(sym,alias) \
|
||||||
|
__asm__(".weak " #alias); \
|
||||||
|
__asm__(".equ " #alias ", " #sym)
|
||||||
|
#define __warn_references(sym,msg) \
|
||||||
|
__asm__(".section .gnu.warning." #sym); \
|
||||||
|
__asm__(".asciz \"" msg "\""); \
|
||||||
|
__asm__(".previous")
|
||||||
|
#else
|
||||||
|
#define __weak_reference(sym,alias) \
|
||||||
|
__asm__(".weak alias"); \
|
||||||
|
__asm__(".equ alias, sym")
|
||||||
|
#define __warn_references(sym,msg) \
|
||||||
|
__asm__(".section .gnu.warning.sym"); \
|
||||||
|
__asm__(".asciz \"msg\""); \
|
||||||
|
__asm__(".previous")
|
||||||
|
#endif /* __STDC__ */
|
||||||
|
#else /* !__ELF__ */
|
||||||
|
#ifdef __STDC__
|
||||||
|
#define __weak_reference(sym,alias) \
|
||||||
|
__asm__(".stabs \"_" #alias "\",11,0,0,0"); \
|
||||||
|
__asm__(".stabs \"_" #sym "\",1,0,0,0")
|
||||||
|
#define __warn_references(sym,msg) \
|
||||||
|
__asm__(".stabs \"" msg "\",30,0,0,0"); \
|
||||||
|
__asm__(".stabs \"_" #sym "\",1,0,0,0")
|
||||||
|
#else
|
||||||
|
#define __weak_reference(sym,alias) \
|
||||||
|
__asm__(".stabs \"_/**/alias\",11,0,0,0"); \
|
||||||
|
__asm__(".stabs \"_/**/sym\",1,0,0,0")
|
||||||
|
#define __warn_references(sym,msg) \
|
||||||
|
__asm__(".stabs msg,30,0,0,0"); \
|
||||||
|
__asm__(".stabs \"_/**/sym\",1,0,0,0")
|
||||||
|
#endif /* __STDC__ */
|
||||||
|
#endif /* __ELF__ */
|
||||||
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
|
#endif /* _SYS_CDEFS_H */
|
@ -96,6 +96,7 @@ extern __IMPORT int sys_nerr;
|
|||||||
#define ELBIN 75 /* Inode is remote (not really error) */
|
#define ELBIN 75 /* Inode is remote (not really error) */
|
||||||
#define EDOTDOT 76 /* Cross mount point (not really error) */
|
#define EDOTDOT 76 /* Cross mount point (not really error) */
|
||||||
#define EBADMSG 77 /* Trying to read unreadable message */
|
#define EBADMSG 77 /* Trying to read unreadable message */
|
||||||
|
#define EFTYPE 79 /* Inappropriate file type or format */
|
||||||
#define ENOTUNIQ 80 /* Given log. name not unique */
|
#define ENOTUNIQ 80 /* Given log. name not unique */
|
||||||
#define EBADFD 81 /* f.d. invalid for this operation */
|
#define EBADFD 81 /* f.d. invalid for this operation */
|
||||||
#define EREMCHG 82 /* Remote address changed */
|
#define EREMCHG 82 /* Remote address changed */
|
||||||
|
@ -5,14 +5,27 @@
|
|||||||
#ifndef _SYS_PARAM_H
|
#ifndef _SYS_PARAM_H
|
||||||
# define _SYS_PARAM_H
|
# define _SYS_PARAM_H
|
||||||
|
|
||||||
|
#include <sys/config.h>
|
||||||
|
|
||||||
# define HZ (60)
|
# define HZ (60)
|
||||||
# define NOFILE (60)
|
# define NOFILE (60)
|
||||||
# define PATHSIZE (1024)
|
# define PATHSIZE (1024)
|
||||||
|
|
||||||
#ifdef __i386__
|
|
||||||
#define BIG_ENDIAN 4321
|
#define BIG_ENDIAN 4321
|
||||||
#define LITTLE_ENDIAN 1234
|
#define LITTLE_ENDIAN 1234
|
||||||
|
|
||||||
|
#ifdef __IEEE_LITTLE_ENDIAN
|
||||||
#define BYTE_ORDER LITTLE_ENDIAN
|
#define BYTE_ORDER LITTLE_ENDIAN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __IEEE_BIG_ENDIAN
|
||||||
|
#define BYTE_ORDER BIG_ENDIAN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __i386__
|
||||||
|
#ifndef BYTE_ORDER
|
||||||
|
#define BYTE_ORDER LITTLE_ENDIAN
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
471
newlib/libc/include/sys/queue.h
Normal file
471
newlib/libc/include/sys/queue.h
Normal file
@ -0,0 +1,471 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1991, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the University of
|
||||||
|
* California, Berkeley and its contributors.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)queue.h 8.5 (Berkeley) 8/20/94
|
||||||
|
* $FreeBSD: src/sys/sys/queue.h,v 1.48 2002/04/17 14:00:37 tmm Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SYS_QUEUE_H_
|
||||||
|
#define _SYS_QUEUE_H_
|
||||||
|
|
||||||
|
#include <machine/ansi.h> /* for __offsetof */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file defines four types of data structures: singly-linked lists,
|
||||||
|
* singly-linked tail queues, lists and tail queues.
|
||||||
|
*
|
||||||
|
* A singly-linked list is headed by a single forward pointer. The elements
|
||||||
|
* are singly linked for minimum space and pointer manipulation overhead at
|
||||||
|
* the expense of O(n) removal for arbitrary elements. New elements can be
|
||||||
|
* added to the list after an existing element or at the head of the list.
|
||||||
|
* Elements being removed from the head of the list should use the explicit
|
||||||
|
* macro for this purpose for optimum efficiency. A singly-linked list may
|
||||||
|
* only be traversed in the forward direction. Singly-linked lists are ideal
|
||||||
|
* for applications with large datasets and few or no removals or for
|
||||||
|
* implementing a LIFO queue.
|
||||||
|
*
|
||||||
|
* A singly-linked tail queue is headed by a pair of pointers, one to the
|
||||||
|
* head of the list and the other to the tail of the list. The elements are
|
||||||
|
* singly linked for minimum space and pointer manipulation overhead at the
|
||||||
|
* expense of O(n) removal for arbitrary elements. New elements can be added
|
||||||
|
* to the list after an existing element, at the head of the list, or at the
|
||||||
|
* end of the list. Elements being removed from the head of the tail queue
|
||||||
|
* should use the explicit macro for this purpose for optimum efficiency.
|
||||||
|
* A singly-linked tail queue may only be traversed in the forward direction.
|
||||||
|
* Singly-linked tail queues are ideal for applications with large datasets
|
||||||
|
* and few or no removals or for implementing a FIFO queue.
|
||||||
|
*
|
||||||
|
* A list is headed by a single forward pointer (or an array of forward
|
||||||
|
* pointers for a hash table header). The elements are doubly linked
|
||||||
|
* so that an arbitrary element can be removed without a need to
|
||||||
|
* traverse the list. New elements can be added to the list before
|
||||||
|
* or after an existing element or at the head of the list. A list
|
||||||
|
* may only be traversed in the forward direction.
|
||||||
|
*
|
||||||
|
* A tail queue is headed by a pair of pointers, one to the head of the
|
||||||
|
* list and the other to the tail of the list. The elements are doubly
|
||||||
|
* linked so that an arbitrary element can be removed without a need to
|
||||||
|
* traverse the list. New elements can be added to the list before or
|
||||||
|
* after an existing element, at the head of the list, or at the end of
|
||||||
|
* the list. A tail queue may be traversed in either direction.
|
||||||
|
*
|
||||||
|
* For details on the use of these macros, see the queue(3) manual page.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* SLIST LIST STAILQ TAILQ
|
||||||
|
* _HEAD + + + +
|
||||||
|
* _HEAD_INITIALIZER + + + +
|
||||||
|
* _ENTRY + + + +
|
||||||
|
* _INIT + + + +
|
||||||
|
* _EMPTY + + + +
|
||||||
|
* _FIRST + + + +
|
||||||
|
* _NEXT + + + +
|
||||||
|
* _PREV - - - +
|
||||||
|
* _LAST - - + +
|
||||||
|
* _FOREACH + + + +
|
||||||
|
* _FOREACH_REVERSE - - - +
|
||||||
|
* _INSERT_HEAD + + + +
|
||||||
|
* _INSERT_BEFORE - + - +
|
||||||
|
* _INSERT_AFTER + + + +
|
||||||
|
* _INSERT_TAIL - - + +
|
||||||
|
* _CONCAT - - + +
|
||||||
|
* _REMOVE_HEAD + - + -
|
||||||
|
* _REMOVE + + + +
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Singly-linked List declarations.
|
||||||
|
*/
|
||||||
|
#define SLIST_HEAD(name, type) \
|
||||||
|
struct name { \
|
||||||
|
struct type *slh_first; /* first element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SLIST_HEAD_INITIALIZER(head) \
|
||||||
|
{ NULL }
|
||||||
|
|
||||||
|
#define SLIST_ENTRY(type) \
|
||||||
|
struct { \
|
||||||
|
struct type *sle_next; /* next element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Singly-linked List functions.
|
||||||
|
*/
|
||||||
|
#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
|
||||||
|
|
||||||
|
#define SLIST_FIRST(head) ((head)->slh_first)
|
||||||
|
|
||||||
|
#define SLIST_FOREACH(var, head, field) \
|
||||||
|
for ((var) = SLIST_FIRST((head)); \
|
||||||
|
(var); \
|
||||||
|
(var) = SLIST_NEXT((var), field))
|
||||||
|
|
||||||
|
#define SLIST_INIT(head) do { \
|
||||||
|
SLIST_FIRST((head)) = NULL; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
|
||||||
|
SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
|
||||||
|
SLIST_NEXT((slistelm), field) = (elm); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define SLIST_INSERT_HEAD(head, elm, field) do { \
|
||||||
|
SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
|
||||||
|
SLIST_FIRST((head)) = (elm); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
|
||||||
|
|
||||||
|
#define SLIST_REMOVE(head, elm, type, field) do { \
|
||||||
|
if (SLIST_FIRST((head)) == (elm)) { \
|
||||||
|
SLIST_REMOVE_HEAD((head), field); \
|
||||||
|
} \
|
||||||
|
else { \
|
||||||
|
struct type *curelm = SLIST_FIRST((head)); \
|
||||||
|
while (SLIST_NEXT(curelm, field) != (elm)) \
|
||||||
|
curelm = SLIST_NEXT(curelm, field); \
|
||||||
|
SLIST_NEXT(curelm, field) = \
|
||||||
|
SLIST_NEXT(SLIST_NEXT(curelm, field), field); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define SLIST_REMOVE_HEAD(head, field) do { \
|
||||||
|
SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Singly-linked Tail queue declarations.
|
||||||
|
*/
|
||||||
|
#define STAILQ_HEAD(name, type) \
|
||||||
|
struct name { \
|
||||||
|
struct type *stqh_first;/* first element */ \
|
||||||
|
struct type **stqh_last;/* addr of last next element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define STAILQ_HEAD_INITIALIZER(head) \
|
||||||
|
{ NULL, &(head).stqh_first }
|
||||||
|
|
||||||
|
#define STAILQ_ENTRY(type) \
|
||||||
|
struct { \
|
||||||
|
struct type *stqe_next; /* next element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Singly-linked Tail queue functions.
|
||||||
|
*/
|
||||||
|
#define STAILQ_CONCAT(head1, head2) do { \
|
||||||
|
if (!STAILQ_EMPTY((head2))) { \
|
||||||
|
*(head1)->stqh_last = (head2)->stqh_first; \
|
||||||
|
(head1)->stqh_last = (head2)->stqh_last; \
|
||||||
|
STAILQ_INIT((head2)); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
|
||||||
|
|
||||||
|
#define STAILQ_FIRST(head) ((head)->stqh_first)
|
||||||
|
|
||||||
|
#define STAILQ_FOREACH(var, head, field) \
|
||||||
|
for((var) = STAILQ_FIRST((head)); \
|
||||||
|
(var); \
|
||||||
|
(var) = STAILQ_NEXT((var), field))
|
||||||
|
|
||||||
|
#define STAILQ_INIT(head) do { \
|
||||||
|
STAILQ_FIRST((head)) = NULL; \
|
||||||
|
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
|
||||||
|
if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
|
||||||
|
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||||
|
STAILQ_NEXT((tqelm), field) = (elm); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define STAILQ_INSERT_HEAD(head, elm, field) do { \
|
||||||
|
if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
|
||||||
|
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||||
|
STAILQ_FIRST((head)) = (elm); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define STAILQ_INSERT_TAIL(head, elm, field) do { \
|
||||||
|
STAILQ_NEXT((elm), field) = NULL; \
|
||||||
|
*(head)->stqh_last = (elm); \
|
||||||
|
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define STAILQ_LAST(head, type, field) \
|
||||||
|
(STAILQ_EMPTY((head)) ? \
|
||||||
|
NULL : \
|
||||||
|
((struct type *) \
|
||||||
|
((char *)((head)->stqh_last) - __offsetof(struct type, field))))
|
||||||
|
|
||||||
|
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
|
||||||
|
|
||||||
|
#define STAILQ_REMOVE(head, elm, type, field) do { \
|
||||||
|
if (STAILQ_FIRST((head)) == (elm)) { \
|
||||||
|
STAILQ_REMOVE_HEAD((head), field); \
|
||||||
|
} \
|
||||||
|
else { \
|
||||||
|
struct type *curelm = STAILQ_FIRST((head)); \
|
||||||
|
while (STAILQ_NEXT(curelm, field) != (elm)) \
|
||||||
|
curelm = STAILQ_NEXT(curelm, field); \
|
||||||
|
if ((STAILQ_NEXT(curelm, field) = \
|
||||||
|
STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\
|
||||||
|
(head)->stqh_last = &STAILQ_NEXT((curelm), field);\
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define STAILQ_REMOVE_HEAD(head, field) do { \
|
||||||
|
if ((STAILQ_FIRST((head)) = \
|
||||||
|
STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
|
||||||
|
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \
|
||||||
|
if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \
|
||||||
|
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List declarations.
|
||||||
|
*/
|
||||||
|
#define LIST_HEAD(name, type) \
|
||||||
|
struct name { \
|
||||||
|
struct type *lh_first; /* first element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LIST_HEAD_INITIALIZER(head) \
|
||||||
|
{ NULL }
|
||||||
|
|
||||||
|
#define LIST_ENTRY(type) \
|
||||||
|
struct { \
|
||||||
|
struct type *le_next; /* next element */ \
|
||||||
|
struct type **le_prev; /* address of previous next element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
|
||||||
|
|
||||||
|
#define LIST_FIRST(head) ((head)->lh_first)
|
||||||
|
|
||||||
|
#define LIST_FOREACH(var, head, field) \
|
||||||
|
for ((var) = LIST_FIRST((head)); \
|
||||||
|
(var); \
|
||||||
|
(var) = LIST_NEXT((var), field))
|
||||||
|
|
||||||
|
#define LIST_INIT(head) do { \
|
||||||
|
LIST_FIRST((head)) = NULL; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
|
||||||
|
if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
|
||||||
|
LIST_NEXT((listelm), field)->field.le_prev = \
|
||||||
|
&LIST_NEXT((elm), field); \
|
||||||
|
LIST_NEXT((listelm), field) = (elm); \
|
||||||
|
(elm)->field.le_prev = &LIST_NEXT((listelm), field); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
|
||||||
|
(elm)->field.le_prev = (listelm)->field.le_prev; \
|
||||||
|
LIST_NEXT((elm), field) = (listelm); \
|
||||||
|
*(listelm)->field.le_prev = (elm); \
|
||||||
|
(listelm)->field.le_prev = &LIST_NEXT((elm), field); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LIST_INSERT_HEAD(head, elm, field) do { \
|
||||||
|
if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
|
||||||
|
LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
|
||||||
|
LIST_FIRST((head)) = (elm); \
|
||||||
|
(elm)->field.le_prev = &LIST_FIRST((head)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
|
||||||
|
|
||||||
|
#define LIST_REMOVE(elm, field) do { \
|
||||||
|
if (LIST_NEXT((elm), field) != NULL) \
|
||||||
|
LIST_NEXT((elm), field)->field.le_prev = \
|
||||||
|
(elm)->field.le_prev; \
|
||||||
|
*(elm)->field.le_prev = LIST_NEXT((elm), field); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tail queue declarations.
|
||||||
|
*/
|
||||||
|
#define TAILQ_HEAD(name, type) \
|
||||||
|
struct name { \
|
||||||
|
struct type *tqh_first; /* first element */ \
|
||||||
|
struct type **tqh_last; /* addr of last next element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TAILQ_HEAD_INITIALIZER(head) \
|
||||||
|
{ NULL, &(head).tqh_first }
|
||||||
|
|
||||||
|
#define TAILQ_ENTRY(type) \
|
||||||
|
struct { \
|
||||||
|
struct type *tqe_next; /* next element */ \
|
||||||
|
struct type **tqe_prev; /* address of previous next element */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tail queue functions.
|
||||||
|
*/
|
||||||
|
#define TAILQ_CONCAT(head1, head2, field) do { \
|
||||||
|
if (!TAILQ_EMPTY(head2)) { \
|
||||||
|
*(head1)->tqh_last = (head2)->tqh_first; \
|
||||||
|
(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
|
||||||
|
(head1)->tqh_last = (head2)->tqh_last; \
|
||||||
|
TAILQ_INIT((head2)); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
|
||||||
|
|
||||||
|
#define TAILQ_FIRST(head) ((head)->tqh_first)
|
||||||
|
|
||||||
|
#define TAILQ_FOREACH(var, head, field) \
|
||||||
|
for ((var) = TAILQ_FIRST((head)); \
|
||||||
|
(var); \
|
||||||
|
(var) = TAILQ_NEXT((var), field))
|
||||||
|
|
||||||
|
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
|
||||||
|
for ((var) = TAILQ_LAST((head), headname); \
|
||||||
|
(var); \
|
||||||
|
(var) = TAILQ_PREV((var), headname, field))
|
||||||
|
|
||||||
|
#define TAILQ_INIT(head) do { \
|
||||||
|
TAILQ_FIRST((head)) = NULL; \
|
||||||
|
(head)->tqh_last = &TAILQ_FIRST((head)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||||
|
if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
|
||||||
|
TAILQ_NEXT((elm), field)->field.tqe_prev = \
|
||||||
|
&TAILQ_NEXT((elm), field); \
|
||||||
|
else \
|
||||||
|
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||||
|
TAILQ_NEXT((listelm), field) = (elm); \
|
||||||
|
(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
|
||||||
|
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
|
||||||
|
TAILQ_NEXT((elm), field) = (listelm); \
|
||||||
|
*(listelm)->field.tqe_prev = (elm); \
|
||||||
|
(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
|
||||||
|
if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
|
||||||
|
TAILQ_FIRST((head))->field.tqe_prev = \
|
||||||
|
&TAILQ_NEXT((elm), field); \
|
||||||
|
else \
|
||||||
|
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||||
|
TAILQ_FIRST((head)) = (elm); \
|
||||||
|
(elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
|
||||||
|
TAILQ_NEXT((elm), field) = NULL; \
|
||||||
|
(elm)->field.tqe_prev = (head)->tqh_last; \
|
||||||
|
*(head)->tqh_last = (elm); \
|
||||||
|
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define TAILQ_LAST(head, headname) \
|
||||||
|
(*(((struct headname *)((head)->tqh_last))->tqh_last))
|
||||||
|
|
||||||
|
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
|
||||||
|
|
||||||
|
#define TAILQ_PREV(elm, headname, field) \
|
||||||
|
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
|
||||||
|
|
||||||
|
#define TAILQ_REMOVE(head, elm, field) do { \
|
||||||
|
if ((TAILQ_NEXT((elm), field)) != NULL) \
|
||||||
|
TAILQ_NEXT((elm), field)->field.tqe_prev = \
|
||||||
|
(elm)->field.tqe_prev; \
|
||||||
|
else \
|
||||||
|
(head)->tqh_last = (elm)->field.tqe_prev; \
|
||||||
|
*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _KERNEL
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX insque() and remque() are an old way of handling certain queues.
|
||||||
|
* They bogusly assumes that all queue heads look alike.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct quehead {
|
||||||
|
struct quehead *qh_link;
|
||||||
|
struct quehead *qh_rlink;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
|
||||||
|
static __inline void
|
||||||
|
insque(void *a, void *b)
|
||||||
|
{
|
||||||
|
struct quehead *element = (struct quehead *)a,
|
||||||
|
*head = (struct quehead *)b;
|
||||||
|
|
||||||
|
element->qh_link = head->qh_link;
|
||||||
|
element->qh_rlink = head;
|
||||||
|
head->qh_link = element;
|
||||||
|
element->qh_link->qh_rlink = element;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void
|
||||||
|
remque(void *a)
|
||||||
|
{
|
||||||
|
struct quehead *element = (struct quehead *)a;
|
||||||
|
|
||||||
|
element->qh_link->qh_rlink = element->qh_rlink;
|
||||||
|
element->qh_rlink->qh_link = element->qh_link;
|
||||||
|
element->qh_rlink = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* !__GNUC__ */
|
||||||
|
|
||||||
|
void insque(void *a, void *b);
|
||||||
|
void remque(void *a);
|
||||||
|
|
||||||
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
|
#endif /* _KERNEL */
|
||||||
|
|
||||||
|
#endif /* !_SYS_QUEUE_H_ */
|
40
newlib/libc/search/Makefile.am
Normal file
40
newlib/libc/search/Makefile.am
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
## Process this file with automake to generate Makefile.in
|
||||||
|
|
||||||
|
AUTOMAKE_OPTIONS = cygnus
|
||||||
|
|
||||||
|
INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
|
||||||
|
|
||||||
|
LIB_SOURCES = \
|
||||||
|
bsearch.c \
|
||||||
|
extern.h \
|
||||||
|
hash.c \
|
||||||
|
hash.h \
|
||||||
|
hash_bigkey.c \
|
||||||
|
hash_buf.c \
|
||||||
|
hash_func.c \
|
||||||
|
hash_log2.c \
|
||||||
|
hash_page.c \
|
||||||
|
hcreate.c \
|
||||||
|
hcreate_r.c \
|
||||||
|
ndbm.c \
|
||||||
|
page.h \
|
||||||
|
qsort.c \
|
||||||
|
tdelete.c \
|
||||||
|
tdestroy.c \
|
||||||
|
tfind.c \
|
||||||
|
tsearch.c \
|
||||||
|
twalk.c
|
||||||
|
|
||||||
|
libsearch_la_LDFLAGS = -Xcompiler -nostdlib
|
||||||
|
|
||||||
|
if USE_LIBTOOL
|
||||||
|
noinst_LTLIBRARIES = libsearch.la
|
||||||
|
libsearch_la_SOURCES = $(LIB_SOURCES)
|
||||||
|
noinst_DATA = objectlist.awk.in
|
||||||
|
else
|
||||||
|
noinst_LIBRARIES = lib.a
|
||||||
|
lib_a_SOURCES = $(LIB_SOURCES)
|
||||||
|
noinst_DATA =
|
||||||
|
endif # USE_LIBTOOL
|
||||||
|
|
||||||
|
include $(srcdir)/../../Makefile.shared
|
396
newlib/libc/search/Makefile.in
Normal file
396
newlib/libc/search/Makefile.in
Normal file
@ -0,0 +1,396 @@
|
|||||||
|
# Makefile.in generated automatically by automake 1.4 from Makefile.am
|
||||||
|
|
||||||
|
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
|
||||||
|
# This Makefile.in is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||||
|
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
# PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SHELL = @SHELL@
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
prefix = @prefix@
|
||||||
|
exec_prefix = @exec_prefix@
|
||||||
|
|
||||||
|
bindir = @bindir@
|
||||||
|
sbindir = @sbindir@
|
||||||
|
libexecdir = @libexecdir@
|
||||||
|
datadir = @datadir@
|
||||||
|
sysconfdir = @sysconfdir@
|
||||||
|
sharedstatedir = @sharedstatedir@
|
||||||
|
localstatedir = @localstatedir@
|
||||||
|
libdir = @libdir@
|
||||||
|
infodir = @infodir@
|
||||||
|
mandir = @mandir@
|
||||||
|
includedir = @includedir@
|
||||||
|
oldincludedir = /usr/include
|
||||||
|
|
||||||
|
DESTDIR =
|
||||||
|
|
||||||
|
pkgdatadir = $(datadir)/@PACKAGE@
|
||||||
|
pkglibdir = $(libdir)/@PACKAGE@
|
||||||
|
pkgincludedir = $(includedir)/@PACKAGE@
|
||||||
|
|
||||||
|
top_builddir = ..
|
||||||
|
|
||||||
|
ACLOCAL = @ACLOCAL@
|
||||||
|
AUTOCONF = @AUTOCONF@
|
||||||
|
AUTOMAKE = @AUTOMAKE@
|
||||||
|
AUTOHEADER = @AUTOHEADER@
|
||||||
|
|
||||||
|
INSTALL = @INSTALL@
|
||||||
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
|
||||||
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
|
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||||
|
transform = @program_transform_name@
|
||||||
|
|
||||||
|
NORMAL_INSTALL = :
|
||||||
|
PRE_INSTALL = :
|
||||||
|
POST_INSTALL = :
|
||||||
|
NORMAL_UNINSTALL = :
|
||||||
|
PRE_UNINSTALL = :
|
||||||
|
POST_UNINSTALL = :
|
||||||
|
build_alias = @build_alias@
|
||||||
|
build_triplet = @build@
|
||||||
|
host_alias = @host_alias@
|
||||||
|
host_triplet = @host@
|
||||||
|
target_alias = @target_alias@
|
||||||
|
target_triplet = @target@
|
||||||
|
AR = @AR@
|
||||||
|
AS = @AS@
|
||||||
|
CC = @CC@
|
||||||
|
CPP = @CPP@
|
||||||
|
CRT0 = @CRT0@
|
||||||
|
CXX = @CXX@
|
||||||
|
CXXCPP = @CXXCPP@
|
||||||
|
DLLTOOL = @DLLTOOL@
|
||||||
|
EXEEXT = @EXEEXT@
|
||||||
|
GCJ = @GCJ@
|
||||||
|
GCJFLAGS = @GCJFLAGS@
|
||||||
|
LDFLAGS = @LDFLAGS@
|
||||||
|
LIBC_EXTRA_DEF = @LIBC_EXTRA_DEF@
|
||||||
|
LIBC_EXTRA_LIB = @LIBC_EXTRA_LIB@
|
||||||
|
LIBC_MACHINE_LIB = @LIBC_MACHINE_LIB@
|
||||||
|
LIBC_POSIX_LIB = @LIBC_POSIX_LIB@
|
||||||
|
LIBC_SIGNAL_DEF = @LIBC_SIGNAL_DEF@
|
||||||
|
LIBC_SIGNAL_LIB = @LIBC_SIGNAL_LIB@
|
||||||
|
LIBC_SYSCALL_LIB = @LIBC_SYSCALL_LIB@
|
||||||
|
LIBC_SYS_LIB = @LIBC_SYS_LIB@
|
||||||
|
LIBC_UNIX_LIB = @LIBC_UNIX_LIB@
|
||||||
|
LIBTOOL = @LIBTOOL@
|
||||||
|
LN_S = @LN_S@
|
||||||
|
MAINT = @MAINT@
|
||||||
|
MAKEINFO = @MAKEINFO@
|
||||||
|
NEWLIB_CFLAGS = @NEWLIB_CFLAGS@
|
||||||
|
OBJDUMP = @OBJDUMP@
|
||||||
|
OBJEXT = @OBJEXT@
|
||||||
|
PACKAGE = @PACKAGE@
|
||||||
|
RANLIB = @RANLIB@
|
||||||
|
STRIP = @STRIP@
|
||||||
|
VERSION = @VERSION@
|
||||||
|
aext = @aext@
|
||||||
|
extra_dir = @extra_dir@
|
||||||
|
libm_machine_dir = @libm_machine_dir@
|
||||||
|
machine_dir = @machine_dir@
|
||||||
|
newlib_basedir = @newlib_basedir@
|
||||||
|
oext = @oext@
|
||||||
|
sys_dir = @sys_dir@
|
||||||
|
|
||||||
|
AUTOMAKE_OPTIONS = cygnus
|
||||||
|
|
||||||
|
INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
|
||||||
|
|
||||||
|
LIB_SOURCES = \
|
||||||
|
bsearch.c \
|
||||||
|
extern.h \
|
||||||
|
hash.c \
|
||||||
|
hash.h \
|
||||||
|
hash_bigkey.c \
|
||||||
|
hash_buf.c \
|
||||||
|
hash_func.c \
|
||||||
|
hash_log2.c \
|
||||||
|
hash_page.c \
|
||||||
|
hcreate.c \
|
||||||
|
hcreate_r.c \
|
||||||
|
ndbm.c \
|
||||||
|
page.h \
|
||||||
|
qsort.c \
|
||||||
|
tdelete.c \
|
||||||
|
tdestroy.c \
|
||||||
|
tfind.c \
|
||||||
|
tsearch.c \
|
||||||
|
twalk.c
|
||||||
|
|
||||||
|
|
||||||
|
libsearch_la_LDFLAGS = -Xcompiler -nostdlib
|
||||||
|
|
||||||
|
@USE_LIBTOOL_TRUE@noinst_LTLIBRARIES = @USE_LIBTOOL_TRUE@libsearch.la
|
||||||
|
@USE_LIBTOOL_TRUE@libsearch_la_SOURCES = @USE_LIBTOOL_TRUE@$(LIB_SOURCES)
|
||||||
|
@USE_LIBTOOL_TRUE@noinst_DATA = @USE_LIBTOOL_TRUE@objectlist.awk.in
|
||||||
|
@USE_LIBTOOL_FALSE@noinst_DATA =
|
||||||
|
@USE_LIBTOOL_FALSE@noinst_LIBRARIES = @USE_LIBTOOL_FALSE@lib.a
|
||||||
|
@USE_LIBTOOL_FALSE@lib_a_SOURCES = @USE_LIBTOOL_FALSE@$(LIB_SOURCES)
|
||||||
|
mkinstalldirs = $(SHELL) $(top_srcdir)/../../mkinstalldirs
|
||||||
|
CONFIG_CLEAN_FILES =
|
||||||
|
LIBRARIES = $(noinst_LIBRARIES)
|
||||||
|
|
||||||
|
|
||||||
|
DEFS = @DEFS@ -I. -I$(srcdir)
|
||||||
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
LIBS = @LIBS@
|
||||||
|
lib_a_LIBADD =
|
||||||
|
@USE_LIBTOOL_FALSE@lib_a_OBJECTS = bsearch.$(OBJEXT) hash.$(OBJEXT) \
|
||||||
|
@USE_LIBTOOL_FALSE@hash_bigkey.$(OBJEXT) hash_buf.$(OBJEXT) \
|
||||||
|
@USE_LIBTOOL_FALSE@hash_func.$(OBJEXT) hash_log2.$(OBJEXT) \
|
||||||
|
@USE_LIBTOOL_FALSE@hash_page.$(OBJEXT) hcreate.$(OBJEXT) \
|
||||||
|
@USE_LIBTOOL_FALSE@hcreate_r.$(OBJEXT) ndbm.$(OBJEXT) qsort.$(OBJEXT) \
|
||||||
|
@USE_LIBTOOL_FALSE@tdelete.$(OBJEXT) tdestroy.$(OBJEXT) tfind.$(OBJEXT) \
|
||||||
|
@USE_LIBTOOL_FALSE@tsearch.$(OBJEXT) twalk.$(OBJEXT)
|
||||||
|
LTLIBRARIES = $(noinst_LTLIBRARIES)
|
||||||
|
|
||||||
|
libsearch_la_LIBADD =
|
||||||
|
@USE_LIBTOOL_TRUE@libsearch_la_OBJECTS = bsearch.lo hash.lo \
|
||||||
|
@USE_LIBTOOL_TRUE@hash_bigkey.lo hash_buf.lo hash_func.lo hash_log2.lo \
|
||||||
|
@USE_LIBTOOL_TRUE@hash_page.lo hcreate.lo hcreate_r.lo ndbm.lo qsort.lo \
|
||||||
|
@USE_LIBTOOL_TRUE@tdelete.lo tdestroy.lo tfind.lo tsearch.lo twalk.lo
|
||||||
|
CFLAGS = @CFLAGS@
|
||||||
|
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||||
|
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||||
|
CCLD = $(CC)
|
||||||
|
LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
|
||||||
|
DATA = $(noinst_DATA)
|
||||||
|
|
||||||
|
DIST_COMMON = Makefile.am Makefile.in
|
||||||
|
|
||||||
|
|
||||||
|
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
|
|
||||||
|
TAR = gtar
|
||||||
|
GZIP_ENV = --best
|
||||||
|
SOURCES = $(lib_a_SOURCES) $(libsearch_la_SOURCES)
|
||||||
|
OBJECTS = $(lib_a_OBJECTS) $(libsearch_la_OBJECTS)
|
||||||
|
|
||||||
|
all: all-redirect
|
||||||
|
.SUFFIXES:
|
||||||
|
.SUFFIXES: .S .c .lo .o .obj .s
|
||||||
|
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../Makefile.shared
|
||||||
|
cd $(top_srcdir) && $(AUTOMAKE) --cygnus search/Makefile
|
||||||
|
|
||||||
|
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||||
|
cd $(top_builddir) \
|
||||||
|
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||||
|
|
||||||
|
|
||||||
|
mostlyclean-noinstLIBRARIES:
|
||||||
|
|
||||||
|
clean-noinstLIBRARIES:
|
||||||
|
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
|
||||||
|
|
||||||
|
distclean-noinstLIBRARIES:
|
||||||
|
|
||||||
|
maintainer-clean-noinstLIBRARIES:
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(COMPILE) -c $<
|
||||||
|
|
||||||
|
# FIXME: We should only use cygpath when building on Windows,
|
||||||
|
# and only if it is available.
|
||||||
|
.c.obj:
|
||||||
|
$(COMPILE) -c `cygpath -w $<`
|
||||||
|
|
||||||
|
.s.o:
|
||||||
|
$(COMPILE) -c $<
|
||||||
|
|
||||||
|
.S.o:
|
||||||
|
$(COMPILE) -c $<
|
||||||
|
|
||||||
|
mostlyclean-compile:
|
||||||
|
-rm -f *.o core *.core
|
||||||
|
-rm -f *.$(OBJEXT)
|
||||||
|
|
||||||
|
clean-compile:
|
||||||
|
|
||||||
|
distclean-compile:
|
||||||
|
-rm -f *.tab.c
|
||||||
|
|
||||||
|
maintainer-clean-compile:
|
||||||
|
|
||||||
|
.c.lo:
|
||||||
|
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
|
||||||
|
|
||||||
|
.s.lo:
|
||||||
|
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
|
||||||
|
|
||||||
|
.S.lo:
|
||||||
|
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
|
||||||
|
|
||||||
|
mostlyclean-libtool:
|
||||||
|
-rm -f *.lo
|
||||||
|
|
||||||
|
clean-libtool:
|
||||||
|
-rm -rf .libs _libs
|
||||||
|
|
||||||
|
distclean-libtool:
|
||||||
|
|
||||||
|
maintainer-clean-libtool:
|
||||||
|
|
||||||
|
lib.a: $(lib_a_OBJECTS) $(lib_a_DEPENDENCIES)
|
||||||
|
-rm -f lib.a
|
||||||
|
$(AR) cru lib.a $(lib_a_OBJECTS) $(lib_a_LIBADD)
|
||||||
|
$(RANLIB) lib.a
|
||||||
|
|
||||||
|
mostlyclean-noinstLTLIBRARIES:
|
||||||
|
|
||||||
|
clean-noinstLTLIBRARIES:
|
||||||
|
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
|
||||||
|
|
||||||
|
distclean-noinstLTLIBRARIES:
|
||||||
|
|
||||||
|
maintainer-clean-noinstLTLIBRARIES:
|
||||||
|
|
||||||
|
libsearch.la: $(libsearch_la_OBJECTS) $(libsearch_la_DEPENDENCIES)
|
||||||
|
$(LINK) $(libsearch_la_LDFLAGS) $(libsearch_la_OBJECTS) $(libsearch_la_LIBADD) $(LIBS)
|
||||||
|
|
||||||
|
tags: TAGS
|
||||||
|
|
||||||
|
ID: $(HEADERS) $(SOURCES) $(LISP)
|
||||||
|
list='$(SOURCES) $(HEADERS)'; \
|
||||||
|
unique=`for i in $$list; do echo $$i; done | \
|
||||||
|
awk ' { files[$$0] = 1; } \
|
||||||
|
END { for (i in files) print i; }'`; \
|
||||||
|
here=`pwd` && cd $(srcdir) \
|
||||||
|
&& mkid -f$$here/ID $$unique $(LISP)
|
||||||
|
|
||||||
|
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
|
||||||
|
tags=; \
|
||||||
|
here=`pwd`; \
|
||||||
|
list='$(SOURCES) $(HEADERS)'; \
|
||||||
|
unique=`for i in $$list; do echo $$i; done | \
|
||||||
|
awk ' { files[$$0] = 1; } \
|
||||||
|
END { for (i in files) print i; }'`; \
|
||||||
|
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|
||||||
|
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
|
||||||
|
|
||||||
|
mostlyclean-tags:
|
||||||
|
|
||||||
|
clean-tags:
|
||||||
|
|
||||||
|
distclean-tags:
|
||||||
|
-rm -f TAGS ID
|
||||||
|
|
||||||
|
maintainer-clean-tags:
|
||||||
|
|
||||||
|
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
|
||||||
|
|
||||||
|
subdir = search
|
||||||
|
|
||||||
|
distdir: $(DISTFILES)
|
||||||
|
@for file in $(DISTFILES); do \
|
||||||
|
if test -f $$file; then d=.; else d=$(srcdir); fi; \
|
||||||
|
if test -d $$d/$$file; then \
|
||||||
|
cp -pr $$d/$$file $(distdir)/$$file; \
|
||||||
|
else \
|
||||||
|
test -f $(distdir)/$$file \
|
||||||
|
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|
||||||
|
|| cp -p $$d/$$file $(distdir)/$$file || :; \
|
||||||
|
fi; \
|
||||||
|
done
|
||||||
|
info-am:
|
||||||
|
info: info-am
|
||||||
|
dvi-am:
|
||||||
|
dvi: dvi-am
|
||||||
|
check-am:
|
||||||
|
check: check-am
|
||||||
|
installcheck-am:
|
||||||
|
installcheck: installcheck-am
|
||||||
|
install-info-am:
|
||||||
|
install-info: install-info-am
|
||||||
|
install-exec-am:
|
||||||
|
install-exec: install-exec-am
|
||||||
|
|
||||||
|
install-data-am:
|
||||||
|
install-data: install-data-am
|
||||||
|
|
||||||
|
install-am: all-am
|
||||||
|
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||||
|
install: install-am
|
||||||
|
uninstall-am:
|
||||||
|
uninstall: uninstall-am
|
||||||
|
all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(DATA)
|
||||||
|
all-redirect: all-am
|
||||||
|
install-strip:
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
|
||||||
|
installdirs:
|
||||||
|
|
||||||
|
|
||||||
|
mostlyclean-generic:
|
||||||
|
|
||||||
|
clean-generic:
|
||||||
|
|
||||||
|
distclean-generic:
|
||||||
|
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||||
|
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
|
||||||
|
|
||||||
|
maintainer-clean-generic:
|
||||||
|
mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \
|
||||||
|
mostlyclean-libtool mostlyclean-noinstLTLIBRARIES \
|
||||||
|
mostlyclean-tags mostlyclean-generic
|
||||||
|
|
||||||
|
mostlyclean: mostlyclean-am
|
||||||
|
|
||||||
|
clean-am: clean-noinstLIBRARIES clean-compile clean-libtool \
|
||||||
|
clean-noinstLTLIBRARIES clean-tags clean-generic \
|
||||||
|
mostlyclean-am
|
||||||
|
|
||||||
|
clean: clean-am
|
||||||
|
|
||||||
|
distclean-am: distclean-noinstLIBRARIES distclean-compile \
|
||||||
|
distclean-libtool distclean-noinstLTLIBRARIES \
|
||||||
|
distclean-tags distclean-generic clean-am
|
||||||
|
-rm -f libtool
|
||||||
|
|
||||||
|
distclean: distclean-am
|
||||||
|
|
||||||
|
maintainer-clean-am: maintainer-clean-noinstLIBRARIES \
|
||||||
|
maintainer-clean-compile maintainer-clean-libtool \
|
||||||
|
maintainer-clean-noinstLTLIBRARIES \
|
||||||
|
maintainer-clean-tags maintainer-clean-generic \
|
||||||
|
distclean-am
|
||||||
|
@echo "This command is intended for maintainers to use;"
|
||||||
|
@echo "it deletes files that may require special tools to rebuild."
|
||||||
|
|
||||||
|
maintainer-clean: maintainer-clean-am
|
||||||
|
|
||||||
|
.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
|
||||||
|
clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
|
||||||
|
mostlyclean-compile distclean-compile clean-compile \
|
||||||
|
maintainer-clean-compile mostlyclean-libtool distclean-libtool \
|
||||||
|
clean-libtool maintainer-clean-libtool mostlyclean-noinstLTLIBRARIES \
|
||||||
|
distclean-noinstLTLIBRARIES clean-noinstLTLIBRARIES \
|
||||||
|
maintainer-clean-noinstLTLIBRARIES tags mostlyclean-tags distclean-tags \
|
||||||
|
clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \
|
||||||
|
check-am installcheck-am installcheck install-info-am install-info \
|
||||||
|
install-exec-am install-exec install-data-am install-data install-am \
|
||||||
|
install uninstall-am uninstall all-redirect all-am all installdirs \
|
||||||
|
mostlyclean-generic distclean-generic clean-generic \
|
||||||
|
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
|
||||||
|
|
||||||
|
|
||||||
|
objectlist.awk.in: $(noinst_LTLIBRARIES)
|
||||||
|
-rm -f objectlist.awk.in
|
||||||
|
for i in `ls *.lo` ; \
|
||||||
|
do \
|
||||||
|
echo $$i `pwd`/$$i >> objectlist.awk.in ; \
|
||||||
|
done
|
||||||
|
|
||||||
|
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||||
|
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||||
|
.NOEXPORT:
|
100
newlib/libc/search/bsearch.c
Normal file
100
newlib/libc/search/bsearch.c
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* bsearch.c
|
||||||
|
* Original Author: G. Haley
|
||||||
|
* Rewritten by: G. Noer
|
||||||
|
*
|
||||||
|
* Searches an array of nmemb members, the initial member of which is pointed
|
||||||
|
* to by base, for a member that matches the object pointed to by key. The
|
||||||
|
* contents of the array shall be in ascending order according to a comparison
|
||||||
|
* function pointed to by compar. The function shall return an integer less
|
||||||
|
* than, equal to or greater than zero if the first argument is considered to be
|
||||||
|
* respectively less than, equal to or greater than the second. Returns a
|
||||||
|
* pointer to the matching member of the array, or a null pointer if no match
|
||||||
|
* is found.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
FUNCTION
|
||||||
|
<<bsearch>>---binary search
|
||||||
|
|
||||||
|
INDEX
|
||||||
|
bsearch
|
||||||
|
|
||||||
|
ANSI_SYNOPSIS
|
||||||
|
#include <stdlib.h>
|
||||||
|
void *bsearch(const void *<[key]>, const void *<[base]>,
|
||||||
|
size_t <[nmemb]>, size_t <[size]>,
|
||||||
|
int (*<[compar]>)(const void *, const void *));
|
||||||
|
|
||||||
|
TRAD_SYNOPSIS
|
||||||
|
#include <stdlib.h>
|
||||||
|
char *bsearch(<[key]>, <[base]>, <[nmemb]>, <[size]>, <[compar]>)
|
||||||
|
char *<[key]>;
|
||||||
|
char *<[base]>;
|
||||||
|
size_t <[nmemb]>, <[size]>;
|
||||||
|
int (*<[compar]>)();
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
<<bsearch>> searches an array beginning at <[base]> for any element
|
||||||
|
that matches <[key]>, using binary search. <[nmemb]> is the element
|
||||||
|
count of the array; <[size]> is the size of each element.
|
||||||
|
|
||||||
|
The array must be sorted in ascending order with respect to the
|
||||||
|
comparison function <[compar]> (which you supply as the last argument of
|
||||||
|
<<bsearch>>).
|
||||||
|
|
||||||
|
You must define the comparison function <<(*<[compar]>)>> to have two
|
||||||
|
arguments; its result must be negative if the first argument is
|
||||||
|
less than the second, zero if the two arguments match, and
|
||||||
|
positive if the first argument is greater than the second (where
|
||||||
|
``less than'' and ``greater than'' refer to whatever arbitrary
|
||||||
|
ordering is appropriate).
|
||||||
|
|
||||||
|
RETURNS
|
||||||
|
Returns a pointer to an element of <[array]> that matches <[key]>. If
|
||||||
|
more than one matching element is available, the result may point to
|
||||||
|
any of them.
|
||||||
|
|
||||||
|
PORTABILITY
|
||||||
|
<<bsearch>> is ANSI.
|
||||||
|
|
||||||
|
No supporting OS subroutines are required.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
_PTR
|
||||||
|
_DEFUN (bsearch, (key, base, nmemb, size, compar),
|
||||||
|
_CONST _PTR key _AND
|
||||||
|
_CONST _PTR base _AND
|
||||||
|
size_t nmemb _AND
|
||||||
|
size_t size _AND
|
||||||
|
int _EXFUN ((*compar), (const _PTR, const _PTR)))
|
||||||
|
{
|
||||||
|
_PTR current;
|
||||||
|
size_t lower = 0;
|
||||||
|
size_t upper = nmemb;
|
||||||
|
size_t index;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if (nmemb == 0 || size == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while (lower < upper)
|
||||||
|
{
|
||||||
|
index = (lower + upper) / 2;
|
||||||
|
current = (_PTR) (((char *) base) + (index * size));
|
||||||
|
|
||||||
|
result = compar (key, current);
|
||||||
|
|
||||||
|
if (result < 0)
|
||||||
|
upper = index;
|
||||||
|
else if (result > 0)
|
||||||
|
lower = index + 1;
|
||||||
|
else
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
66
newlib/libc/search/extern.h
Normal file
66
newlib/libc/search/extern.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1991, 1993, 1994
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the University of
|
||||||
|
* California, Berkeley and its contributors.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)extern.h 8.4 (Berkeley) 6/16/94
|
||||||
|
* $FreeBSD: src/lib/libc/db/hash/extern.h,v 1.3 2002/03/22 09:18:22 obrien Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
BUFHEAD *__add_ovflpage(HTAB *, BUFHEAD *);
|
||||||
|
int __addel(HTAB *, BUFHEAD *, const DBT *, const DBT *);
|
||||||
|
int __big_delete(HTAB *, BUFHEAD *);
|
||||||
|
int __big_insert(HTAB *, BUFHEAD *, const DBT *, const DBT *);
|
||||||
|
int __big_keydata(HTAB *, BUFHEAD *, DBT *, DBT *, int);
|
||||||
|
int __big_return(HTAB *, BUFHEAD *, int, DBT *, int);
|
||||||
|
int __big_split(HTAB *, BUFHEAD *, BUFHEAD *, BUFHEAD *,
|
||||||
|
int, __uint32_t, SPLIT_RETURN *);
|
||||||
|
int __buf_free(HTAB *, int, int);
|
||||||
|
void __buf_init(HTAB *, int);
|
||||||
|
__uint32_t __call_hash(HTAB *, char *, int);
|
||||||
|
int __delpair(HTAB *, BUFHEAD *, int);
|
||||||
|
int __expand_table(HTAB *);
|
||||||
|
int __find_bigpair(HTAB *, BUFHEAD *, int, char *, int);
|
||||||
|
__uint16_t __find_last_page(HTAB *, BUFHEAD **);
|
||||||
|
void __free_ovflpage(HTAB *, BUFHEAD *);
|
||||||
|
BUFHEAD *__get_buf(HTAB *, __uint32_t, BUFHEAD *, int);
|
||||||
|
int __get_page(HTAB *, char *, __uint32_t, int, int, int);
|
||||||
|
int __ibitmap(HTAB *, int, int, int);
|
||||||
|
__uint32_t __log2(__uint32_t);
|
||||||
|
int __put_page(HTAB *, char *, __uint32_t, int, int);
|
||||||
|
void __reclaim_buf(HTAB *, BUFHEAD *);
|
||||||
|
int __split_page(HTAB *, __uint32_t, __uint32_t);
|
||||||
|
|
||||||
|
/* Default hash routine. */
|
||||||
|
extern __uint32_t (*__default_hash)(const void *, size_t);
|
||||||
|
|
||||||
|
#ifdef HASH_STATISTICS
|
||||||
|
extern int hash_accesses, hash_collisions, hash_expansions, hash_overflows;
|
||||||
|
#endif
|
1004
newlib/libc/search/hash.c
Normal file
1004
newlib/libc/search/hash.c
Normal file
File diff suppressed because it is too large
Load Diff
294
newlib/libc/search/hash.h
Normal file
294
newlib/libc/search/hash.h
Normal file
@ -0,0 +1,294 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1990, 1993, 1994
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Margo Seltzer.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the University of
|
||||||
|
* California, Berkeley and its contributors.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)hash.h 8.3 (Berkeley) 5/31/94
|
||||||
|
* $FreeBSD: src/lib/libc/db/hash/hash.h,v 1.6 2002/03/21 22:46:26 obrien Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Operations */
|
||||||
|
typedef enum {
|
||||||
|
HASH_GET, HASH_PUT, HASH_PUTNEW, HASH_DELETE, HASH_FIRST, HASH_NEXT
|
||||||
|
} ACTION;
|
||||||
|
|
||||||
|
/* Buffer Management structures */
|
||||||
|
typedef struct _bufhead BUFHEAD;
|
||||||
|
|
||||||
|
struct _bufhead {
|
||||||
|
BUFHEAD *prev; /* LRU links */
|
||||||
|
BUFHEAD *next; /* LRU links */
|
||||||
|
BUFHEAD *ovfl; /* Overflow page buffer header */
|
||||||
|
__uint32_t addr; /* Address of this page */
|
||||||
|
char *page; /* Actual page data */
|
||||||
|
char flags;
|
||||||
|
#define BUF_MOD 0x0001
|
||||||
|
#define BUF_DISK 0x0002
|
||||||
|
#define BUF_BUCKET 0x0004
|
||||||
|
#define BUF_PIN 0x0008
|
||||||
|
};
|
||||||
|
|
||||||
|
#define IS_BUCKET(X) ((X) & BUF_BUCKET)
|
||||||
|
|
||||||
|
typedef BUFHEAD **SEGMENT;
|
||||||
|
|
||||||
|
/* Hash Table Information */
|
||||||
|
typedef struct hashhdr { /* Disk resident portion */
|
||||||
|
int magic; /* Magic NO for hash tables */
|
||||||
|
int version; /* Version ID */
|
||||||
|
__uint32_t lorder; /* Byte Order */
|
||||||
|
int bsize; /* Bucket/Page Size */
|
||||||
|
int bshift; /* Bucket shift */
|
||||||
|
int dsize; /* Directory Size */
|
||||||
|
int ssize; /* Segment Size */
|
||||||
|
int sshift; /* Segment shift */
|
||||||
|
int ovfl_point; /* Where overflow pages are being
|
||||||
|
* allocated */
|
||||||
|
int last_freed; /* Last overflow page freed */
|
||||||
|
int max_bucket; /* ID of Maximum bucket in use */
|
||||||
|
int high_mask; /* Mask to modulo into entire table */
|
||||||
|
int low_mask; /* Mask to modulo into lower half of
|
||||||
|
* table */
|
||||||
|
int ffactor; /* Fill factor */
|
||||||
|
int nkeys; /* Number of keys in hash table */
|
||||||
|
int hdrpages; /* Size of table header */
|
||||||
|
int h_charkey; /* value of hash(CHARKEY) */
|
||||||
|
#define NCACHED 32 /* number of bit maps and spare
|
||||||
|
* points */
|
||||||
|
int spares[NCACHED];/* spare pages for overflow */
|
||||||
|
__uint16_t bitmaps[NCACHED]; /* address of overflow page
|
||||||
|
* bitmaps */
|
||||||
|
} HASHHDR;
|
||||||
|
|
||||||
|
typedef struct htab { /* Memory resident data structure */
|
||||||
|
HASHHDR hdr; /* Header */
|
||||||
|
int nsegs; /* Number of allocated segments */
|
||||||
|
int exsegs; /* Number of extra allocated
|
||||||
|
* segments */
|
||||||
|
__uint32_t /* Hash function */
|
||||||
|
(*hash)(const void *, size_t);
|
||||||
|
int flags; /* Flag values */
|
||||||
|
int fp; /* File pointer */
|
||||||
|
char *tmp_buf; /* Temporary Buffer for BIG data */
|
||||||
|
char *tmp_key; /* Temporary Buffer for BIG keys */
|
||||||
|
BUFHEAD *cpage; /* Current page */
|
||||||
|
int cbucket; /* Current bucket */
|
||||||
|
int cndx; /* Index of next item on cpage */
|
||||||
|
int error; /* Error Number -- for DBM
|
||||||
|
* compatibility */
|
||||||
|
int new_file; /* Indicates if fd is backing store
|
||||||
|
* or no */
|
||||||
|
int save_file; /* Indicates whether we need to flush
|
||||||
|
* file at
|
||||||
|
* exit */
|
||||||
|
__uint32_t *mapp[NCACHED]; /* Pointers to page maps */
|
||||||
|
int nmaps; /* Initial number of bitmaps */
|
||||||
|
int nbufs; /* Number of buffers left to
|
||||||
|
* allocate */
|
||||||
|
BUFHEAD bufhead; /* Header of buffer lru list */
|
||||||
|
SEGMENT *dir; /* Hash Bucket directory */
|
||||||
|
} HTAB;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constants
|
||||||
|
*/
|
||||||
|
#define MAX_BSIZE 65536 /* 2^16 */
|
||||||
|
#define MIN_BUFFERS 6
|
||||||
|
#define MINHDRSIZE 512
|
||||||
|
#define DEF_BUFSIZE 65536 /* 64 K */
|
||||||
|
#define DEF_BUCKET_SIZE 4096
|
||||||
|
#define DEF_BUCKET_SHIFT 12 /* log2(BUCKET) */
|
||||||
|
#define DEF_SEGSIZE 256
|
||||||
|
#define DEF_SEGSIZE_SHIFT 8 /* log2(SEGSIZE) */
|
||||||
|
#define DEF_DIRSIZE 256
|
||||||
|
#define DEF_FFACTOR 65536
|
||||||
|
#define MIN_FFACTOR 4
|
||||||
|
#define SPLTMAX 8
|
||||||
|
#define CHARKEY "%$sniglet^&"
|
||||||
|
#define NUMKEY 1038583
|
||||||
|
#define BYTE_SHIFT 3
|
||||||
|
#define INT_TO_BYTE 2
|
||||||
|
#define INT_BYTE_SHIFT 5
|
||||||
|
#define ALL_SET ((__uint32_t)0xFFFFFFFF)
|
||||||
|
#define ALL_CLEAR 0
|
||||||
|
|
||||||
|
#define PTROF(X) ((BUFHEAD *)((ptrdiff_t)(X)&~0x3))
|
||||||
|
#define ISMOD(X) ((__uint32_t)(ptrdiff_t)(X)&0x1)
|
||||||
|
#define DOMOD(X) ((X) = (char *)((ptrdiff_t)(X)|0x1))
|
||||||
|
#define ISDISK(X) ((__uint32_t)(ptrdiff_t)(X)&0x2)
|
||||||
|
#define DODISK(X) ((X) = (char *)((ptrdiff_t)(X)|0x2))
|
||||||
|
|
||||||
|
#define BITS_PER_MAP 32
|
||||||
|
|
||||||
|
/* Given the address of the beginning of a big map, clear/set the nth bit */
|
||||||
|
#define CLRBIT(A, N) ((A)[(N)/BITS_PER_MAP] &= ~(1<<((N)%BITS_PER_MAP)))
|
||||||
|
#define SETBIT(A, N) ((A)[(N)/BITS_PER_MAP] |= (1<<((N)%BITS_PER_MAP)))
|
||||||
|
#define ISSET(A, N) ((A)[(N)/BITS_PER_MAP] & (1<<((N)%BITS_PER_MAP)))
|
||||||
|
|
||||||
|
/* Overflow management */
|
||||||
|
/*
|
||||||
|
* Overflow page numbers are allocated per split point. At each doubling of
|
||||||
|
* the table, we can allocate extra pages. So, an overflow page number has
|
||||||
|
* the top 5 bits indicate which split point and the lower 11 bits indicate
|
||||||
|
* which page at that split point is indicated (pages within split points are
|
||||||
|
* numberered starting with 1).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SPLITSHIFT 11
|
||||||
|
#define SPLITMASK 0x7FF
|
||||||
|
#define SPLITNUM(N) (((__uint32_t)(N)) >> SPLITSHIFT)
|
||||||
|
#define OPAGENUM(N) ((N) & SPLITMASK)
|
||||||
|
#define OADDR_OF(S,O) ((__uint32_t)((__uint32_t)(S) << SPLITSHIFT) + (O))
|
||||||
|
|
||||||
|
#define BUCKET_TO_PAGE(B) \
|
||||||
|
(B) + hashp->HDRPAGES + ((B) ? hashp->SPARES[__log2((B)+1)-1] : 0)
|
||||||
|
#define OADDR_TO_PAGE(B) \
|
||||||
|
BUCKET_TO_PAGE ( (1 << SPLITNUM((B))) -1 ) + OPAGENUM((B));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* page.h contains a detailed description of the page format.
|
||||||
|
*
|
||||||
|
* Normally, keys and data are accessed from offset tables in the top of
|
||||||
|
* each page which point to the beginning of the key and data. There are
|
||||||
|
* four flag values which may be stored in these offset tables which indicate
|
||||||
|
* the following:
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* OVFLPAGE Rather than a key data pair, this pair contains
|
||||||
|
* the address of an overflow page. The format of
|
||||||
|
* the pair is:
|
||||||
|
* OVERFLOW_PAGE_NUMBER OVFLPAGE
|
||||||
|
*
|
||||||
|
* PARTIAL_KEY This must be the first key/data pair on a page
|
||||||
|
* and implies that page contains only a partial key.
|
||||||
|
* That is, the key is too big to fit on a single page
|
||||||
|
* so it starts on this page and continues on the next.
|
||||||
|
* The format of the page is:
|
||||||
|
* KEY_OFF PARTIAL_KEY OVFL_PAGENO OVFLPAGE
|
||||||
|
*
|
||||||
|
* KEY_OFF -- offset of the beginning of the key
|
||||||
|
* PARTIAL_KEY -- 1
|
||||||
|
* OVFL_PAGENO - page number of the next overflow page
|
||||||
|
* OVFLPAGE -- 0
|
||||||
|
*
|
||||||
|
* FULL_KEY This must be the first key/data pair on the page. It
|
||||||
|
* is used in two cases.
|
||||||
|
*
|
||||||
|
* Case 1:
|
||||||
|
* There is a complete key on the page but no data
|
||||||
|
* (because it wouldn't fit). The next page contains
|
||||||
|
* the data.
|
||||||
|
*
|
||||||
|
* Page format it:
|
||||||
|
* KEY_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE
|
||||||
|
*
|
||||||
|
* KEY_OFF -- offset of the beginning of the key
|
||||||
|
* FULL_KEY -- 2
|
||||||
|
* OVFL_PAGENO - page number of the next overflow page
|
||||||
|
* OVFLPAGE -- 0
|
||||||
|
*
|
||||||
|
* Case 2:
|
||||||
|
* This page contains no key, but part of a large
|
||||||
|
* data field, which is continued on the next page.
|
||||||
|
*
|
||||||
|
* Page format it:
|
||||||
|
* DATA_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE
|
||||||
|
*
|
||||||
|
* KEY_OFF -- offset of the beginning of the data on
|
||||||
|
* this page
|
||||||
|
* FULL_KEY -- 2
|
||||||
|
* OVFL_PAGENO - page number of the next overflow page
|
||||||
|
* OVFLPAGE -- 0
|
||||||
|
*
|
||||||
|
* FULL_KEY_DATA
|
||||||
|
* This must be the first key/data pair on the page.
|
||||||
|
* There are two cases:
|
||||||
|
*
|
||||||
|
* Case 1:
|
||||||
|
* This page contains a key and the beginning of the
|
||||||
|
* data field, but the data field is continued on the
|
||||||
|
* next page.
|
||||||
|
*
|
||||||
|
* Page format is:
|
||||||
|
* KEY_OFF FULL_KEY_DATA OVFL_PAGENO DATA_OFF
|
||||||
|
*
|
||||||
|
* KEY_OFF -- offset of the beginning of the key
|
||||||
|
* FULL_KEY_DATA -- 3
|
||||||
|
* OVFL_PAGENO - page number of the next overflow page
|
||||||
|
* DATA_OFF -- offset of the beginning of the data
|
||||||
|
*
|
||||||
|
* Case 2:
|
||||||
|
* This page contains the last page of a big data pair.
|
||||||
|
* There is no key, only the tail end of the data
|
||||||
|
* on this page.
|
||||||
|
*
|
||||||
|
* Page format is:
|
||||||
|
* DATA_OFF FULL_KEY_DATA <OVFL_PAGENO> <OVFLPAGE>
|
||||||
|
*
|
||||||
|
* DATA_OFF -- offset of the beginning of the data on
|
||||||
|
* this page
|
||||||
|
* FULL_KEY_DATA -- 3
|
||||||
|
* OVFL_PAGENO - page number of the next overflow page
|
||||||
|
* OVFLPAGE -- 0
|
||||||
|
*
|
||||||
|
* OVFL_PAGENO and OVFLPAGE are optional (they are
|
||||||
|
* not present if there is no next page).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define OVFLPAGE 0
|
||||||
|
#define PARTIAL_KEY 1
|
||||||
|
#define FULL_KEY 2
|
||||||
|
#define FULL_KEY_DATA 3
|
||||||
|
#define REAL_KEY 4
|
||||||
|
|
||||||
|
/* Short hands for accessing structure */
|
||||||
|
#define BSIZE hdr.bsize
|
||||||
|
#define BSHIFT hdr.bshift
|
||||||
|
#define DSIZE hdr.dsize
|
||||||
|
#define SGSIZE hdr.ssize
|
||||||
|
#define SSHIFT hdr.sshift
|
||||||
|
#define LORDER hdr.lorder
|
||||||
|
#define OVFL_POINT hdr.ovfl_point
|
||||||
|
#define LAST_FREED hdr.last_freed
|
||||||
|
#define MAX_BUCKET hdr.max_bucket
|
||||||
|
#define FFACTOR hdr.ffactor
|
||||||
|
#define HIGH_MASK hdr.high_mask
|
||||||
|
#define LOW_MASK hdr.low_mask
|
||||||
|
#define NKEYS hdr.nkeys
|
||||||
|
#define HDRPAGES hdr.hdrpages
|
||||||
|
#define SPARES hdr.spares
|
||||||
|
#define BITMAPS hdr.bitmaps
|
||||||
|
#define HASH_VERSION hdr.version
|
||||||
|
#define MAGIC hdr.magic
|
||||||
|
#define NEXT_FREE hdr.next_free
|
||||||
|
#define H_CHARKEY hdr.h_charkey
|
669
newlib/libc/search/hash_bigkey.c
Normal file
669
newlib/libc/search/hash_bigkey.c
Normal file
@ -0,0 +1,669 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1990, 1993, 1994
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Margo Seltzer.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the University of
|
||||||
|
* California, Berkeley and its contributors.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
static char sccsid[] = "@(#)hash_bigkey.c 8.3 (Berkeley) 5/31/94";
|
||||||
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PACKAGE: hash
|
||||||
|
* DESCRIPTION:
|
||||||
|
* Big key/data handling for the hashing package.
|
||||||
|
*
|
||||||
|
* ROUTINES:
|
||||||
|
* External
|
||||||
|
* __big_keydata
|
||||||
|
* __big_split
|
||||||
|
* __big_insert
|
||||||
|
* __big_return
|
||||||
|
* __big_delete
|
||||||
|
* __find_last_page
|
||||||
|
* Internal
|
||||||
|
* collect_key
|
||||||
|
* collect_data
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#include <assert.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <db.h>
|
||||||
|
#include "hash.h"
|
||||||
|
#include "page.h"
|
||||||
|
#include "extern.h"
|
||||||
|
|
||||||
|
static int collect_key(HTAB *, BUFHEAD *, int, DBT *, int);
|
||||||
|
static int collect_data(HTAB *, BUFHEAD *, int, int);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Big_insert
|
||||||
|
*
|
||||||
|
* You need to do an insert and the key/data pair is too big
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* 0 ==> OK
|
||||||
|
*-1 ==> ERROR
|
||||||
|
*/
|
||||||
|
extern int
|
||||||
|
__big_insert(hashp, bufp, key, val)
|
||||||
|
HTAB *hashp;
|
||||||
|
BUFHEAD *bufp;
|
||||||
|
const DBT *key, *val;
|
||||||
|
{
|
||||||
|
__uint16_t *p;
|
||||||
|
int key_size, n, val_size;
|
||||||
|
__uint16_t space, move_bytes, off;
|
||||||
|
char *cp, *key_data, *val_data;
|
||||||
|
|
||||||
|
cp = bufp->page; /* Character pointer of p. */
|
||||||
|
p = (__uint16_t *)cp;
|
||||||
|
|
||||||
|
key_data = (char *)key->data;
|
||||||
|
key_size = key->size;
|
||||||
|
val_data = (char *)val->data;
|
||||||
|
val_size = val->size;
|
||||||
|
|
||||||
|
/* First move the Key */
|
||||||
|
for (space = FREESPACE(p) - BIGOVERHEAD; key_size;
|
||||||
|
space = FREESPACE(p) - BIGOVERHEAD) {
|
||||||
|
move_bytes = MIN(space, key_size);
|
||||||
|
off = OFFSET(p) - move_bytes;
|
||||||
|
memmove(cp + off, key_data, move_bytes);
|
||||||
|
key_size -= move_bytes;
|
||||||
|
key_data += move_bytes;
|
||||||
|
n = p[0];
|
||||||
|
p[++n] = off;
|
||||||
|
p[0] = ++n;
|
||||||
|
FREESPACE(p) = off - PAGE_META(n);
|
||||||
|
OFFSET(p) = off;
|
||||||
|
p[n] = PARTIAL_KEY;
|
||||||
|
bufp = __add_ovflpage(hashp, bufp);
|
||||||
|
if (!bufp)
|
||||||
|
return (-1);
|
||||||
|
n = p[0];
|
||||||
|
if (!key_size)
|
||||||
|
if (FREESPACE(p)) {
|
||||||
|
move_bytes = MIN(FREESPACE(p), val_size);
|
||||||
|
off = OFFSET(p) - move_bytes;
|
||||||
|
p[n] = off;
|
||||||
|
memmove(cp + off, val_data, move_bytes);
|
||||||
|
val_data += move_bytes;
|
||||||
|
val_size -= move_bytes;
|
||||||
|
p[n - 2] = FULL_KEY_DATA;
|
||||||
|
FREESPACE(p) = FREESPACE(p) - move_bytes;
|
||||||
|
OFFSET(p) = off;
|
||||||
|
} else
|
||||||
|
p[n - 2] = FULL_KEY;
|
||||||
|
p = (__uint16_t *)bufp->page;
|
||||||
|
cp = bufp->page;
|
||||||
|
bufp->flags |= BUF_MOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now move the data */
|
||||||
|
for (space = FREESPACE(p) - BIGOVERHEAD; val_size;
|
||||||
|
space = FREESPACE(p) - BIGOVERHEAD) {
|
||||||
|
move_bytes = MIN(space, val_size);
|
||||||
|
/*
|
||||||
|
* Here's the hack to make sure that if the data ends on the
|
||||||
|
* same page as the key ends, FREESPACE is at least one.
|
||||||
|
*/
|
||||||
|
if (space == val_size && val_size == val->size)
|
||||||
|
move_bytes--;
|
||||||
|
off = OFFSET(p) - move_bytes;
|
||||||
|
memmove(cp + off, val_data, move_bytes);
|
||||||
|
val_size -= move_bytes;
|
||||||
|
val_data += move_bytes;
|
||||||
|
n = p[0];
|
||||||
|
p[++n] = off;
|
||||||
|
p[0] = ++n;
|
||||||
|
FREESPACE(p) = off - PAGE_META(n);
|
||||||
|
OFFSET(p) = off;
|
||||||
|
if (val_size) {
|
||||||
|
p[n] = FULL_KEY;
|
||||||
|
bufp = __add_ovflpage(hashp, bufp);
|
||||||
|
if (!bufp)
|
||||||
|
return (-1);
|
||||||
|
cp = bufp->page;
|
||||||
|
p = (__uint16_t *)cp;
|
||||||
|
} else
|
||||||
|
p[n] = FULL_KEY_DATA;
|
||||||
|
bufp->flags |= BUF_MOD;
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called when bufp's page contains a partial key (index should be 1)
|
||||||
|
*
|
||||||
|
* All pages in the big key/data pair except bufp are freed. We cannot
|
||||||
|
* free bufp because the page pointing to it is lost and we can't get rid
|
||||||
|
* of its pointer.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* 0 => OK
|
||||||
|
*-1 => ERROR
|
||||||
|
*/
|
||||||
|
extern int
|
||||||
|
__big_delete(hashp, bufp)
|
||||||
|
HTAB *hashp;
|
||||||
|
BUFHEAD *bufp;
|
||||||
|
{
|
||||||
|
BUFHEAD *last_bfp, *rbufp;
|
||||||
|
__uint16_t *bp, pageno;
|
||||||
|
int key_done, n;
|
||||||
|
|
||||||
|
rbufp = bufp;
|
||||||
|
last_bfp = NULL;
|
||||||
|
bp = (__uint16_t *)bufp->page;
|
||||||
|
pageno = 0;
|
||||||
|
key_done = 0;
|
||||||
|
|
||||||
|
while (!key_done || (bp[2] != FULL_KEY_DATA)) {
|
||||||
|
if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA)
|
||||||
|
key_done = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there is freespace left on a FULL_KEY_DATA page, then
|
||||||
|
* the data is short and fits entirely on this page, and this
|
||||||
|
* is the last page.
|
||||||
|
*/
|
||||||
|
if (bp[2] == FULL_KEY_DATA && FREESPACE(bp))
|
||||||
|
break;
|
||||||
|
pageno = bp[bp[0] - 1];
|
||||||
|
rbufp->flags |= BUF_MOD;
|
||||||
|
rbufp = __get_buf(hashp, pageno, rbufp, 0);
|
||||||
|
if (last_bfp)
|
||||||
|
__free_ovflpage(hashp, last_bfp);
|
||||||
|
last_bfp = rbufp;
|
||||||
|
if (!rbufp)
|
||||||
|
return (-1); /* Error. */
|
||||||
|
bp = (__uint16_t *)rbufp->page;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we get here then rbufp points to the last page of the big
|
||||||
|
* key/data pair. Bufp points to the first one -- it should now be
|
||||||
|
* empty pointing to the next page after this pair. Can't free it
|
||||||
|
* because we don't have the page pointing to it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This is information from the last page of the pair. */
|
||||||
|
n = bp[0];
|
||||||
|
pageno = bp[n - 1];
|
||||||
|
|
||||||
|
/* Now, bp is the first page of the pair. */
|
||||||
|
bp = (__uint16_t *)bufp->page;
|
||||||
|
if (n > 2) {
|
||||||
|
/* There is an overflow page. */
|
||||||
|
bp[1] = pageno;
|
||||||
|
bp[2] = OVFLPAGE;
|
||||||
|
bufp->ovfl = rbufp->ovfl;
|
||||||
|
} else
|
||||||
|
/* This is the last page. */
|
||||||
|
bufp->ovfl = NULL;
|
||||||
|
n -= 2;
|
||||||
|
bp[0] = n;
|
||||||
|
FREESPACE(bp) = hashp->BSIZE - PAGE_META(n);
|
||||||
|
OFFSET(bp) = hashp->BSIZE - 1;
|
||||||
|
|
||||||
|
bufp->flags |= BUF_MOD;
|
||||||
|
if (rbufp)
|
||||||
|
__free_ovflpage(hashp, rbufp);
|
||||||
|
if (last_bfp != rbufp)
|
||||||
|
__free_ovflpage(hashp, last_bfp);
|
||||||
|
|
||||||
|
hashp->NKEYS--;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Returns:
|
||||||
|
* 0 = key not found
|
||||||
|
* -1 = get next overflow page
|
||||||
|
* -2 means key not found and this is big key/data
|
||||||
|
* -3 error
|
||||||
|
*/
|
||||||
|
extern int
|
||||||
|
__find_bigpair(hashp, bufp, ndx, key, size)
|
||||||
|
HTAB *hashp;
|
||||||
|
BUFHEAD *bufp;
|
||||||
|
int ndx;
|
||||||
|
char *key;
|
||||||
|
int size;
|
||||||
|
{
|
||||||
|
__uint16_t *bp;
|
||||||
|
char *p;
|
||||||
|
int ksize;
|
||||||
|
__uint16_t bytes;
|
||||||
|
char *kkey;
|
||||||
|
|
||||||
|
bp = (__uint16_t *)bufp->page;
|
||||||
|
p = bufp->page;
|
||||||
|
ksize = size;
|
||||||
|
kkey = key;
|
||||||
|
|
||||||
|
for (bytes = hashp->BSIZE - bp[ndx];
|
||||||
|
bytes <= size && bp[ndx + 1] == PARTIAL_KEY;
|
||||||
|
bytes = hashp->BSIZE - bp[ndx]) {
|
||||||
|
if (memcmp(p + bp[ndx], kkey, bytes))
|
||||||
|
return (-2);
|
||||||
|
kkey += bytes;
|
||||||
|
ksize -= bytes;
|
||||||
|
bufp = __get_buf(hashp, bp[ndx + 2], bufp, 0);
|
||||||
|
if (!bufp)
|
||||||
|
return (-3);
|
||||||
|
p = bufp->page;
|
||||||
|
bp = (__uint16_t *)p;
|
||||||
|
ndx = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytes != ksize || memcmp(p + bp[ndx], kkey, bytes)) {
|
||||||
|
#ifdef HASH_STATISTICS
|
||||||
|
++hash_collisions;
|
||||||
|
#endif
|
||||||
|
return (-2);
|
||||||
|
} else
|
||||||
|
return (ndx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Given the buffer pointer of the first overflow page of a big pair,
|
||||||
|
* find the end of the big pair
|
||||||
|
*
|
||||||
|
* This will set bpp to the buffer header of the last page of the big pair.
|
||||||
|
* It will return the pageno of the overflow page following the last page
|
||||||
|
* of the pair; 0 if there isn't any (i.e. big pair is the last key in the
|
||||||
|
* bucket)
|
||||||
|
*/
|
||||||
|
extern __uint16_t
|
||||||
|
__find_last_page(hashp, bpp)
|
||||||
|
HTAB *hashp;
|
||||||
|
BUFHEAD **bpp;
|
||||||
|
{
|
||||||
|
BUFHEAD *bufp;
|
||||||
|
__uint16_t *bp, pageno;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
bufp = *bpp;
|
||||||
|
bp = (__uint16_t *)bufp->page;
|
||||||
|
for (;;) {
|
||||||
|
n = bp[0];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the last page if: the tag is FULL_KEY_DATA and
|
||||||
|
* either only 2 entries OVFLPAGE marker is explicit there
|
||||||
|
* is freespace on the page.
|
||||||
|
*/
|
||||||
|
if (bp[2] == FULL_KEY_DATA &&
|
||||||
|
((n == 2) || (bp[n] == OVFLPAGE) || (FREESPACE(bp))))
|
||||||
|
break;
|
||||||
|
|
||||||
|
pageno = bp[n - 1];
|
||||||
|
bufp = __get_buf(hashp, pageno, bufp, 0);
|
||||||
|
if (!bufp)
|
||||||
|
return (0); /* Need to indicate an error! */
|
||||||
|
bp = (__uint16_t *)bufp->page;
|
||||||
|
}
|
||||||
|
|
||||||
|
*bpp = bufp;
|
||||||
|
if (bp[0] > 2)
|
||||||
|
return (bp[3]);
|
||||||
|
else
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the data for the key/data pair that begins on this page at this
|
||||||
|
* index (index should always be 1).
|
||||||
|
*/
|
||||||
|
extern int
|
||||||
|
__big_return(hashp, bufp, ndx, val, set_current)
|
||||||
|
HTAB *hashp;
|
||||||
|
BUFHEAD *bufp;
|
||||||
|
int ndx;
|
||||||
|
DBT *val;
|
||||||
|
int set_current;
|
||||||
|
{
|
||||||
|
BUFHEAD *save_p;
|
||||||
|
__uint16_t *bp, len, off, save_addr;
|
||||||
|
char *tp;
|
||||||
|
|
||||||
|
bp = (__uint16_t *)bufp->page;
|
||||||
|
while (bp[ndx + 1] == PARTIAL_KEY) {
|
||||||
|
bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
|
||||||
|
if (!bufp)
|
||||||
|
return (-1);
|
||||||
|
bp = (__uint16_t *)bufp->page;
|
||||||
|
ndx = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bp[ndx + 1] == FULL_KEY) {
|
||||||
|
bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
|
||||||
|
if (!bufp)
|
||||||
|
return (-1);
|
||||||
|
bp = (__uint16_t *)bufp->page;
|
||||||
|
save_p = bufp;
|
||||||
|
save_addr = save_p->addr;
|
||||||
|
off = bp[1];
|
||||||
|
len = 0;
|
||||||
|
} else
|
||||||
|
if (!FREESPACE(bp)) {
|
||||||
|
/*
|
||||||
|
* This is a hack. We can't distinguish between
|
||||||
|
* FULL_KEY_DATA that contains complete data or
|
||||||
|
* incomplete data, so we require that if the data
|
||||||
|
* is complete, there is at least 1 byte of free
|
||||||
|
* space left.
|
||||||
|
*/
|
||||||
|
off = bp[bp[0]];
|
||||||
|
len = bp[1] - off;
|
||||||
|
save_p = bufp;
|
||||||
|
save_addr = bufp->addr;
|
||||||
|
bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
|
||||||
|
if (!bufp)
|
||||||
|
return (-1);
|
||||||
|
bp = (__uint16_t *)bufp->page;
|
||||||
|
} else {
|
||||||
|
/* The data is all on one page. */
|
||||||
|
tp = (char *)bp;
|
||||||
|
off = bp[bp[0]];
|
||||||
|
val->data = (u_char *)tp + off;
|
||||||
|
val->size = bp[1] - off;
|
||||||
|
if (set_current) {
|
||||||
|
if (bp[0] == 2) { /* No more buckets in
|
||||||
|
* chain */
|
||||||
|
hashp->cpage = NULL;
|
||||||
|
hashp->cbucket++;
|
||||||
|
hashp->cndx = 1;
|
||||||
|
} else {
|
||||||
|
hashp->cpage = __get_buf(hashp,
|
||||||
|
bp[bp[0] - 1], bufp, 0);
|
||||||
|
if (!hashp->cpage)
|
||||||
|
return (-1);
|
||||||
|
hashp->cndx = 1;
|
||||||
|
if (!((__uint16_t *)
|
||||||
|
hashp->cpage->page)[0]) {
|
||||||
|
hashp->cbucket++;
|
||||||
|
hashp->cpage = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
val->size = collect_data(hashp, bufp, (int)len, set_current);
|
||||||
|
if (val->size == -1)
|
||||||
|
return (-1);
|
||||||
|
if (save_p->addr != save_addr) {
|
||||||
|
/* We are pretty short on buffers. */
|
||||||
|
errno = EINVAL; /* OUT OF BUFFERS */
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
memmove(hashp->tmp_buf, (save_p->page) + off, len);
|
||||||
|
val->data = (u_char *)hashp->tmp_buf;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Count how big the total datasize is by recursing through the pages. Then
|
||||||
|
* allocate a buffer and copy the data as you recurse up.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
collect_data(hashp, bufp, len, set)
|
||||||
|
HTAB *hashp;
|
||||||
|
BUFHEAD *bufp;
|
||||||
|
int len, set;
|
||||||
|
{
|
||||||
|
__uint16_t *bp;
|
||||||
|
char *p;
|
||||||
|
BUFHEAD *xbp;
|
||||||
|
__uint16_t save_addr;
|
||||||
|
int mylen, totlen;
|
||||||
|
|
||||||
|
p = bufp->page;
|
||||||
|
bp = (__uint16_t *)p;
|
||||||
|
mylen = hashp->BSIZE - bp[1];
|
||||||
|
save_addr = bufp->addr;
|
||||||
|
|
||||||
|
if (bp[2] == FULL_KEY_DATA) { /* End of Data */
|
||||||
|
totlen = len + mylen;
|
||||||
|
if (hashp->tmp_buf)
|
||||||
|
free(hashp->tmp_buf);
|
||||||
|
if ((hashp->tmp_buf = (char *)malloc(totlen)) == NULL)
|
||||||
|
return (-1);
|
||||||
|
if (set) {
|
||||||
|
hashp->cndx = 1;
|
||||||
|
if (bp[0] == 2) { /* No more buckets in chain */
|
||||||
|
hashp->cpage = NULL;
|
||||||
|
hashp->cbucket++;
|
||||||
|
} else {
|
||||||
|
hashp->cpage =
|
||||||
|
__get_buf(hashp, bp[bp[0] - 1], bufp, 0);
|
||||||
|
if (!hashp->cpage)
|
||||||
|
return (-1);
|
||||||
|
else if (!((__uint16_t *)hashp->cpage->page)[0]) {
|
||||||
|
hashp->cbucket++;
|
||||||
|
hashp->cpage = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
xbp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
|
||||||
|
if (!xbp || ((totlen =
|
||||||
|
collect_data(hashp, xbp, len + mylen, set)) < 1))
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (bufp->addr != save_addr) {
|
||||||
|
errno = EINVAL; /* Out of buffers. */
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
memmove(&hashp->tmp_buf[len], (bufp->page) + bp[1], mylen);
|
||||||
|
return (totlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fill in the key and data for this big pair.
|
||||||
|
*/
|
||||||
|
extern int
|
||||||
|
__big_keydata(hashp, bufp, key, val, set)
|
||||||
|
HTAB *hashp;
|
||||||
|
BUFHEAD *bufp;
|
||||||
|
DBT *key, *val;
|
||||||
|
int set;
|
||||||
|
{
|
||||||
|
key->size = collect_key(hashp, bufp, 0, val, set);
|
||||||
|
if (key->size == -1)
|
||||||
|
return (-1);
|
||||||
|
key->data = (u_char *)hashp->tmp_key;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Count how big the total key size is by recursing through the pages. Then
|
||||||
|
* collect the data, allocate a buffer and copy the key as you recurse up.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
collect_key(hashp, bufp, len, val, set)
|
||||||
|
HTAB *hashp;
|
||||||
|
BUFHEAD *bufp;
|
||||||
|
int len;
|
||||||
|
DBT *val;
|
||||||
|
int set;
|
||||||
|
{
|
||||||
|
BUFHEAD *xbp;
|
||||||
|
char *p;
|
||||||
|
int mylen, totlen;
|
||||||
|
__uint16_t *bp, save_addr;
|
||||||
|
|
||||||
|
p = bufp->page;
|
||||||
|
bp = (__uint16_t *)p;
|
||||||
|
mylen = hashp->BSIZE - bp[1];
|
||||||
|
|
||||||
|
save_addr = bufp->addr;
|
||||||
|
totlen = len + mylen;
|
||||||
|
if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA) { /* End of Key. */
|
||||||
|
if (hashp->tmp_key != NULL)
|
||||||
|
free(hashp->tmp_key);
|
||||||
|
if ((hashp->tmp_key = (char *)malloc(totlen)) == NULL)
|
||||||
|
return (-1);
|
||||||
|
if (__big_return(hashp, bufp, 1, val, set))
|
||||||
|
return (-1);
|
||||||
|
} else {
|
||||||
|
xbp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
|
||||||
|
if (!xbp || ((totlen =
|
||||||
|
collect_key(hashp, xbp, totlen, val, set)) < 1))
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (bufp->addr != save_addr) {
|
||||||
|
errno = EINVAL; /* MIS -- OUT OF BUFFERS */
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
memmove(&hashp->tmp_key[len], (bufp->page) + bp[1], mylen);
|
||||||
|
return (totlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns:
|
||||||
|
* 0 => OK
|
||||||
|
* -1 => error
|
||||||
|
*/
|
||||||
|
extern int
|
||||||
|
__big_split(hashp, op, np, big_keyp, addr, obucket, ret)
|
||||||
|
HTAB *hashp;
|
||||||
|
BUFHEAD *op; /* Pointer to where to put keys that go in old bucket */
|
||||||
|
BUFHEAD *np; /* Pointer to new bucket page */
|
||||||
|
/* Pointer to first page containing the big key/data */
|
||||||
|
BUFHEAD *big_keyp;
|
||||||
|
int addr; /* Address of big_keyp */
|
||||||
|
__uint32_t obucket;/* Old Bucket */
|
||||||
|
SPLIT_RETURN *ret;
|
||||||
|
{
|
||||||
|
BUFHEAD *tmpp;
|
||||||
|
__uint16_t *tp;
|
||||||
|
BUFHEAD *bp;
|
||||||
|
DBT key, val;
|
||||||
|
__uint32_t change;
|
||||||
|
__uint16_t free_space, n, off;
|
||||||
|
|
||||||
|
bp = big_keyp;
|
||||||
|
|
||||||
|
/* Now figure out where the big key/data goes */
|
||||||
|
if (__big_keydata(hashp, big_keyp, &key, &val, 0))
|
||||||
|
return (-1);
|
||||||
|
change = (__call_hash(hashp, key.data, key.size) != obucket);
|
||||||
|
|
||||||
|
if ( (ret->next_addr = __find_last_page(hashp, &big_keyp)) ) {
|
||||||
|
if (!(ret->nextp =
|
||||||
|
__get_buf(hashp, ret->next_addr, big_keyp, 0)))
|
||||||
|
return (-1);;
|
||||||
|
} else
|
||||||
|
ret->nextp = NULL;
|
||||||
|
|
||||||
|
/* Now make one of np/op point to the big key/data pair */
|
||||||
|
#ifdef DEBUG
|
||||||
|
assert(np->ovfl == NULL);
|
||||||
|
#endif
|
||||||
|
if (change)
|
||||||
|
tmpp = np;
|
||||||
|
else
|
||||||
|
tmpp = op;
|
||||||
|
|
||||||
|
tmpp->flags |= BUF_MOD;
|
||||||
|
#ifdef DEBUG1
|
||||||
|
(void)fprintf(stderr,
|
||||||
|
"BIG_SPLIT: %d->ovfl was %d is now %d\n", tmpp->addr,
|
||||||
|
(tmpp->ovfl ? tmpp->ovfl->addr : 0), (bp ? bp->addr : 0));
|
||||||
|
#endif
|
||||||
|
tmpp->ovfl = bp; /* one of op/np point to big_keyp */
|
||||||
|
tp = (__uint16_t *)tmpp->page;
|
||||||
|
#ifdef DEBUG
|
||||||
|
assert(FREESPACE(tp) >= OVFLSIZE);
|
||||||
|
#endif
|
||||||
|
n = tp[0];
|
||||||
|
off = OFFSET(tp);
|
||||||
|
free_space = FREESPACE(tp);
|
||||||
|
tp[++n] = (__uint16_t)addr;
|
||||||
|
tp[++n] = OVFLPAGE;
|
||||||
|
tp[0] = n;
|
||||||
|
OFFSET(tp) = off;
|
||||||
|
FREESPACE(tp) = free_space - OVFLSIZE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Finally, set the new and old return values. BIG_KEYP contains a
|
||||||
|
* pointer to the last page of the big key_data pair. Make sure that
|
||||||
|
* big_keyp has no following page (2 elements) or create an empty
|
||||||
|
* following page.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret->newp = np;
|
||||||
|
ret->oldp = op;
|
||||||
|
|
||||||
|
tp = (__uint16_t *)big_keyp->page;
|
||||||
|
big_keyp->flags |= BUF_MOD;
|
||||||
|
if (tp[0] > 2) {
|
||||||
|
/*
|
||||||
|
* There may be either one or two offsets on this page. If
|
||||||
|
* there is one, then the overflow page is linked on normally
|
||||||
|
* and tp[4] is OVFLPAGE. If there are two, tp[4] contains
|
||||||
|
* the second offset and needs to get stuffed in after the
|
||||||
|
* next overflow page is added.
|
||||||
|
*/
|
||||||
|
n = tp[4];
|
||||||
|
free_space = FREESPACE(tp);
|
||||||
|
off = OFFSET(tp);
|
||||||
|
tp[0] -= 2;
|
||||||
|
FREESPACE(tp) = free_space + OVFLSIZE;
|
||||||
|
OFFSET(tp) = off;
|
||||||
|
tmpp = __add_ovflpage(hashp, big_keyp);
|
||||||
|
if (!tmpp)
|
||||||
|
return (-1);
|
||||||
|
tp[4] = n;
|
||||||
|
} else
|
||||||
|
tmpp = big_keyp;
|
||||||
|
|
||||||
|
if (change)
|
||||||
|
ret->newp = tmpp;
|
||||||
|
else
|
||||||
|
ret->oldp = tmpp;
|
||||||
|
return (0);
|
||||||
|
}
|
356
newlib/libc/search/hash_buf.c
Normal file
356
newlib/libc/search/hash_buf.c
Normal file
@ -0,0 +1,356 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1990, 1993, 1994
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Margo Seltzer.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the University of
|
||||||
|
* California, Berkeley and its contributors.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
static char sccsid[] = "@(#)hash_buf.c 8.5 (Berkeley) 7/15/94";
|
||||||
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PACKAGE: hash
|
||||||
|
*
|
||||||
|
* DESCRIPTION:
|
||||||
|
* Contains buffer management
|
||||||
|
*
|
||||||
|
* ROUTINES:
|
||||||
|
* External
|
||||||
|
* __buf_init
|
||||||
|
* __get_buf
|
||||||
|
* __buf_free
|
||||||
|
* __reclaim_buf
|
||||||
|
* Internal
|
||||||
|
* newbuf
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#include <assert.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <db.h>
|
||||||
|
#include "hash.h"
|
||||||
|
#include "page.h"
|
||||||
|
#include "extern.h"
|
||||||
|
|
||||||
|
static BUFHEAD *newbuf(HTAB *, __uint32_t, BUFHEAD *);
|
||||||
|
|
||||||
|
/* Unlink B from its place in the lru */
|
||||||
|
#define BUF_REMOVE(B) { \
|
||||||
|
(B)->prev->next = (B)->next; \
|
||||||
|
(B)->next->prev = (B)->prev; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Insert B after P */
|
||||||
|
#define BUF_INSERT(B, P) { \
|
||||||
|
(B)->next = (P)->next; \
|
||||||
|
(B)->prev = (P); \
|
||||||
|
(P)->next = (B); \
|
||||||
|
(B)->next->prev = (B); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MRU hashp->bufhead.next
|
||||||
|
#define LRU hashp->bufhead.prev
|
||||||
|
|
||||||
|
#define MRU_INSERT(B) BUF_INSERT((B), &hashp->bufhead)
|
||||||
|
#define LRU_INSERT(B) BUF_INSERT((B), LRU)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We are looking for a buffer with address "addr". If prev_bp is NULL, then
|
||||||
|
* address is a bucket index. If prev_bp is not NULL, then it points to the
|
||||||
|
* page previous to an overflow page that we are trying to find.
|
||||||
|
*
|
||||||
|
* CAVEAT: The buffer header accessed via prev_bp's ovfl field may no longer
|
||||||
|
* be valid. Therefore, you must always verify that its address matches the
|
||||||
|
* address you are seeking.
|
||||||
|
*/
|
||||||
|
extern BUFHEAD *
|
||||||
|
__get_buf(hashp, addr, prev_bp, newpage)
|
||||||
|
HTAB *hashp;
|
||||||
|
__uint32_t addr;
|
||||||
|
BUFHEAD *prev_bp;
|
||||||
|
int newpage; /* If prev_bp set, indicates a new overflow page. */
|
||||||
|
{
|
||||||
|
BUFHEAD *bp;
|
||||||
|
__uint32_t is_disk_mask;
|
||||||
|
int is_disk, segment_ndx;
|
||||||
|
SEGMENT segp;
|
||||||
|
|
||||||
|
is_disk = 0;
|
||||||
|
is_disk_mask = 0;
|
||||||
|
if (prev_bp) {
|
||||||
|
bp = prev_bp->ovfl;
|
||||||
|
if (!bp || (bp->addr != addr))
|
||||||
|
bp = NULL;
|
||||||
|
if (!newpage)
|
||||||
|
is_disk = BUF_DISK;
|
||||||
|
} else {
|
||||||
|
/* Grab buffer out of directory */
|
||||||
|
segment_ndx = addr & (hashp->SGSIZE - 1);
|
||||||
|
|
||||||
|
/* valid segment ensured by __call_hash() */
|
||||||
|
segp = hashp->dir[addr >> hashp->SSHIFT];
|
||||||
|
#ifdef DEBUG
|
||||||
|
assert(segp != NULL);
|
||||||
|
#endif
|
||||||
|
bp = PTROF(segp[segment_ndx]);
|
||||||
|
is_disk_mask = ISDISK(segp[segment_ndx]);
|
||||||
|
is_disk = is_disk_mask || !hashp->new_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bp) {
|
||||||
|
bp = newbuf(hashp, addr, prev_bp);
|
||||||
|
if (!bp ||
|
||||||
|
__get_page(hashp, bp->page, addr, !prev_bp, is_disk, 0))
|
||||||
|
return (NULL);
|
||||||
|
if (!prev_bp)
|
||||||
|
segp[segment_ndx] =
|
||||||
|
(BUFHEAD *)((ptrdiff_t)bp | is_disk_mask);
|
||||||
|
} else {
|
||||||
|
BUF_REMOVE(bp);
|
||||||
|
MRU_INSERT(bp);
|
||||||
|
}
|
||||||
|
return (bp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need a buffer for this page. Either allocate one, or evict a resident
|
||||||
|
* one (if we have as many buffers as we're allowed) and put this one in.
|
||||||
|
*
|
||||||
|
* If newbuf finds an error (returning NULL), it also sets errno.
|
||||||
|
*/
|
||||||
|
static BUFHEAD *
|
||||||
|
newbuf(hashp, addr, prev_bp)
|
||||||
|
HTAB *hashp;
|
||||||
|
__uint32_t addr;
|
||||||
|
BUFHEAD *prev_bp;
|
||||||
|
{
|
||||||
|
BUFHEAD *bp; /* The buffer we're going to use */
|
||||||
|
BUFHEAD *xbp; /* Temp pointer */
|
||||||
|
BUFHEAD *next_xbp;
|
||||||
|
SEGMENT segp;
|
||||||
|
int segment_ndx;
|
||||||
|
__uint16_t oaddr, *shortp;
|
||||||
|
|
||||||
|
oaddr = 0;
|
||||||
|
bp = LRU;
|
||||||
|
/*
|
||||||
|
* If LRU buffer is pinned, the buffer pool is too small. We need to
|
||||||
|
* allocate more buffers.
|
||||||
|
*/
|
||||||
|
if (hashp->nbufs || (bp->flags & BUF_PIN)) {
|
||||||
|
/* Allocate a new one */
|
||||||
|
if ((bp = (BUFHEAD *)malloc(sizeof(BUFHEAD))) == NULL)
|
||||||
|
return (NULL);
|
||||||
|
#ifdef PURIFY
|
||||||
|
memset(bp, 0xff, sizeof(BUFHEAD));
|
||||||
|
#endif
|
||||||
|
if ((bp->page = (char *)malloc(hashp->BSIZE)) == NULL) {
|
||||||
|
free(bp);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
#ifdef PURIFY
|
||||||
|
memset(bp->page, 0xff, hashp->BSIZE);
|
||||||
|
#endif
|
||||||
|
if (hashp->nbufs)
|
||||||
|
hashp->nbufs--;
|
||||||
|
} else {
|
||||||
|
/* Kick someone out */
|
||||||
|
BUF_REMOVE(bp);
|
||||||
|
/*
|
||||||
|
* If this is an overflow page with addr 0, it's already been
|
||||||
|
* flushed back in an overflow chain and initialized.
|
||||||
|
*/
|
||||||
|
if ((bp->addr != 0) || (bp->flags & BUF_BUCKET)) {
|
||||||
|
/*
|
||||||
|
* Set oaddr before __put_page so that you get it
|
||||||
|
* before bytes are swapped.
|
||||||
|
*/
|
||||||
|
shortp = (__uint16_t *)bp->page;
|
||||||
|
if (shortp[0])
|
||||||
|
oaddr = shortp[shortp[0] - 1];
|
||||||
|
if ((bp->flags & BUF_MOD) && __put_page(hashp, bp->page,
|
||||||
|
bp->addr, (int)IS_BUCKET(bp->flags), 0))
|
||||||
|
return (NULL);
|
||||||
|
/*
|
||||||
|
* Update the pointer to this page (i.e. invalidate it).
|
||||||
|
*
|
||||||
|
* If this is a new file (i.e. we created it at open
|
||||||
|
* time), make sure that we mark pages which have been
|
||||||
|
* written to disk so we retrieve them from disk later,
|
||||||
|
* rather than allocating new pages.
|
||||||
|
*/
|
||||||
|
if (IS_BUCKET(bp->flags)) {
|
||||||
|
segment_ndx = bp->addr & (hashp->SGSIZE - 1);
|
||||||
|
segp = hashp->dir[bp->addr >> hashp->SSHIFT];
|
||||||
|
#ifdef DEBUG
|
||||||
|
assert(segp != NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (hashp->new_file &&
|
||||||
|
((bp->flags & BUF_MOD) ||
|
||||||
|
ISDISK(segp[segment_ndx])))
|
||||||
|
segp[segment_ndx] = (BUFHEAD *)BUF_DISK;
|
||||||
|
else
|
||||||
|
segp[segment_ndx] = NULL;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Since overflow pages can only be access by means of
|
||||||
|
* their bucket, free overflow pages associated with
|
||||||
|
* this bucket.
|
||||||
|
*/
|
||||||
|
for (xbp = bp; xbp->ovfl;) {
|
||||||
|
next_xbp = xbp->ovfl;
|
||||||
|
xbp->ovfl = 0;
|
||||||
|
xbp = next_xbp;
|
||||||
|
|
||||||
|
/* Check that ovfl pointer is up date. */
|
||||||
|
if (IS_BUCKET(xbp->flags) ||
|
||||||
|
(oaddr != xbp->addr))
|
||||||
|
break;
|
||||||
|
|
||||||
|
shortp = (__uint16_t *)xbp->page;
|
||||||
|
if (shortp[0])
|
||||||
|
/* set before __put_page */
|
||||||
|
oaddr = shortp[shortp[0] - 1];
|
||||||
|
if ((xbp->flags & BUF_MOD) && __put_page(hashp,
|
||||||
|
xbp->page, xbp->addr, 0, 0))
|
||||||
|
return (NULL);
|
||||||
|
xbp->addr = 0;
|
||||||
|
xbp->flags = 0;
|
||||||
|
BUF_REMOVE(xbp);
|
||||||
|
LRU_INSERT(xbp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now assign this buffer */
|
||||||
|
bp->addr = addr;
|
||||||
|
#ifdef DEBUG1
|
||||||
|
(void)fprintf(stderr, "NEWBUF1: %d->ovfl was %d is now %d\n",
|
||||||
|
bp->addr, (bp->ovfl ? bp->ovfl->addr : 0), 0);
|
||||||
|
#endif
|
||||||
|
bp->ovfl = NULL;
|
||||||
|
if (prev_bp) {
|
||||||
|
/*
|
||||||
|
* If prev_bp is set, this is an overflow page, hook it in to
|
||||||
|
* the buffer overflow links.
|
||||||
|
*/
|
||||||
|
#ifdef DEBUG1
|
||||||
|
(void)fprintf(stderr, "NEWBUF2: %d->ovfl was %d is now %d\n",
|
||||||
|
prev_bp->addr, (prev_bp->ovfl ? bp->ovfl->addr : 0),
|
||||||
|
(bp ? bp->addr : 0));
|
||||||
|
#endif
|
||||||
|
prev_bp->ovfl = bp;
|
||||||
|
bp->flags = 0;
|
||||||
|
} else
|
||||||
|
bp->flags = BUF_BUCKET;
|
||||||
|
MRU_INSERT(bp);
|
||||||
|
return (bp);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void
|
||||||
|
__buf_init(hashp, nbytes)
|
||||||
|
HTAB *hashp;
|
||||||
|
int nbytes;
|
||||||
|
{
|
||||||
|
BUFHEAD *bfp;
|
||||||
|
int npages;
|
||||||
|
|
||||||
|
bfp = &(hashp->bufhead);
|
||||||
|
npages = (nbytes + hashp->BSIZE - 1) >> hashp->BSHIFT;
|
||||||
|
npages = MAX(npages, MIN_BUFFERS);
|
||||||
|
|
||||||
|
hashp->nbufs = npages;
|
||||||
|
bfp->next = bfp;
|
||||||
|
bfp->prev = bfp;
|
||||||
|
/*
|
||||||
|
* This space is calloc'd so these are already null.
|
||||||
|
*
|
||||||
|
* bfp->ovfl = NULL;
|
||||||
|
* bfp->flags = 0;
|
||||||
|
* bfp->page = NULL;
|
||||||
|
* bfp->addr = 0;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
extern int
|
||||||
|
__buf_free(hashp, do_free, to_disk)
|
||||||
|
HTAB *hashp;
|
||||||
|
int do_free, to_disk;
|
||||||
|
{
|
||||||
|
BUFHEAD *bp;
|
||||||
|
|
||||||
|
/* Need to make sure that buffer manager has been initialized */
|
||||||
|
if (!LRU)
|
||||||
|
return (0);
|
||||||
|
for (bp = LRU; bp != &hashp->bufhead;) {
|
||||||
|
/* Check that the buffer is valid */
|
||||||
|
if (bp->addr || IS_BUCKET(bp->flags)) {
|
||||||
|
if (to_disk && (bp->flags & BUF_MOD) &&
|
||||||
|
__put_page(hashp, bp->page,
|
||||||
|
bp->addr, IS_BUCKET(bp->flags), 0))
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
/* Check if we are freeing stuff */
|
||||||
|
if (do_free) {
|
||||||
|
if (bp->page)
|
||||||
|
free(bp->page);
|
||||||
|
BUF_REMOVE(bp);
|
||||||
|
free(bp);
|
||||||
|
bp = LRU;
|
||||||
|
} else
|
||||||
|
bp = bp->prev;
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void
|
||||||
|
__reclaim_buf(hashp, bp)
|
||||||
|
HTAB *hashp;
|
||||||
|
BUFHEAD *bp;
|
||||||
|
{
|
||||||
|
bp->ovfl = 0;
|
||||||
|
bp->addr = 0;
|
||||||
|
bp->flags = 0;
|
||||||
|
BUF_REMOVE(bp);
|
||||||
|
LRU_INSERT(bp);
|
||||||
|
}
|
212
newlib/libc/search/hash_func.c
Normal file
212
newlib/libc/search/hash_func.c
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1990, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Margo Seltzer.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the University of
|
||||||
|
* California, Berkeley and its contributors.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
static char sccsid[] = "@(#)hash_func.c 8.2 (Berkeley) 2/21/94";
|
||||||
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <db.h>
|
||||||
|
#include "hash.h"
|
||||||
|
#include "page.h"
|
||||||
|
#include "extern.h"
|
||||||
|
|
||||||
|
static __uint32_t hash1(const void *, size_t);
|
||||||
|
static __uint32_t hash2(const void *, size_t);
|
||||||
|
static __uint32_t hash3(const void *, size_t);
|
||||||
|
static __uint32_t hash4(const void *, size_t);
|
||||||
|
|
||||||
|
/* Global default hash function */
|
||||||
|
__uint32_t (*__default_hash)(const void *, size_t) = hash4;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HASH FUNCTIONS
|
||||||
|
*
|
||||||
|
* Assume that we've already split the bucket to which this key hashes,
|
||||||
|
* calculate that bucket, and check that in fact we did already split it.
|
||||||
|
*
|
||||||
|
* This came from ejb's hsearch.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PRIME1 37
|
||||||
|
#define PRIME2 1048583
|
||||||
|
|
||||||
|
static __uint32_t
|
||||||
|
hash1(keyarg, len)
|
||||||
|
const void *keyarg;
|
||||||
|
size_t len;
|
||||||
|
{
|
||||||
|
const u_char *key;
|
||||||
|
__uint32_t h;
|
||||||
|
|
||||||
|
/* Convert string to integer */
|
||||||
|
for (key = keyarg, h = 0; len--;)
|
||||||
|
h = h * PRIME1 ^ (*key++ - ' ');
|
||||||
|
h %= PRIME2;
|
||||||
|
return (h);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Phong's linear congruential hash
|
||||||
|
*/
|
||||||
|
#define dcharhash(h, c) ((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c))
|
||||||
|
|
||||||
|
static __uint32_t
|
||||||
|
hash2(keyarg, len)
|
||||||
|
const void *keyarg;
|
||||||
|
size_t len;
|
||||||
|
{
|
||||||
|
const u_char *e, *key;
|
||||||
|
__uint32_t h;
|
||||||
|
u_char c;
|
||||||
|
|
||||||
|
key = keyarg;
|
||||||
|
e = key + len;
|
||||||
|
for (h = 0; key != e;) {
|
||||||
|
c = *key++;
|
||||||
|
if (!c && key > e)
|
||||||
|
break;
|
||||||
|
dcharhash(h, c);
|
||||||
|
}
|
||||||
|
return (h);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is INCREDIBLY ugly, but fast. We break the string up into 8 byte
|
||||||
|
* units. On the first time through the loop we get the "leftover bytes"
|
||||||
|
* (strlen % 8). On every other iteration, we perform 8 HASHC's so we handle
|
||||||
|
* all 8 bytes. Essentially, this saves us 7 cmp & branch instructions. If
|
||||||
|
* this routine is heavily used enough, it's worth the ugly coding.
|
||||||
|
*
|
||||||
|
* OZ's original sdbm hash
|
||||||
|
*/
|
||||||
|
static __uint32_t
|
||||||
|
hash3(keyarg, len)
|
||||||
|
const void *keyarg;
|
||||||
|
size_t len;
|
||||||
|
{
|
||||||
|
const u_char *key;
|
||||||
|
size_t loop;
|
||||||
|
__uint32_t h;
|
||||||
|
|
||||||
|
#define HASHC h = *key++ + 65599 * h
|
||||||
|
|
||||||
|
h = 0;
|
||||||
|
key = keyarg;
|
||||||
|
if (len > 0) {
|
||||||
|
loop = (len + 8 - 1) >> 3;
|
||||||
|
|
||||||
|
switch (len & (8 - 1)) {
|
||||||
|
case 0:
|
||||||
|
do {
|
||||||
|
HASHC;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case 7:
|
||||||
|
HASHC;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case 6:
|
||||||
|
HASHC;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case 5:
|
||||||
|
HASHC;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case 4:
|
||||||
|
HASHC;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case 3:
|
||||||
|
HASHC;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case 2:
|
||||||
|
HASHC;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case 1:
|
||||||
|
HASHC;
|
||||||
|
} while (--loop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (h);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hash function from Chris Torek. */
|
||||||
|
static __uint32_t
|
||||||
|
hash4(keyarg, len)
|
||||||
|
const void *keyarg;
|
||||||
|
size_t len;
|
||||||
|
{
|
||||||
|
const u_char *key;
|
||||||
|
size_t loop;
|
||||||
|
__uint32_t h;
|
||||||
|
|
||||||
|
#define HASH4a h = (h << 5) - h + *key++;
|
||||||
|
#define HASH4b h = (h << 5) + h + *key++;
|
||||||
|
#define HASH4 HASH4b
|
||||||
|
|
||||||
|
h = 0;
|
||||||
|
key = keyarg;
|
||||||
|
if (len > 0) {
|
||||||
|
loop = (len + 8 - 1) >> 3;
|
||||||
|
|
||||||
|
switch (len & (8 - 1)) {
|
||||||
|
case 0:
|
||||||
|
do {
|
||||||
|
HASH4;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case 7:
|
||||||
|
HASH4;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case 6:
|
||||||
|
HASH4;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case 5:
|
||||||
|
HASH4;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case 4:
|
||||||
|
HASH4;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case 3:
|
||||||
|
HASH4;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case 2:
|
||||||
|
HASH4;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case 1:
|
||||||
|
HASH4;
|
||||||
|
} while (--loop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (h);
|
||||||
|
}
|
55
newlib/libc/search/hash_log2.c
Normal file
55
newlib/libc/search/hash_log2.c
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1990, 1993, 1994
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Margo Seltzer.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the University of
|
||||||
|
* California, Berkeley and its contributors.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
static char sccsid[] = "@(#)hash_log2.c 8.2 (Berkeley) 5/31/94";
|
||||||
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <db.h>
|
||||||
|
|
||||||
|
__uint32_t
|
||||||
|
__log2(num)
|
||||||
|
__uint32_t num;
|
||||||
|
{
|
||||||
|
__uint32_t i, limit;
|
||||||
|
|
||||||
|
limit = 1;
|
||||||
|
for (i = 0; limit < num; limit = limit << 1, i++);
|
||||||
|
return (i);
|
||||||
|
}
|
946
newlib/libc/search/hash_page.c
Normal file
946
newlib/libc/search/hash_page.c
Normal file
@ -0,0 +1,946 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1990, 1993, 1994
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Margo Seltzer.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the University of
|
||||||
|
* California, Berkeley and its contributors.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
static char sccsid[] = "@(#)hash_page.c 8.7 (Berkeley) 8/16/94";
|
||||||
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PACKAGE: hashing
|
||||||
|
*
|
||||||
|
* DESCRIPTION:
|
||||||
|
* Page manipulation for hashing package.
|
||||||
|
*
|
||||||
|
* ROUTINES:
|
||||||
|
*
|
||||||
|
* External
|
||||||
|
* __get_page
|
||||||
|
* __add_ovflpage
|
||||||
|
* Internal
|
||||||
|
* overflow_page
|
||||||
|
* open_temp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#ifdef DEBUG
|
||||||
|
#include <assert.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <db.h>
|
||||||
|
#include "hash.h"
|
||||||
|
#include "page.h"
|
||||||
|
#include "extern.h"
|
||||||
|
|
||||||
|
static __uint32_t *fetch_bitmap(HTAB *, int);
|
||||||
|
static __uint32_t first_free(__uint32_t);
|
||||||
|
static int open_temp(HTAB *);
|
||||||
|
static __uint16_t overflow_page(HTAB *);
|
||||||
|
static void putpair(char *, const DBT *, const DBT *);
|
||||||
|
static void squeeze_key(__uint16_t *, const DBT *, const DBT *);
|
||||||
|
static int ugly_split
|
||||||
|
(HTAB *, __uint32_t, BUFHEAD *, BUFHEAD *, int, int);
|
||||||
|
|
||||||
|
#define PAGE_INIT(P) { \
|
||||||
|
((__uint16_t *)(P))[0] = 0; \
|
||||||
|
((__uint16_t *)(P))[1] = hashp->BSIZE - 3 * sizeof(__uint16_t); \
|
||||||
|
((__uint16_t *)(P))[2] = hashp->BSIZE; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is called AFTER we have verified that there is room on the page for
|
||||||
|
* the pair (PAIRFITS has returned true) so we go right ahead and start moving
|
||||||
|
* stuff on.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
putpair(p, key, val)
|
||||||
|
char *p;
|
||||||
|
const DBT *key, *val;
|
||||||
|
{
|
||||||
|
__uint16_t *bp, n, off;
|
||||||
|
|
||||||
|
bp = (__uint16_t *)p;
|
||||||
|
|
||||||
|
/* Enter the key first. */
|
||||||
|
n = bp[0];
|
||||||
|
|
||||||
|
off = OFFSET(bp) - key->size;
|
||||||
|
memmove(p + off, key->data, key->size);
|
||||||
|
bp[++n] = off;
|
||||||
|
|
||||||
|
/* Now the data. */
|
||||||
|
off -= val->size;
|
||||||
|
memmove(p + off, val->data, val->size);
|
||||||
|
bp[++n] = off;
|
||||||
|
|
||||||
|
/* Adjust page info. */
|
||||||
|
bp[0] = n;
|
||||||
|
bp[n + 1] = off - ((n + 3) * sizeof(__uint16_t));
|
||||||
|
bp[n + 2] = off;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns:
|
||||||
|
* 0 OK
|
||||||
|
* -1 error
|
||||||
|
*/
|
||||||
|
extern int
|
||||||
|
__delpair(hashp, bufp, ndx)
|
||||||
|
HTAB *hashp;
|
||||||
|
BUFHEAD *bufp;
|
||||||
|
int ndx;
|
||||||
|
{
|
||||||
|
__uint16_t *bp, newoff;
|
||||||
|
int n;
|
||||||
|
__uint16_t pairlen;
|
||||||
|
|
||||||
|
bp = (__uint16_t *)bufp->page;
|
||||||
|
n = bp[0];
|
||||||
|
|
||||||
|
if (bp[ndx + 1] < REAL_KEY)
|
||||||
|
return (__big_delete(hashp, bufp));
|
||||||
|
if (ndx != 1)
|
||||||
|
newoff = bp[ndx - 1];
|
||||||
|
else
|
||||||
|
newoff = hashp->BSIZE;
|
||||||
|
pairlen = newoff - bp[ndx + 1];
|
||||||
|
|
||||||
|
if (ndx != (n - 1)) {
|
||||||
|
/* Hard Case -- need to shuffle keys */
|
||||||
|
int i;
|
||||||
|
char *src = bufp->page + (int)OFFSET(bp);
|
||||||
|
char *dst = src + (int)pairlen;
|
||||||
|
memmove(dst, src, bp[ndx + 1] - OFFSET(bp));
|
||||||
|
|
||||||
|
/* Now adjust the pointers */
|
||||||
|
for (i = ndx + 2; i <= n; i += 2) {
|
||||||
|
if (bp[i + 1] == OVFLPAGE) {
|
||||||
|
bp[i - 2] = bp[i];
|
||||||
|
bp[i - 1] = bp[i + 1];
|
||||||
|
} else {
|
||||||
|
bp[i - 2] = bp[i] + pairlen;
|
||||||
|
bp[i - 1] = bp[i + 1] + pairlen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Finally adjust the page data */
|
||||||
|
bp[n] = OFFSET(bp) + pairlen;
|
||||||
|
bp[n - 1] = bp[n + 1] + pairlen + 2 * sizeof(__uint16_t);
|
||||||
|
bp[0] = n - 2;
|
||||||
|
hashp->NKEYS--;
|
||||||
|
|
||||||
|
bufp->flags |= BUF_MOD;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Returns:
|
||||||
|
* 0 ==> OK
|
||||||
|
* -1 ==> Error
|
||||||
|
*/
|
||||||
|
extern int
|
||||||
|
__split_page(hashp, obucket, nbucket)
|
||||||
|
HTAB *hashp;
|
||||||
|
__uint32_t obucket, nbucket;
|
||||||
|
{
|
||||||
|
BUFHEAD *new_bufp, *old_bufp;
|
||||||
|
__uint16_t *ino;
|
||||||
|
char *np;
|
||||||
|
DBT key, val;
|
||||||
|
int n, ndx, retval;
|
||||||
|
__uint16_t copyto, diff, off, moved;
|
||||||
|
char *op;
|
||||||
|
|
||||||
|
copyto = (__uint16_t)hashp->BSIZE;
|
||||||
|
off = (__uint16_t)hashp->BSIZE;
|
||||||
|
old_bufp = __get_buf(hashp, obucket, NULL, 0);
|
||||||
|
if (old_bufp == NULL)
|
||||||
|
return (-1);
|
||||||
|
new_bufp = __get_buf(hashp, nbucket, NULL, 0);
|
||||||
|
if (new_bufp == NULL)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
old_bufp->flags |= (BUF_MOD | BUF_PIN);
|
||||||
|
new_bufp->flags |= (BUF_MOD | BUF_PIN);
|
||||||
|
|
||||||
|
ino = (__uint16_t *)(op = old_bufp->page);
|
||||||
|
np = new_bufp->page;
|
||||||
|
|
||||||
|
moved = 0;
|
||||||
|
|
||||||
|
for (n = 1, ndx = 1; n < ino[0]; n += 2) {
|
||||||
|
if (ino[n + 1] < REAL_KEY) {
|
||||||
|
retval = ugly_split(hashp, obucket, old_bufp, new_bufp,
|
||||||
|
(int)copyto, (int)moved);
|
||||||
|
old_bufp->flags &= ~BUF_PIN;
|
||||||
|
new_bufp->flags &= ~BUF_PIN;
|
||||||
|
return (retval);
|
||||||
|
|
||||||
|
}
|
||||||
|
key.data = (u_char *)op + ino[n];
|
||||||
|
key.size = off - ino[n];
|
||||||
|
|
||||||
|
if (__call_hash(hashp, key.data, key.size) == obucket) {
|
||||||
|
/* Don't switch page */
|
||||||
|
diff = copyto - off;
|
||||||
|
if (diff) {
|
||||||
|
copyto = ino[n + 1] + diff;
|
||||||
|
memmove(op + copyto, op + ino[n + 1],
|
||||||
|
off - ino[n + 1]);
|
||||||
|
ino[ndx] = copyto + ino[n] - ino[n + 1];
|
||||||
|
ino[ndx + 1] = copyto;
|
||||||
|
} else
|
||||||
|
copyto = ino[n + 1];
|
||||||
|
ndx += 2;
|
||||||
|
} else {
|
||||||
|
/* Switch page */
|
||||||
|
val.data = (u_char *)op + ino[n + 1];
|
||||||
|
val.size = ino[n] - ino[n + 1];
|
||||||
|
putpair(np, &key, &val);
|
||||||
|
moved += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
off = ino[n + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now clean up the page */
|
||||||
|
ino[0] -= moved;
|
||||||
|
FREESPACE(ino) = copyto - sizeof(__uint16_t) * (ino[0] + 3);
|
||||||
|
OFFSET(ino) = copyto;
|
||||||
|
|
||||||
|
#ifdef DEBUG3
|
||||||
|
(void)fprintf(stderr, "split %d/%d\n",
|
||||||
|
((__uint16_t *)np)[0] / 2,
|
||||||
|
((__uint16_t *)op)[0] / 2);
|
||||||
|
#endif
|
||||||
|
/* unpin both pages */
|
||||||
|
old_bufp->flags &= ~BUF_PIN;
|
||||||
|
new_bufp->flags &= ~BUF_PIN;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called when we encounter an overflow or big key/data page during split
|
||||||
|
* handling. This is special cased since we have to begin checking whether
|
||||||
|
* the key/data pairs fit on their respective pages and because we may need
|
||||||
|
* overflow pages for both the old and new pages.
|
||||||
|
*
|
||||||
|
* The first page might be a page with regular key/data pairs in which case
|
||||||
|
* we have a regular overflow condition and just need to go on to the next
|
||||||
|
* page or it might be a big key/data pair in which case we need to fix the
|
||||||
|
* big key/data pair.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* 0 ==> success
|
||||||
|
* -1 ==> failure
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved)
|
||||||
|
HTAB *hashp;
|
||||||
|
__uint32_t obucket; /* Same as __split_page. */
|
||||||
|
BUFHEAD *old_bufp, *new_bufp;
|
||||||
|
int copyto; /* First byte on page which contains key/data values. */
|
||||||
|
int moved; /* Number of pairs moved to new page. */
|
||||||
|
{
|
||||||
|
BUFHEAD *bufp; /* Buffer header for ino */
|
||||||
|
__uint16_t *ino; /* Page keys come off of */
|
||||||
|
__uint16_t *np; /* New page */
|
||||||
|
__uint16_t *op; /* Page keys go on to if they aren't moving */
|
||||||
|
|
||||||
|
BUFHEAD *last_bfp; /* Last buf header OVFL needing to be freed */
|
||||||
|
DBT key, val;
|
||||||
|
SPLIT_RETURN ret;
|
||||||
|
__uint16_t n, off, ov_addr, scopyto;
|
||||||
|
char *cino; /* Character value of ino */
|
||||||
|
|
||||||
|
bufp = old_bufp;
|
||||||
|
ino = (__uint16_t *)old_bufp->page;
|
||||||
|
np = (__uint16_t *)new_bufp->page;
|
||||||
|
op = (__uint16_t *)old_bufp->page;
|
||||||
|
last_bfp = NULL;
|
||||||
|
scopyto = (__uint16_t)copyto; /* ANSI */
|
||||||
|
|
||||||
|
n = ino[0] - 1;
|
||||||
|
while (n < ino[0]) {
|
||||||
|
if (ino[2] < REAL_KEY && ino[2] != OVFLPAGE) {
|
||||||
|
if (__big_split(hashp, old_bufp,
|
||||||
|
new_bufp, bufp, bufp->addr, obucket, &ret))
|
||||||
|
return (-1);
|
||||||
|
old_bufp = ret.oldp;
|
||||||
|
if (!old_bufp)
|
||||||
|
return (-1);
|
||||||
|
op = (__uint16_t *)old_bufp->page;
|
||||||
|
new_bufp = ret.newp;
|
||||||
|
if (!new_bufp)
|
||||||
|
return (-1);
|
||||||
|
np = (__uint16_t *)new_bufp->page;
|
||||||
|
bufp = ret.nextp;
|
||||||
|
if (!bufp)
|
||||||
|
return (0);
|
||||||
|
cino = (char *)bufp->page;
|
||||||
|
ino = (__uint16_t *)cino;
|
||||||
|
last_bfp = ret.nextp;
|
||||||
|
} else if (ino[n + 1] == OVFLPAGE) {
|
||||||
|
ov_addr = ino[n];
|
||||||
|
/*
|
||||||
|
* Fix up the old page -- the extra 2 are the fields
|
||||||
|
* which contained the overflow information.
|
||||||
|
*/
|
||||||
|
ino[0] -= (moved + 2);
|
||||||
|
FREESPACE(ino) =
|
||||||
|
scopyto - sizeof(__uint16_t) * (ino[0] + 3);
|
||||||
|
OFFSET(ino) = scopyto;
|
||||||
|
|
||||||
|
bufp = __get_buf(hashp, ov_addr, bufp, 0);
|
||||||
|
if (!bufp)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
ino = (__uint16_t *)bufp->page;
|
||||||
|
n = 1;
|
||||||
|
scopyto = hashp->BSIZE;
|
||||||
|
moved = 0;
|
||||||
|
|
||||||
|
if (last_bfp)
|
||||||
|
__free_ovflpage(hashp, last_bfp);
|
||||||
|
last_bfp = bufp;
|
||||||
|
}
|
||||||
|
/* Move regular sized pairs of there are any */
|
||||||
|
off = hashp->BSIZE;
|
||||||
|
for (n = 1; (n < ino[0]) && (ino[n + 1] >= REAL_KEY); n += 2) {
|
||||||
|
cino = (char *)ino;
|
||||||
|
key.data = (u_char *)cino + ino[n];
|
||||||
|
key.size = off - ino[n];
|
||||||
|
val.data = (u_char *)cino + ino[n + 1];
|
||||||
|
val.size = ino[n] - ino[n + 1];
|
||||||
|
off = ino[n + 1];
|
||||||
|
|
||||||
|
if (__call_hash(hashp, key.data, key.size) == obucket) {
|
||||||
|
/* Keep on old page */
|
||||||
|
if (PAIRFITS(op, (&key), (&val)))
|
||||||
|
putpair((char *)op, &key, &val);
|
||||||
|
else {
|
||||||
|
old_bufp =
|
||||||
|
__add_ovflpage(hashp, old_bufp);
|
||||||
|
if (!old_bufp)
|
||||||
|
return (-1);
|
||||||
|
op = (__uint16_t *)old_bufp->page;
|
||||||
|
putpair((char *)op, &key, &val);
|
||||||
|
}
|
||||||
|
old_bufp->flags |= BUF_MOD;
|
||||||
|
} else {
|
||||||
|
/* Move to new page */
|
||||||
|
if (PAIRFITS(np, (&key), (&val)))
|
||||||
|
putpair((char *)np, &key, &val);
|
||||||
|
else {
|
||||||
|
new_bufp =
|
||||||
|
__add_ovflpage(hashp, new_bufp);
|
||||||
|
if (!new_bufp)
|
||||||
|
return (-1);
|
||||||
|
np = (__uint16_t *)new_bufp->page;
|
||||||
|
putpair((char *)np, &key, &val);
|
||||||
|
}
|
||||||
|
new_bufp->flags |= BUF_MOD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (last_bfp)
|
||||||
|
__free_ovflpage(hashp, last_bfp);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the given pair to the page
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* 0 ==> OK
|
||||||
|
* 1 ==> failure
|
||||||
|
*/
|
||||||
|
extern int
|
||||||
|
__addel(hashp, bufp, key, val)
|
||||||
|
HTAB *hashp;
|
||||||
|
BUFHEAD *bufp;
|
||||||
|
const DBT *key, *val;
|
||||||
|
{
|
||||||
|
__uint16_t *bp, *sop;
|
||||||
|
int do_expand;
|
||||||
|
|
||||||
|
bp = (__uint16_t *)bufp->page;
|
||||||
|
do_expand = 0;
|
||||||
|
while (bp[0] && (bp[2] < REAL_KEY || bp[bp[0]] < REAL_KEY))
|
||||||
|
/* Exception case */
|
||||||
|
if (bp[2] == FULL_KEY_DATA && bp[0] == 2)
|
||||||
|
/* This is the last page of a big key/data pair
|
||||||
|
and we need to add another page */
|
||||||
|
break;
|
||||||
|
else if (bp[2] < REAL_KEY && bp[bp[0]] != OVFLPAGE) {
|
||||||
|
bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
|
||||||
|
if (!bufp)
|
||||||
|
return (-1);
|
||||||
|
bp = (__uint16_t *)bufp->page;
|
||||||
|
} else
|
||||||
|
/* Try to squeeze key on this page */
|
||||||
|
if (FREESPACE(bp) > PAIRSIZE(key, val)) {
|
||||||
|
squeeze_key(bp, key, val);
|
||||||
|
return (0);
|
||||||
|
} else {
|
||||||
|
bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
|
||||||
|
if (!bufp)
|
||||||
|
return (-1);
|
||||||
|
bp = (__uint16_t *)bufp->page;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PAIRFITS(bp, key, val))
|
||||||
|
putpair(bufp->page, key, val);
|
||||||
|
else {
|
||||||
|
do_expand = 1;
|
||||||
|
bufp = __add_ovflpage(hashp, bufp);
|
||||||
|
if (!bufp)
|
||||||
|
return (-1);
|
||||||
|
sop = (__uint16_t *)bufp->page;
|
||||||
|
|
||||||
|
if (PAIRFITS(sop, key, val))
|
||||||
|
putpair((char *)sop, key, val);
|
||||||
|
else
|
||||||
|
if (__big_insert(hashp, bufp, key, val))
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
bufp->flags |= BUF_MOD;
|
||||||
|
/*
|
||||||
|
* If the average number of keys per bucket exceeds the fill factor,
|
||||||
|
* expand the table.
|
||||||
|
*/
|
||||||
|
hashp->NKEYS++;
|
||||||
|
if (do_expand ||
|
||||||
|
(hashp->NKEYS / (hashp->MAX_BUCKET + 1) > hashp->FFACTOR))
|
||||||
|
return (__expand_table(hashp));
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* pointer on success
|
||||||
|
* NULL on error
|
||||||
|
*/
|
||||||
|
extern BUFHEAD *
|
||||||
|
__add_ovflpage(hashp, bufp)
|
||||||
|
HTAB *hashp;
|
||||||
|
BUFHEAD *bufp;
|
||||||
|
{
|
||||||
|
__uint16_t *sp;
|
||||||
|
__uint16_t ndx, ovfl_num;
|
||||||
|
#ifdef DEBUG1
|
||||||
|
int tmp1, tmp2;
|
||||||
|
#endif
|
||||||
|
sp = (__uint16_t *)bufp->page;
|
||||||
|
|
||||||
|
/* Check if we are dynamically determining the fill factor */
|
||||||
|
if (hashp->FFACTOR == DEF_FFACTOR) {
|
||||||
|
hashp->FFACTOR = sp[0] >> 1;
|
||||||
|
if (hashp->FFACTOR < MIN_FFACTOR)
|
||||||
|
hashp->FFACTOR = MIN_FFACTOR;
|
||||||
|
}
|
||||||
|
bufp->flags |= BUF_MOD;
|
||||||
|
ovfl_num = overflow_page(hashp);
|
||||||
|
#ifdef DEBUG1
|
||||||
|
tmp1 = bufp->addr;
|
||||||
|
tmp2 = bufp->ovfl ? bufp->ovfl->addr : 0;
|
||||||
|
#endif
|
||||||
|
if (!ovfl_num || !(bufp->ovfl = __get_buf(hashp, ovfl_num, bufp, 1)))
|
||||||
|
return (NULL);
|
||||||
|
bufp->ovfl->flags |= BUF_MOD;
|
||||||
|
#ifdef DEBUG1
|
||||||
|
(void)fprintf(stderr, "ADDOVFLPAGE: %d->ovfl was %d is now %d\n",
|
||||||
|
tmp1, tmp2, bufp->ovfl->addr);
|
||||||
|
#endif
|
||||||
|
ndx = sp[0];
|
||||||
|
/*
|
||||||
|
* Since a pair is allocated on a page only if there's room to add
|
||||||
|
* an overflow page, we know that the OVFL information will fit on
|
||||||
|
* the page.
|
||||||
|
*/
|
||||||
|
sp[ndx + 4] = OFFSET(sp);
|
||||||
|
sp[ndx + 3] = FREESPACE(sp) - OVFLSIZE;
|
||||||
|
sp[ndx + 1] = ovfl_num;
|
||||||
|
sp[ndx + 2] = OVFLPAGE;
|
||||||
|
sp[0] = ndx + 2;
|
||||||
|
#ifdef HASH_STATISTICS
|
||||||
|
hash_overflows++;
|
||||||
|
#endif
|
||||||
|
return (bufp->ovfl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns:
|
||||||
|
* 0 indicates SUCCESS
|
||||||
|
* -1 indicates FAILURE
|
||||||
|
*/
|
||||||
|
extern int
|
||||||
|
__get_page(hashp, p, bucket, is_bucket, is_disk, is_bitmap)
|
||||||
|
HTAB *hashp;
|
||||||
|
char *p;
|
||||||
|
__uint32_t bucket;
|
||||||
|
int is_bucket, is_disk, is_bitmap;
|
||||||
|
{
|
||||||
|
int fd, page, size;
|
||||||
|
int rsize;
|
||||||
|
__uint16_t *bp;
|
||||||
|
|
||||||
|
fd = hashp->fp;
|
||||||
|
size = hashp->BSIZE;
|
||||||
|
|
||||||
|
if ((fd == -1) || !is_disk) {
|
||||||
|
PAGE_INIT(p);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if (is_bucket)
|
||||||
|
page = BUCKET_TO_PAGE(bucket);
|
||||||
|
else
|
||||||
|
page = OADDR_TO_PAGE(bucket);
|
||||||
|
if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) ||
|
||||||
|
((rsize = read(fd, p, size)) == -1))
|
||||||
|
return (-1);
|
||||||
|
bp = (__uint16_t *)p;
|
||||||
|
if (!rsize)
|
||||||
|
bp[0] = 0; /* We hit the EOF, so initialize a new page */
|
||||||
|
else
|
||||||
|
if (rsize != size) {
|
||||||
|
errno = EFTYPE;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (!is_bitmap && !bp[0]) {
|
||||||
|
PAGE_INIT(p);
|
||||||
|
} else
|
||||||
|
if (hashp->LORDER != BYTE_ORDER) {
|
||||||
|
int i, max;
|
||||||
|
|
||||||
|
if (is_bitmap) {
|
||||||
|
max = hashp->BSIZE >> 2; /* divide by 4 */
|
||||||
|
for (i = 0; i < max; i++)
|
||||||
|
M_32_SWAP(((int *)p)[i]);
|
||||||
|
} else {
|
||||||
|
M_16_SWAP(bp[0]);
|
||||||
|
max = bp[0] + 2;
|
||||||
|
for (i = 1; i <= max; i++)
|
||||||
|
M_16_SWAP(bp[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write page p to disk
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* 0 ==> OK
|
||||||
|
* -1 ==>failure
|
||||||
|
*/
|
||||||
|
extern int
|
||||||
|
__put_page(hashp, p, bucket, is_bucket, is_bitmap)
|
||||||
|
HTAB *hashp;
|
||||||
|
char *p;
|
||||||
|
__uint32_t bucket;
|
||||||
|
int is_bucket, is_bitmap;
|
||||||
|
{
|
||||||
|
int fd, page, size;
|
||||||
|
int wsize;
|
||||||
|
|
||||||
|
size = hashp->BSIZE;
|
||||||
|
if ((hashp->fp == -1) && open_temp(hashp))
|
||||||
|
return (-1);
|
||||||
|
fd = hashp->fp;
|
||||||
|
|
||||||
|
if (hashp->LORDER != BYTE_ORDER) {
|
||||||
|
int i;
|
||||||
|
int max;
|
||||||
|
|
||||||
|
if (is_bitmap) {
|
||||||
|
max = hashp->BSIZE >> 2; /* divide by 4 */
|
||||||
|
for (i = 0; i < max; i++)
|
||||||
|
M_32_SWAP(((int *)p)[i]);
|
||||||
|
} else {
|
||||||
|
max = ((__uint16_t *)p)[0] + 2;
|
||||||
|
for (i = 0; i <= max; i++)
|
||||||
|
M_16_SWAP(((__uint16_t *)p)[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_bucket)
|
||||||
|
page = BUCKET_TO_PAGE(bucket);
|
||||||
|
else
|
||||||
|
page = OADDR_TO_PAGE(bucket);
|
||||||
|
if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) ||
|
||||||
|
((wsize = write(fd, p, size)) == -1))
|
||||||
|
/* Errno is set */
|
||||||
|
return (-1);
|
||||||
|
if (wsize != size) {
|
||||||
|
errno = EFTYPE;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BYTE_MASK ((1 << INT_BYTE_SHIFT) -1)
|
||||||
|
/*
|
||||||
|
* Initialize a new bitmap page. Bitmap pages are left in memory
|
||||||
|
* once they are read in.
|
||||||
|
*/
|
||||||
|
extern int
|
||||||
|
__ibitmap(hashp, pnum, nbits, ndx)
|
||||||
|
HTAB *hashp;
|
||||||
|
int pnum, nbits, ndx;
|
||||||
|
{
|
||||||
|
__uint32_t *ip;
|
||||||
|
int clearbytes, clearints;
|
||||||
|
|
||||||
|
if ((ip = (__uint32_t *)malloc(hashp->BSIZE)) == NULL)
|
||||||
|
return (1);
|
||||||
|
hashp->nmaps++;
|
||||||
|
clearints = ((nbits - 1) >> INT_BYTE_SHIFT) + 1;
|
||||||
|
clearbytes = clearints << INT_TO_BYTE;
|
||||||
|
(void)memset((char *)ip, 0, clearbytes);
|
||||||
|
(void)memset(((char *)ip) + clearbytes, 0xFF,
|
||||||
|
hashp->BSIZE - clearbytes);
|
||||||
|
ip[clearints - 1] = ALL_SET << (nbits & BYTE_MASK);
|
||||||
|
SETBIT(ip, 0);
|
||||||
|
hashp->BITMAPS[ndx] = (__uint16_t)pnum;
|
||||||
|
hashp->mapp[ndx] = ip;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __uint32_t
|
||||||
|
first_free(map)
|
||||||
|
__uint32_t map;
|
||||||
|
{
|
||||||
|
__uint32_t i, mask;
|
||||||
|
|
||||||
|
mask = 0x1;
|
||||||
|
for (i = 0; i < BITS_PER_MAP; i++) {
|
||||||
|
if (!(mask & map))
|
||||||
|
return (i);
|
||||||
|
mask = mask << 1;
|
||||||
|
}
|
||||||
|
return (i);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __uint16_t
|
||||||
|
overflow_page(hashp)
|
||||||
|
HTAB *hashp;
|
||||||
|
{
|
||||||
|
__uint32_t *freep;
|
||||||
|
int max_free, offset, splitnum;
|
||||||
|
__uint16_t addr;
|
||||||
|
int bit, first_page, free_bit, free_page, i, in_use_bits, j;
|
||||||
|
#ifdef DEBUG2
|
||||||
|
int tmp1, tmp2;
|
||||||
|
#endif
|
||||||
|
splitnum = hashp->OVFL_POINT;
|
||||||
|
max_free = hashp->SPARES[splitnum];
|
||||||
|
|
||||||
|
free_page = (max_free - 1) >> (hashp->BSHIFT + BYTE_SHIFT);
|
||||||
|
free_bit = (max_free - 1) & ((hashp->BSIZE << BYTE_SHIFT) - 1);
|
||||||
|
|
||||||
|
/* Look through all the free maps to find the first free block */
|
||||||
|
first_page = hashp->LAST_FREED >>(hashp->BSHIFT + BYTE_SHIFT);
|
||||||
|
for ( i = first_page; i <= free_page; i++ ) {
|
||||||
|
if (!(freep = (__uint32_t *)hashp->mapp[i]) &&
|
||||||
|
!(freep = fetch_bitmap(hashp, i)))
|
||||||
|
return (0);
|
||||||
|
if (i == free_page)
|
||||||
|
in_use_bits = free_bit;
|
||||||
|
else
|
||||||
|
in_use_bits = (hashp->BSIZE << BYTE_SHIFT) - 1;
|
||||||
|
|
||||||
|
if (i == first_page) {
|
||||||
|
bit = hashp->LAST_FREED &
|
||||||
|
((hashp->BSIZE << BYTE_SHIFT) - 1);
|
||||||
|
j = bit / BITS_PER_MAP;
|
||||||
|
bit = bit & ~(BITS_PER_MAP - 1);
|
||||||
|
} else {
|
||||||
|
bit = 0;
|
||||||
|
j = 0;
|
||||||
|
}
|
||||||
|
for (; bit <= in_use_bits; j++, bit += BITS_PER_MAP)
|
||||||
|
if (freep[j] != ALL_SET)
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No Free Page Found */
|
||||||
|
hashp->LAST_FREED = hashp->SPARES[splitnum];
|
||||||
|
hashp->SPARES[splitnum]++;
|
||||||
|
offset = hashp->SPARES[splitnum] -
|
||||||
|
(splitnum ? hashp->SPARES[splitnum - 1] : 0);
|
||||||
|
|
||||||
|
#define OVMSG "HASH: Out of overflow pages. Increase page size\n"
|
||||||
|
if (offset > SPLITMASK) {
|
||||||
|
if (++splitnum >= NCACHED) {
|
||||||
|
(void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
hashp->OVFL_POINT = splitnum;
|
||||||
|
hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1];
|
||||||
|
hashp->SPARES[splitnum-1]--;
|
||||||
|
offset = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we need to allocate a new bitmap page */
|
||||||
|
if (free_bit == (hashp->BSIZE << BYTE_SHIFT) - 1) {
|
||||||
|
free_page++;
|
||||||
|
if (free_page >= NCACHED) {
|
||||||
|
(void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This is tricky. The 1 indicates that you want the new page
|
||||||
|
* allocated with 1 clear bit. Actually, you are going to
|
||||||
|
* allocate 2 pages from this map. The first is going to be
|
||||||
|
* the map page, the second is the overflow page we were
|
||||||
|
* looking for. The init_bitmap routine automatically, sets
|
||||||
|
* the first bit of itself to indicate that the bitmap itself
|
||||||
|
* is in use. We would explicitly set the second bit, but
|
||||||
|
* don't have to if we tell init_bitmap not to leave it clear
|
||||||
|
* in the first place.
|
||||||
|
*/
|
||||||
|
if (__ibitmap(hashp,
|
||||||
|
(int)OADDR_OF(splitnum, offset), 1, free_page))
|
||||||
|
return (0);
|
||||||
|
hashp->SPARES[splitnum]++;
|
||||||
|
#ifdef DEBUG2
|
||||||
|
free_bit = 2;
|
||||||
|
#endif
|
||||||
|
offset++;
|
||||||
|
if (offset > SPLITMASK) {
|
||||||
|
if (++splitnum >= NCACHED) {
|
||||||
|
(void)write(STDERR_FILENO, OVMSG,
|
||||||
|
sizeof(OVMSG) - 1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
hashp->OVFL_POINT = splitnum;
|
||||||
|
hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1];
|
||||||
|
hashp->SPARES[splitnum-1]--;
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Free_bit addresses the last used bit. Bump it to address
|
||||||
|
* the first available bit.
|
||||||
|
*/
|
||||||
|
free_bit++;
|
||||||
|
SETBIT(freep, free_bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate address of the new overflow page */
|
||||||
|
addr = OADDR_OF(splitnum, offset);
|
||||||
|
#ifdef DEBUG2
|
||||||
|
(void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
|
||||||
|
addr, free_bit, free_page);
|
||||||
|
#endif
|
||||||
|
return (addr);
|
||||||
|
|
||||||
|
found:
|
||||||
|
bit = bit + first_free(freep[j]);
|
||||||
|
SETBIT(freep, bit);
|
||||||
|
#ifdef DEBUG2
|
||||||
|
tmp1 = bit;
|
||||||
|
tmp2 = i;
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Bits are addressed starting with 0, but overflow pages are addressed
|
||||||
|
* beginning at 1. Bit is a bit addressnumber, so we need to increment
|
||||||
|
* it to convert it to a page number.
|
||||||
|
*/
|
||||||
|
bit = 1 + bit + (i * (hashp->BSIZE << BYTE_SHIFT));
|
||||||
|
if (bit >= hashp->LAST_FREED)
|
||||||
|
hashp->LAST_FREED = bit - 1;
|
||||||
|
|
||||||
|
/* Calculate the split number for this page */
|
||||||
|
for (i = 0; (i < splitnum) && (bit > hashp->SPARES[i]); i++);
|
||||||
|
offset = (i ? bit - hashp->SPARES[i - 1] : bit);
|
||||||
|
if (offset >= SPLITMASK)
|
||||||
|
return (0); /* Out of overflow pages */
|
||||||
|
addr = OADDR_OF(i, offset);
|
||||||
|
#ifdef DEBUG2
|
||||||
|
(void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
|
||||||
|
addr, tmp1, tmp2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Allocate and return the overflow page */
|
||||||
|
return (addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mark this overflow page as free.
|
||||||
|
*/
|
||||||
|
extern void
|
||||||
|
__free_ovflpage(hashp, obufp)
|
||||||
|
HTAB *hashp;
|
||||||
|
BUFHEAD *obufp;
|
||||||
|
{
|
||||||
|
__uint16_t addr;
|
||||||
|
__uint32_t *freep;
|
||||||
|
int bit_address, free_page, free_bit;
|
||||||
|
__uint16_t ndx;
|
||||||
|
|
||||||
|
addr = obufp->addr;
|
||||||
|
#ifdef DEBUG1
|
||||||
|
(void)fprintf(stderr, "Freeing %d\n", addr);
|
||||||
|
#endif
|
||||||
|
ndx = (((__uint16_t)addr) >> SPLITSHIFT);
|
||||||
|
bit_address =
|
||||||
|
(ndx ? hashp->SPARES[ndx - 1] : 0) + (addr & SPLITMASK) - 1;
|
||||||
|
if (bit_address < hashp->LAST_FREED)
|
||||||
|
hashp->LAST_FREED = bit_address;
|
||||||
|
free_page = (bit_address >> (hashp->BSHIFT + BYTE_SHIFT));
|
||||||
|
free_bit = bit_address & ((hashp->BSIZE << BYTE_SHIFT) - 1);
|
||||||
|
|
||||||
|
if (!(freep = hashp->mapp[free_page]))
|
||||||
|
freep = fetch_bitmap(hashp, free_page);
|
||||||
|
#ifdef DEBUG
|
||||||
|
/*
|
||||||
|
* This had better never happen. It means we tried to read a bitmap
|
||||||
|
* that has already had overflow pages allocated off it, and we
|
||||||
|
* failed to read it from the file.
|
||||||
|
*/
|
||||||
|
if (!freep)
|
||||||
|
assert(0);
|
||||||
|
#endif
|
||||||
|
CLRBIT(freep, free_bit);
|
||||||
|
#ifdef DEBUG2
|
||||||
|
(void)fprintf(stderr, "FREE_OVFLPAGE: ADDR: %d BIT: %d PAGE %d\n",
|
||||||
|
obufp->addr, free_bit, free_page);
|
||||||
|
#endif
|
||||||
|
__reclaim_buf(hashp, obufp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns:
|
||||||
|
* 0 success
|
||||||
|
* -1 failure
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
open_temp(hashp)
|
||||||
|
HTAB *hashp;
|
||||||
|
{
|
||||||
|
sigset_t set, oset;
|
||||||
|
static char namestr[] = "_hashXXXXXX";
|
||||||
|
|
||||||
|
/* Block signals; make sure file goes away at process exit. */
|
||||||
|
(void)sigfillset(&set);
|
||||||
|
(void)sigprocmask(SIG_BLOCK, &set, &oset);
|
||||||
|
if ((hashp->fp = mkstemp(namestr)) != -1) {
|
||||||
|
(void)unlink(namestr);
|
||||||
|
(void)fcntl(hashp->fp, F_SETFD, 1);
|
||||||
|
}
|
||||||
|
(void)sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL);
|
||||||
|
return (hashp->fp != -1 ? 0 : -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We have to know that the key will fit, but the last entry on the page is
|
||||||
|
* an overflow pair, so we need to shift things.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
squeeze_key(sp, key, val)
|
||||||
|
__uint16_t *sp;
|
||||||
|
const DBT *key, *val;
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
__uint16_t free_space, n, off, pageno;
|
||||||
|
|
||||||
|
p = (char *)sp;
|
||||||
|
n = sp[0];
|
||||||
|
free_space = FREESPACE(sp);
|
||||||
|
off = OFFSET(sp);
|
||||||
|
|
||||||
|
pageno = sp[n - 1];
|
||||||
|
off -= key->size;
|
||||||
|
sp[n - 1] = off;
|
||||||
|
memmove(p + off, key->data, key->size);
|
||||||
|
off -= val->size;
|
||||||
|
sp[n] = off;
|
||||||
|
memmove(p + off, val->data, val->size);
|
||||||
|
sp[0] = n + 2;
|
||||||
|
sp[n + 1] = pageno;
|
||||||
|
sp[n + 2] = OVFLPAGE;
|
||||||
|
FREESPACE(sp) = free_space - PAIRSIZE(key, val);
|
||||||
|
OFFSET(sp) = off;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __uint32_t *
|
||||||
|
fetch_bitmap(hashp, ndx)
|
||||||
|
HTAB *hashp;
|
||||||
|
int ndx;
|
||||||
|
{
|
||||||
|
if (ndx >= hashp->nmaps)
|
||||||
|
return (NULL);
|
||||||
|
if ((hashp->mapp[ndx] = (__uint32_t *)malloc(hashp->BSIZE)) == NULL)
|
||||||
|
return (NULL);
|
||||||
|
if (__get_page(hashp,
|
||||||
|
(char *)hashp->mapp[ndx], hashp->BITMAPS[ndx], 0, 1, 1)) {
|
||||||
|
free(hashp->mapp[ndx]);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
return (hashp->mapp[ndx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG4
|
||||||
|
int
|
||||||
|
print_chain(addr)
|
||||||
|
int addr;
|
||||||
|
{
|
||||||
|
BUFHEAD *bufp;
|
||||||
|
short *bp, oaddr;
|
||||||
|
|
||||||
|
(void)fprintf(stderr, "%d ", addr);
|
||||||
|
bufp = __get_buf(hashp, addr, NULL, 0);
|
||||||
|
bp = (short *)bufp->page;
|
||||||
|
while (bp[0] && ((bp[bp[0]] == OVFLPAGE) ||
|
||||||
|
((bp[0] > 2) && bp[2] < REAL_KEY))) {
|
||||||
|
oaddr = bp[bp[0] - 1];
|
||||||
|
(void)fprintf(stderr, "%d ", (int)oaddr);
|
||||||
|
bufp = __get_buf(hashp, (int)oaddr, bufp, 0);
|
||||||
|
bp = (short *)bufp->page;
|
||||||
|
}
|
||||||
|
(void)fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
#endif
|
206
newlib/libc/search/hcreate.3
Normal file
206
newlib/libc/search/hcreate.3
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
.\" $FreeBSD: src/lib/libc/stdlib/hcreate.3,v 1.2 2001/07/09 15:54:36 ru Exp $
|
||||||
|
.\"
|
||||||
|
.Dd May 8, 2001
|
||||||
|
.Os
|
||||||
|
.Dt HCREATE 3
|
||||||
|
.Sh NAME
|
||||||
|
.Nm hcreate , hdestroy , hsearch
|
||||||
|
.Nd manage hash search table
|
||||||
|
.Sh LIBRARY
|
||||||
|
.Lb libc
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In search.h
|
||||||
|
.Ft int
|
||||||
|
.Fn hcreate "size_t nel"
|
||||||
|
.Ft void
|
||||||
|
.Fn hdestroy void
|
||||||
|
.Ft ENTRY *
|
||||||
|
.Fn hsearch "ENTRY item" "ACTION action"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Fn hcreate ,
|
||||||
|
.Fn hdestroy ,
|
||||||
|
and
|
||||||
|
.Fn hsearch
|
||||||
|
functions manage hash search tables.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn hcreate
|
||||||
|
function allocates sufficient space for the table, and the application should
|
||||||
|
ensure it is called before
|
||||||
|
.Fn hsearch
|
||||||
|
is used.
|
||||||
|
The
|
||||||
|
.Fa nel
|
||||||
|
argument is an estimate of the maximum
|
||||||
|
number of entries that the table should contain.
|
||||||
|
This number may be adjusted upward by the
|
||||||
|
algorithm in order to obtain certain mathematically favorable circumstances.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn hdestroy
|
||||||
|
function disposes of the search table, and may be followed by another call to
|
||||||
|
.Fn hcreate .
|
||||||
|
After the call to
|
||||||
|
.Fn hdestroy ,
|
||||||
|
the data can no longer be considered accessible.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn hsearch
|
||||||
|
function is a hash-table search routine.
|
||||||
|
It returns a pointer into a hash table
|
||||||
|
indicating the location at which an entry can be found.
|
||||||
|
The
|
||||||
|
.Fa item
|
||||||
|
argument is a structure of type
|
||||||
|
.Vt ENTRY
|
||||||
|
(defined in the
|
||||||
|
.Aq Pa search.h
|
||||||
|
header) containing two pointers:
|
||||||
|
.Fa item.key
|
||||||
|
points to the comparison key (a
|
||||||
|
.Vt "char *" ) ,
|
||||||
|
and
|
||||||
|
.Fa item.data
|
||||||
|
(a
|
||||||
|
.Vt "void *" )
|
||||||
|
points to any other data to be associated with
|
||||||
|
that key.
|
||||||
|
The comparison function used by
|
||||||
|
.Fn hsearch
|
||||||
|
is
|
||||||
|
.Xr strcmp 3 .
|
||||||
|
The
|
||||||
|
.Fa action
|
||||||
|
argument is a
|
||||||
|
member of an enumeration type
|
||||||
|
.Vt ACTION
|
||||||
|
indicating the disposition of the entry if it cannot be
|
||||||
|
found in the table.
|
||||||
|
.Dv ENTER
|
||||||
|
indicates that the
|
||||||
|
.Fa item
|
||||||
|
should be inserted in the table at an
|
||||||
|
appropriate point.
|
||||||
|
.Dv FIND
|
||||||
|
indicates that no entry should be made.
|
||||||
|
Unsuccessful resolution is
|
||||||
|
indicated by the return of a
|
||||||
|
.Dv NULL
|
||||||
|
pointer.
|
||||||
|
.Sh RETURN VALUES
|
||||||
|
The
|
||||||
|
.Fn hcreate
|
||||||
|
function returns 0 if it cannot allocate sufficient space for the table;
|
||||||
|
otherwise, it returns non-zero.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn hdestroy
|
||||||
|
function does not return a value.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn hsearch
|
||||||
|
function returns a
|
||||||
|
.Dv NULL
|
||||||
|
pointer if either the
|
||||||
|
.Fa action
|
||||||
|
is
|
||||||
|
.Dv FIND
|
||||||
|
and the
|
||||||
|
.Fa item
|
||||||
|
could not be found or the
|
||||||
|
.Fa action
|
||||||
|
is
|
||||||
|
.Dv ENTER
|
||||||
|
and the table is full.
|
||||||
|
.Sh ERRORS
|
||||||
|
The
|
||||||
|
.Fn hcreate
|
||||||
|
and
|
||||||
|
.Fn hsearch
|
||||||
|
functions may fail if:
|
||||||
|
.Bl -tag -width Er
|
||||||
|
.It Bq Er ENOMEM
|
||||||
|
Insufficient storage space is available.
|
||||||
|
.El
|
||||||
|
.Sh EXAMPLES
|
||||||
|
The following example reads in strings followed by two numbers
|
||||||
|
and stores them in a hash table, discarding duplicates.
|
||||||
|
It then reads in strings and finds the matching entry in the hash
|
||||||
|
table and prints it out.
|
||||||
|
.Bd -literal
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <search.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
struct info { /* This is the info stored in the table */
|
||||||
|
int age, room; /* other than the key. */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NUM_EMPL 5000 /* # of elements in search table. */
|
||||||
|
|
||||||
|
int
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
char string_space[NUM_EMPL*20]; /* Space to store strings. */
|
||||||
|
struct info info_space[NUM_EMPL]; /* Space to store employee info. */
|
||||||
|
char *str_ptr = string_space; /* Next space in string_space. */
|
||||||
|
struct info *info_ptr = info_space; /* Next space in info_space. */
|
||||||
|
ENTRY item;
|
||||||
|
ENTRY *found_item; /* Name to look for in table. */
|
||||||
|
char name_to_find[30];
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
/* Create table; no error checking is performed. */
|
||||||
|
(void) hcreate(NUM_EMPL);
|
||||||
|
|
||||||
|
while (scanf("%s%d%d", str_ptr, &info_ptr->age,
|
||||||
|
&info_ptr->room) != EOF && i++ < NUM_EMPL) {
|
||||||
|
/* Put information in structure, and structure in item. */
|
||||||
|
item.key = str_ptr;
|
||||||
|
item.data = info_ptr;
|
||||||
|
str_ptr += strlen(str_ptr) + 1;
|
||||||
|
info_ptr++;
|
||||||
|
/* Put item into table. */
|
||||||
|
(void) hsearch(item, ENTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Access table. */
|
||||||
|
item.key = name_to_find;
|
||||||
|
while (scanf("%s", item.key) != EOF) {
|
||||||
|
if ((found_item = hsearch(item, FIND)) != NULL) {
|
||||||
|
/* If item is in the table. */
|
||||||
|
(void)printf("found %s, age = %d, room = %d\en",
|
||||||
|
found_item->key,
|
||||||
|
((struct info *)found_item->data)->age,
|
||||||
|
((struct info *)found_item->data)->room);
|
||||||
|
} else
|
||||||
|
(void)printf("no such employee %s\en", name_to_find);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
.Ed
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr bsearch 3 ,
|
||||||
|
.Xr lsearch 3 ,
|
||||||
|
.Xr malloc 3 ,
|
||||||
|
.Xr strcmp 3 ,
|
||||||
|
.Xr tsearch 3
|
||||||
|
.Sh STANDARDS
|
||||||
|
The
|
||||||
|
.Fn hcreate ,
|
||||||
|
.Fn hdestroy ,
|
||||||
|
and
|
||||||
|
.Fn hsearch
|
||||||
|
functions conform to
|
||||||
|
.St -xpg4.2 .
|
||||||
|
.Sh HISTORY
|
||||||
|
The
|
||||||
|
.Fn hcreate ,
|
||||||
|
.Fn hdestroy ,
|
||||||
|
and
|
||||||
|
.Fn hsearch
|
||||||
|
functions first appeared in
|
||||||
|
.At V .
|
||||||
|
.Sh BUGS
|
||||||
|
The interface permits the use of only one hash table at a time.
|
85
newlib/libc/search/hcreate.c
Normal file
85
newlib/libc/search/hcreate.c
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/* $NetBSD: hcreate.c,v 1.2 2001/02/19 21:26:04 ross Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001 Christopher G. Demetriou
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed for the
|
||||||
|
* NetBSD Project. See http://www.netbsd.org/ for
|
||||||
|
* information about NetBSD.
|
||||||
|
* 4. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hcreate() / hsearch() / hdestroy()
|
||||||
|
*
|
||||||
|
* SysV/XPG4 hash table functions.
|
||||||
|
*
|
||||||
|
* Implementation done based on NetBSD manual page and Solaris manual page,
|
||||||
|
* plus my own personal experience about how they're supposed to work.
|
||||||
|
*
|
||||||
|
* I tried to look at Knuth (as cited by the Solaris manual page), but
|
||||||
|
* nobody had a copy in the office, so...
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#if 0
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
__RCSID("$NetBSD: hcreate.c,v 1.2 2001/02/19 21:26:04 ross Exp $");
|
||||||
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/queue.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <search.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static struct hsearch_data htab;
|
||||||
|
|
||||||
|
int
|
||||||
|
hcreate(size_t nel)
|
||||||
|
{
|
||||||
|
return hcreate_r (nel, &htab);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hdestroy(void)
|
||||||
|
{
|
||||||
|
hdestroy_r (&htab);
|
||||||
|
}
|
||||||
|
|
||||||
|
ENTRY *
|
||||||
|
hsearch(ENTRY item, ACTION action)
|
||||||
|
{
|
||||||
|
ENTRY *retval;
|
||||||
|
|
||||||
|
hsearch_r (item, action, &retval, &htab);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
193
newlib/libc/search/hcreate_r.c
Normal file
193
newlib/libc/search/hcreate_r.c
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
/* $NetBSD: hcreate.c,v 1.2 2001/02/19 21:26:04 ross Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001 Christopher G. Demetriou
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed for the
|
||||||
|
* NetBSD Project. See http://www.netbsd.org/ for
|
||||||
|
* information about NetBSD.
|
||||||
|
* 4. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hcreate() / hsearch() / hdestroy()
|
||||||
|
*
|
||||||
|
* SysV/XPG4 hash table functions.
|
||||||
|
*
|
||||||
|
* Implementation done based on NetBSD manual page and Solaris manual page,
|
||||||
|
* plus my own personal experience about how they're supposed to work.
|
||||||
|
*
|
||||||
|
* I tried to look at Knuth (as cited by the Solaris manual page), but
|
||||||
|
* nobody had a copy in the office, so...
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#if 0
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
__RCSID("$NetBSD: hcreate.c,v 1.2 2001/02/19 21:26:04 ross Exp $");
|
||||||
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/queue.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <search.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DO NOT MAKE THIS STRUCTURE LARGER THAN 32 BYTES (4 ptrs on 64-bit
|
||||||
|
* ptr machine) without adjusting MAX_BUCKETS_LG2 below.
|
||||||
|
*/
|
||||||
|
struct internal_entry {
|
||||||
|
SLIST_ENTRY(internal_entry) link;
|
||||||
|
ENTRY ent;
|
||||||
|
};
|
||||||
|
SLIST_HEAD(internal_head, internal_entry);
|
||||||
|
|
||||||
|
#define MIN_BUCKETS_LG2 4
|
||||||
|
#define MIN_BUCKETS (1 << MIN_BUCKETS_LG2)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* max * sizeof internal_entry must fit into size_t.
|
||||||
|
* assumes internal_entry is <= 32 (2^5) bytes.
|
||||||
|
*/
|
||||||
|
#define MAX_BUCKETS_LG2 (sizeof (size_t) * 8 - 1 - 5)
|
||||||
|
#define MAX_BUCKETS ((size_t)1 << MAX_BUCKETS_LG2)
|
||||||
|
|
||||||
|
/* Default hash function, from db/hash/hash_func.c */
|
||||||
|
extern __uint32_t (*__default_hash)(const void *, size_t);
|
||||||
|
|
||||||
|
int
|
||||||
|
hcreate_r(size_t nel, struct hsearch_data *htab)
|
||||||
|
{
|
||||||
|
size_t idx;
|
||||||
|
unsigned int p2;
|
||||||
|
|
||||||
|
/* Make sure this this isn't called when a table already exists. */
|
||||||
|
if (htab->htable != NULL) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If nel is too small, make it min sized. */
|
||||||
|
if (nel < MIN_BUCKETS)
|
||||||
|
nel = MIN_BUCKETS;
|
||||||
|
|
||||||
|
/* If it's too large, cap it. */
|
||||||
|
if (nel > MAX_BUCKETS)
|
||||||
|
nel = MAX_BUCKETS;
|
||||||
|
|
||||||
|
/* If it's is not a power of two in size, round up. */
|
||||||
|
if ((nel & (nel - 1)) != 0) {
|
||||||
|
for (p2 = 0; nel != 0; p2++)
|
||||||
|
nel >>= 1;
|
||||||
|
nel = 1 << p2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate the table. */
|
||||||
|
htab->htablesize = nel;
|
||||||
|
htab->htable = malloc(htab->htablesize * sizeof htab->htable[0]);
|
||||||
|
if (htab->htable == NULL) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize it. */
|
||||||
|
for (idx = 0; idx < htab->htablesize; idx++)
|
||||||
|
SLIST_INIT(&(htab->htable[idx]));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hdestroy_r(struct hsearch_data *htab)
|
||||||
|
{
|
||||||
|
struct internal_entry *ie;
|
||||||
|
size_t idx;
|
||||||
|
|
||||||
|
if (htab->htable == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
for (idx = 0; idx < htab->htablesize; idx++) {
|
||||||
|
while (!SLIST_EMPTY(&(htab->htable[idx]))) {
|
||||||
|
ie = SLIST_FIRST(&(htab->htable[idx]));
|
||||||
|
SLIST_REMOVE_HEAD(&(htab->htable[idx]), link);
|
||||||
|
free(ie->ent.key);
|
||||||
|
free(ie);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
free(htab->htable);
|
||||||
|
htab->htable = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
hsearch_r(ENTRY item, ACTION action, ENTRY **retval, struct hsearch_data *htab)
|
||||||
|
{
|
||||||
|
struct internal_head *head;
|
||||||
|
struct internal_entry *ie;
|
||||||
|
__uint32_t hashval;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
len = strlen(item.key);
|
||||||
|
hashval = (*__default_hash)(item.key, len);
|
||||||
|
|
||||||
|
head = &(htab->htable[hashval & (htab->htablesize - 1)]);
|
||||||
|
ie = SLIST_FIRST(head);
|
||||||
|
while (ie != NULL) {
|
||||||
|
if (strcmp(ie->ent.key, item.key) == 0)
|
||||||
|
break;
|
||||||
|
ie = SLIST_NEXT(ie, link);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ie != NULL)
|
||||||
|
{
|
||||||
|
*retval = &ie->ent;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (action == FIND)
|
||||||
|
{
|
||||||
|
*retval = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ie = malloc(sizeof *ie);
|
||||||
|
if (ie == NULL)
|
||||||
|
{
|
||||||
|
*retval = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ie->ent.key = item.key;
|
||||||
|
ie->ent.data = item.data;
|
||||||
|
|
||||||
|
SLIST_INSERT_HEAD(head, ie, link);
|
||||||
|
*retval = &ie->ent;
|
||||||
|
return 1;
|
||||||
|
}
|
232
newlib/libc/search/ndbm.c
Normal file
232
newlib/libc/search/ndbm.c
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1990, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Margo Seltzer.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the University of
|
||||||
|
* California, Berkeley and its contributors.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/unistd.h>
|
||||||
|
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
static char sccsid[] = "@(#)ndbm.c 8.4 (Berkeley) 7/21/94";
|
||||||
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This package provides a dbm compatible interface to the new hashing
|
||||||
|
* package described in db(3).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <ndbm.h>
|
||||||
|
#include "hash.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns:
|
||||||
|
* *DBM on success
|
||||||
|
* NULL on failure
|
||||||
|
*/
|
||||||
|
extern DBM *
|
||||||
|
dbm_open(file, flags, mode)
|
||||||
|
const char *file;
|
||||||
|
int flags, mode;
|
||||||
|
{
|
||||||
|
HASHINFO info;
|
||||||
|
char path[MAXPATHLEN];
|
||||||
|
|
||||||
|
info.bsize = 4096;
|
||||||
|
info.ffactor = 40;
|
||||||
|
info.nelem = 1;
|
||||||
|
info.cachesize = 0;
|
||||||
|
info.hash = NULL;
|
||||||
|
info.lorder = 0;
|
||||||
|
|
||||||
|
if( strlen(file) >= sizeof(path) - strlen(DBM_SUFFIX)) {
|
||||||
|
errno = ENAMETOOLONG;
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
(void)strcpy(path, file);
|
||||||
|
(void)strcat(path, DBM_SUFFIX);
|
||||||
|
return ((DBM *)__hash_open(path, flags, mode, &info, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void
|
||||||
|
dbm_close(db)
|
||||||
|
DBM *db;
|
||||||
|
{
|
||||||
|
(void)(db->close)(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns:
|
||||||
|
* DATUM on success
|
||||||
|
* NULL on failure
|
||||||
|
*/
|
||||||
|
extern datum
|
||||||
|
dbm_fetch(db, key)
|
||||||
|
DBM *db;
|
||||||
|
datum key;
|
||||||
|
{
|
||||||
|
datum retdata;
|
||||||
|
int status;
|
||||||
|
DBT dbtkey, dbtretdata;
|
||||||
|
|
||||||
|
dbtkey.data = key.dptr;
|
||||||
|
dbtkey.size = key.dsize;
|
||||||
|
status = (db->get)(db, &dbtkey, &dbtretdata, 0);
|
||||||
|
if (status) {
|
||||||
|
dbtretdata.data = NULL;
|
||||||
|
dbtretdata.size = 0;
|
||||||
|
}
|
||||||
|
retdata.dptr = dbtretdata.data;
|
||||||
|
retdata.dsize = dbtretdata.size;
|
||||||
|
return (retdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns:
|
||||||
|
* DATUM on success
|
||||||
|
* NULL on failure
|
||||||
|
*/
|
||||||
|
extern datum
|
||||||
|
dbm_firstkey(db)
|
||||||
|
DBM *db;
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
datum retkey;
|
||||||
|
DBT dbtretkey, dbtretdata;
|
||||||
|
|
||||||
|
status = (db->seq)(db, &dbtretkey, &dbtretdata, R_FIRST);
|
||||||
|
if (status)
|
||||||
|
dbtretkey.data = NULL;
|
||||||
|
retkey.dptr = dbtretkey.data;
|
||||||
|
retkey.dsize = dbtretkey.size;
|
||||||
|
return (retkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns:
|
||||||
|
* DATUM on success
|
||||||
|
* NULL on failure
|
||||||
|
*/
|
||||||
|
extern datum
|
||||||
|
dbm_nextkey(db)
|
||||||
|
DBM *db;
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
datum retkey;
|
||||||
|
DBT dbtretkey, dbtretdata;
|
||||||
|
|
||||||
|
status = (db->seq)(db, &dbtretkey, &dbtretdata, R_NEXT);
|
||||||
|
if (status)
|
||||||
|
dbtretkey.data = NULL;
|
||||||
|
retkey.dptr = dbtretkey.data;
|
||||||
|
retkey.dsize = dbtretkey.size;
|
||||||
|
return (retkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns:
|
||||||
|
* 0 on success
|
||||||
|
* <0 failure
|
||||||
|
*/
|
||||||
|
extern int
|
||||||
|
dbm_delete(db, key)
|
||||||
|
DBM *db;
|
||||||
|
datum key;
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
DBT dbtkey;
|
||||||
|
|
||||||
|
dbtkey.data = key.dptr;
|
||||||
|
dbtkey.size = key.dsize;
|
||||||
|
status = (db->del)(db, &dbtkey, 0);
|
||||||
|
if (status)
|
||||||
|
return (-1);
|
||||||
|
else
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns:
|
||||||
|
* 0 on success
|
||||||
|
* <0 failure
|
||||||
|
* 1 if DBM_INSERT and entry exists
|
||||||
|
*/
|
||||||
|
extern int
|
||||||
|
dbm_store(db, key, data, flags)
|
||||||
|
DBM *db;
|
||||||
|
datum key, data;
|
||||||
|
int flags;
|
||||||
|
{
|
||||||
|
DBT dbtkey, dbtdata;
|
||||||
|
|
||||||
|
dbtkey.data = key.dptr;
|
||||||
|
dbtkey.size = key.dsize;
|
||||||
|
dbtdata.data = data.dptr;
|
||||||
|
dbtdata.size = data.dsize;
|
||||||
|
return ((db->put)(db, &dbtkey, &dbtdata,
|
||||||
|
(flags == DBM_INSERT) ? R_NOOVERWRITE : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
extern int
|
||||||
|
dbm_error(db)
|
||||||
|
DBM *db;
|
||||||
|
{
|
||||||
|
HTAB *hp;
|
||||||
|
|
||||||
|
hp = (HTAB *)db->internal;
|
||||||
|
return (hp->error);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern int
|
||||||
|
dbm_clearerr(db)
|
||||||
|
DBM *db;
|
||||||
|
{
|
||||||
|
HTAB *hp;
|
||||||
|
|
||||||
|
hp = (HTAB *)db->internal;
|
||||||
|
hp->error = 0;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern int
|
||||||
|
dbm_dirfno(db)
|
||||||
|
DBM *db;
|
||||||
|
{
|
||||||
|
return(((HTAB *)db->internal)->fp);
|
||||||
|
}
|
93
newlib/libc/search/page.h
Normal file
93
newlib/libc/search/page.h
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1990, 1993, 1994
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Margo Seltzer.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the University of
|
||||||
|
* California, Berkeley and its contributors.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)page.h 8.2 (Berkeley) 5/31/94
|
||||||
|
* $FreeBSD: src/lib/libc/db/hash/page.h,v 1.2 2002/03/22 23:41:40 obrien Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Definitions for hashing page file format.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* routines dealing with a data page
|
||||||
|
*
|
||||||
|
* page format:
|
||||||
|
* +------------------------------+
|
||||||
|
* p | n | keyoff | datoff | keyoff |
|
||||||
|
* +------------+--------+--------+
|
||||||
|
* | datoff | free | ptr | --> |
|
||||||
|
* +--------+---------------------+
|
||||||
|
* | F R E E A R E A |
|
||||||
|
* +--------------+---------------+
|
||||||
|
* | <---- - - - | data |
|
||||||
|
* +--------+-----+----+----------+
|
||||||
|
* | key | data | key |
|
||||||
|
* +--------+----------+----------+
|
||||||
|
*
|
||||||
|
* Pointer to the free space is always: p[p[0] + 2]
|
||||||
|
* Amount of free space on the page is: p[p[0] + 1]
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* How many bytes required for this pair?
|
||||||
|
* 2 shorts in the table at the top of the page + room for the
|
||||||
|
* key and room for the data
|
||||||
|
*
|
||||||
|
* We prohibit entering a pair on a page unless there is also room to append
|
||||||
|
* an overflow page. The reason for this it that you can get in a situation
|
||||||
|
* where a single key/data pair fits on a page, but you can't append an
|
||||||
|
* overflow page and later you'd have to split the key/data and handle like
|
||||||
|
* a big pair.
|
||||||
|
* You might as well do this up front.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PAIRSIZE(K,D) (2*sizeof(__uint16_t) + (K)->size + (D)->size)
|
||||||
|
#define BIGOVERHEAD (4*sizeof(__uint16_t))
|
||||||
|
#define KEYSIZE(K) (4*sizeof(__uint16_t) + (K)->size);
|
||||||
|
#define OVFLSIZE (2*sizeof(__uint16_t))
|
||||||
|
#define FREESPACE(P) ((P)[(P)[0]+1])
|
||||||
|
#define OFFSET(P) ((P)[(P)[0]+2])
|
||||||
|
#define PAIRFITS(P,K,D) \
|
||||||
|
(((P)[2] >= REAL_KEY) && \
|
||||||
|
(PAIRSIZE((K),(D)) + OVFLSIZE) <= FREESPACE((P)))
|
||||||
|
#define PAGE_META(N) (((N)+3) * sizeof(__uint16_t))
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
BUFHEAD *newp;
|
||||||
|
BUFHEAD *oldp;
|
||||||
|
BUFHEAD *nextp;
|
||||||
|
__uint16_t next_addr;
|
||||||
|
} SPLIT_RETURN;
|
222
newlib/libc/search/qsort.c
Normal file
222
newlib/libc/search/qsort.c
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
/*
|
||||||
|
FUNCTION
|
||||||
|
<<qsort>>---sort an array
|
||||||
|
|
||||||
|
INDEX
|
||||||
|
qsort
|
||||||
|
|
||||||
|
ANSI_SYNOPSIS
|
||||||
|
#include <stdlib.h>
|
||||||
|
void qsort(void *<[base]>, size_t <[nmemb]>, size_t <[size]>,
|
||||||
|
int (*<[compar]>)(const void *, const void *) );
|
||||||
|
|
||||||
|
TRAD_SYNOPSIS
|
||||||
|
#include <stdlib.h>
|
||||||
|
qsort(<[base]>, <[nmemb]>, <[size]>, <[compar]> )
|
||||||
|
char *<[base]>;
|
||||||
|
size_t <[nmemb]>;
|
||||||
|
size_t <[size]>;
|
||||||
|
int (*<[compar]>)();
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
<<qsort>> sorts an array (beginning at <[base]>) of <[nmemb]> objects.
|
||||||
|
<[size]> describes the size of each element of the array.
|
||||||
|
|
||||||
|
You must supply a pointer to a comparison function, using the argument
|
||||||
|
shown as <[compar]>. (This permits sorting objects of unknown
|
||||||
|
properties.) Define the comparison function to accept two arguments,
|
||||||
|
each a pointer to an element of the array starting at <[base]>. The
|
||||||
|
result of <<(*<[compar]>)>> must be negative if the first argument is
|
||||||
|
less than the second, zero if the two arguments match, and positive if
|
||||||
|
the first argument is greater than the second (where ``less than'' and
|
||||||
|
``greater than'' refer to whatever arbitrary ordering is appropriate).
|
||||||
|
|
||||||
|
The array is sorted in place; that is, when <<qsort>> returns, the
|
||||||
|
array elements beginning at <[base]> have been reordered.
|
||||||
|
|
||||||
|
RETURNS
|
||||||
|
<<qsort>> does not return a result.
|
||||||
|
|
||||||
|
PORTABILITY
|
||||||
|
<<qsort>> is required by ANSI (without specifying the sorting algorithm).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the University of
|
||||||
|
* California, Berkeley and its contributors.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <_ansi.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifndef __GNUC__
|
||||||
|
#define inline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline char *med3 _PARAMS((char *, char *, char *, int (*)()));
|
||||||
|
static inline void swapfunc _PARAMS((char *, char *, int, int));
|
||||||
|
|
||||||
|
#define min(a, b) (a) < (b) ? a : b
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
|
||||||
|
*/
|
||||||
|
#define swapcode(TYPE, parmi, parmj, n) { \
|
||||||
|
long i = (n) / sizeof (TYPE); \
|
||||||
|
register TYPE *pi = (TYPE *) (parmi); \
|
||||||
|
register TYPE *pj = (TYPE *) (parmj); \
|
||||||
|
do { \
|
||||||
|
register TYPE t = *pi; \
|
||||||
|
*pi++ = *pj; \
|
||||||
|
*pj++ = t; \
|
||||||
|
} while (--i > 0); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
|
||||||
|
es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
_DEFUN(swapfunc, (a, b, n, swaptype),
|
||||||
|
char *a _AND
|
||||||
|
char *b _AND
|
||||||
|
int n _AND
|
||||||
|
int swaptype)
|
||||||
|
{
|
||||||
|
if(swaptype <= 1)
|
||||||
|
swapcode(long, a, b, n)
|
||||||
|
else
|
||||||
|
swapcode(char, a, b, n)
|
||||||
|
}
|
||||||
|
|
||||||
|
#define swap(a, b) \
|
||||||
|
if (swaptype == 0) { \
|
||||||
|
long t = *(long *)(a); \
|
||||||
|
*(long *)(a) = *(long *)(b); \
|
||||||
|
*(long *)(b) = t; \
|
||||||
|
} else \
|
||||||
|
swapfunc(a, b, es, swaptype)
|
||||||
|
|
||||||
|
#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
|
||||||
|
|
||||||
|
static inline char *
|
||||||
|
_DEFUN(med3, (a, b, c, cmp),
|
||||||
|
char *a _AND
|
||||||
|
char *b _AND
|
||||||
|
char *c _AND
|
||||||
|
int (*cmp)())
|
||||||
|
{
|
||||||
|
return cmp(a, b) < 0 ?
|
||||||
|
(cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
|
||||||
|
:(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_DEFUN(qsort, (a, n, es, cmp),
|
||||||
|
void *a _AND
|
||||||
|
size_t n _AND
|
||||||
|
size_t es _AND
|
||||||
|
int (*cmp)())
|
||||||
|
{
|
||||||
|
char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
|
||||||
|
int d, r, swaptype, swap_cnt;
|
||||||
|
|
||||||
|
loop: SWAPINIT(a, es);
|
||||||
|
swap_cnt = 0;
|
||||||
|
if (n < 7) {
|
||||||
|
for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
|
||||||
|
for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
|
||||||
|
pl -= es)
|
||||||
|
swap(pl, pl - es);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pm = (char *) a + (n / 2) * es;
|
||||||
|
if (n > 7) {
|
||||||
|
pl = a;
|
||||||
|
pn = (char *) a + (n - 1) * es;
|
||||||
|
if (n > 40) {
|
||||||
|
d = (n / 8) * es;
|
||||||
|
pl = med3(pl, pl + d, pl + 2 * d, cmp);
|
||||||
|
pm = med3(pm - d, pm, pm + d, cmp);
|
||||||
|
pn = med3(pn - 2 * d, pn - d, pn, cmp);
|
||||||
|
}
|
||||||
|
pm = med3(pl, pm, pn, cmp);
|
||||||
|
}
|
||||||
|
swap(a, pm);
|
||||||
|
pa = pb = (char *) a + es;
|
||||||
|
|
||||||
|
pc = pd = (char *) a + (n - 1) * es;
|
||||||
|
for (;;) {
|
||||||
|
while (pb <= pc && (r = cmp(pb, a)) <= 0) {
|
||||||
|
if (r == 0) {
|
||||||
|
swap_cnt = 1;
|
||||||
|
swap(pa, pb);
|
||||||
|
pa += es;
|
||||||
|
}
|
||||||
|
pb += es;
|
||||||
|
}
|
||||||
|
while (pb <= pc && (r = cmp(pc, a)) >= 0) {
|
||||||
|
if (r == 0) {
|
||||||
|
swap_cnt = 1;
|
||||||
|
swap(pc, pd);
|
||||||
|
pd -= es;
|
||||||
|
}
|
||||||
|
pc -= es;
|
||||||
|
}
|
||||||
|
if (pb > pc)
|
||||||
|
break;
|
||||||
|
swap(pb, pc);
|
||||||
|
swap_cnt = 1;
|
||||||
|
pb += es;
|
||||||
|
pc -= es;
|
||||||
|
}
|
||||||
|
if (swap_cnt == 0) { /* Switch to insertion sort */
|
||||||
|
for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
|
||||||
|
for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
|
||||||
|
pl -= es)
|
||||||
|
swap(pl, pl - es);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pn = (char *) a + n * es;
|
||||||
|
r = min(pa - (char *)a, pb - pa);
|
||||||
|
vecswap(a, pb - r, r);
|
||||||
|
r = min(pd - pc, pn - pd - es);
|
||||||
|
vecswap(pb, pn - r, r);
|
||||||
|
if ((r = pb - pa) > es)
|
||||||
|
qsort(a, r / es, es, cmp);
|
||||||
|
if ((r = pd - pc) > es) {
|
||||||
|
/* Iterate rather than recurse to save stack space */
|
||||||
|
a = pn - r;
|
||||||
|
n = r / es;
|
||||||
|
goto loop;
|
||||||
|
}
|
||||||
|
/* qsort(pn - r, r / es, es, cmp);*/
|
||||||
|
}
|
67
newlib/libc/search/tdelete.c
Normal file
67
newlib/libc/search/tdelete.c
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/* $NetBSD: tdelete.c,v 1.2 1999/09/16 11:45:37 lukem Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tree search generalized from Knuth (6.2.2) Algorithm T just like
|
||||||
|
* the AT&T man page says.
|
||||||
|
*
|
||||||
|
* The node_t structure is for internal use only, lint doesn't grok it.
|
||||||
|
*
|
||||||
|
* Written by reading the System V Interface Definition, not the code.
|
||||||
|
*
|
||||||
|
* Totally public domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#if 0
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
__RCSID("$NetBSD: tdelete.c,v 1.2 1999/09/16 11:45:37 lukem Exp $");
|
||||||
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#define _SEARCH_PRIVATE
|
||||||
|
#include <search.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* delete node with given key */
|
||||||
|
void *
|
||||||
|
tdelete(vkey, vrootp, compar)
|
||||||
|
const void *vkey; /* key to be deleted */
|
||||||
|
void **vrootp; /* address of the root of tree */
|
||||||
|
int (*compar)(const void *, const void *);
|
||||||
|
{
|
||||||
|
node_t **rootp = (node_t **)vrootp;
|
||||||
|
node_t *p, *q, *r;
|
||||||
|
int cmp;
|
||||||
|
|
||||||
|
if (rootp == NULL || (p = *rootp) == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while ((cmp = (*compar)(vkey, (*rootp)->key)) != 0) {
|
||||||
|
p = *rootp;
|
||||||
|
rootp = (cmp < 0) ?
|
||||||
|
&(*rootp)->llink : /* follow llink branch */
|
||||||
|
&(*rootp)->rlink; /* follow rlink branch */
|
||||||
|
if (*rootp == NULL)
|
||||||
|
return NULL; /* key not found */
|
||||||
|
}
|
||||||
|
r = (*rootp)->rlink; /* D1: */
|
||||||
|
if ((q = (*rootp)->llink) == NULL) /* Left NULL? */
|
||||||
|
q = r;
|
||||||
|
else if (r != NULL) { /* Right link is NULL? */
|
||||||
|
if (r->llink == NULL) { /* D2: Find successor */
|
||||||
|
r->llink = q;
|
||||||
|
q = r;
|
||||||
|
} else { /* D3: Find NULL link */
|
||||||
|
for (q = r->llink; q->llink != NULL; q = r->llink)
|
||||||
|
r = q;
|
||||||
|
r->llink = q->rlink;
|
||||||
|
q->llink = (*rootp)->llink;
|
||||||
|
q->rlink = (*rootp)->rlink;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(*rootp); /* D4: Free node */
|
||||||
|
*rootp = q; /* link parent to new node */
|
||||||
|
return p;
|
||||||
|
}
|
49
newlib/libc/search/tdestroy.c
Normal file
49
newlib/libc/search/tdestroy.c
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/* $NetBSD: tdelete.c,v 1.2 1999/09/16 11:45:37 lukem Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tree search generalized from Knuth (6.2.2) Algorithm T just like
|
||||||
|
* the AT&T man page says.
|
||||||
|
*
|
||||||
|
* The node_t structure is for internal use only, lint doesn't grok it.
|
||||||
|
*
|
||||||
|
* Written by reading the System V Interface Definition, not the code.
|
||||||
|
*
|
||||||
|
* Totally public domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#if 0
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
__RCSID("$NetBSD: tdelete.c,v 1.2 1999/09/16 11:45:37 lukem Exp $");
|
||||||
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#define _SEARCH_PRIVATE
|
||||||
|
#include <search.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Walk the nodes of a tree */
|
||||||
|
static void
|
||||||
|
trecurse(root, free_action)
|
||||||
|
node_t *root; /* Root of the tree to be walked */
|
||||||
|
void (*free_action)(void *);
|
||||||
|
{
|
||||||
|
if (root->llink != NULL)
|
||||||
|
trecurse(root->llink, free_action);
|
||||||
|
if (root->rlink != NULL)
|
||||||
|
trecurse(root->rlink, free_action);
|
||||||
|
|
||||||
|
(*free_action) ((void *) root->key);
|
||||||
|
free(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tdestroy (void *vrootp, void (*freefct)(void *))
|
||||||
|
{
|
||||||
|
node_t *root = (node_t *) vrootp;
|
||||||
|
|
||||||
|
if (root != NULL)
|
||||||
|
trecurse(root, freefct);
|
||||||
|
}
|
48
newlib/libc/search/tfind.c
Normal file
48
newlib/libc/search/tfind.c
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/* $NetBSD: tfind.c,v 1.2 1999/09/16 11:45:37 lukem Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tree search generalized from Knuth (6.2.2) Algorithm T just like
|
||||||
|
* the AT&T man page says.
|
||||||
|
*
|
||||||
|
* The node_t structure is for internal use only, lint doesn't grok it.
|
||||||
|
*
|
||||||
|
* Written by reading the System V Interface Definition, not the code.
|
||||||
|
*
|
||||||
|
* Totally public domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#if 0
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
__RCSID("$NetBSD: tfind.c,v 1.2 1999/09/16 11:45:37 lukem Exp $");
|
||||||
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#define _SEARCH_PRIVATE
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <search.h>
|
||||||
|
|
||||||
|
/* find a node, or return 0 */
|
||||||
|
void *
|
||||||
|
tfind(vkey, vrootp, compar)
|
||||||
|
const void *vkey; /* key to be found */
|
||||||
|
void **vrootp; /* address of the tree root */
|
||||||
|
int (*compar)(const void *, const void *);
|
||||||
|
{
|
||||||
|
node_t **rootp = (node_t **)vrootp;
|
||||||
|
|
||||||
|
if (rootp == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while (*rootp != NULL) { /* T1: */
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if ((r = (*compar)(vkey, (*rootp)->key)) == 0) /* T2: */
|
||||||
|
return *rootp; /* key found */
|
||||||
|
rootp = (r < 0) ?
|
||||||
|
&(*rootp)->llink : /* T3: follow left branch */
|
||||||
|
&(*rootp)->rlink; /* T4: follow right branch */
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
118
newlib/libc/search/tsearch.3
Normal file
118
newlib/libc/search/tsearch.3
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
.\" $NetBSD$
|
||||||
|
.\" Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||||
|
.\" All rights reserved.
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer in the
|
||||||
|
.\" documentation and/or other materials provided with the distribution.
|
||||||
|
.\" 3. The name of the author may not be used to endorse or promote products
|
||||||
|
.\" derived from this software without specific prior written permission.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
.\"
|
||||||
|
.\" OpenBSD: tsearch.3,v 1.2 1998/06/21 22:13:49 millert Exp
|
||||||
|
.\" $FreeBSD: src/lib/libc/stdlib/tsearch.3,v 1.7 2001/09/07 14:46:36 asmodai Exp $
|
||||||
|
.\"
|
||||||
|
.Dd June 15, 1997
|
||||||
|
.Dt TSEARCH 3
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm tsearch , tfind , tdelete , twalk
|
||||||
|
.Nd manipulate binary search trees
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In search.h
|
||||||
|
.Ft void *
|
||||||
|
.Fn tdelete "const void *key" "void **rootp" "int (*compar) (const void *, const void *)"
|
||||||
|
.Ft void *
|
||||||
|
.Fn tfind "const void *key" "void **rootp" "int (*compar) (const void *, const void *)"
|
||||||
|
.Ft void *
|
||||||
|
.Fn tsearch "const void *key" "void **rootp" "int (*compar) (const void *, const void *)"
|
||||||
|
.Ft void
|
||||||
|
.Fn twalk "const void *root" "void (*compar) (const void *, VISIT, int)"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Fn tdelete ,
|
||||||
|
.Fn tfind ,
|
||||||
|
.Fn tsearch ,
|
||||||
|
and
|
||||||
|
.Fn twalk
|
||||||
|
functions manage binary search trees based on algorithms T and D
|
||||||
|
from Knuth (6.2.2). The comparison function passed in by
|
||||||
|
the user has the same style of return values as
|
||||||
|
.Xr strcmp 3 .
|
||||||
|
.Pp
|
||||||
|
.Fn Tfind
|
||||||
|
searches for the datum matched by the argument
|
||||||
|
.Fa key
|
||||||
|
in the binary tree rooted at
|
||||||
|
.Fa rootp ,
|
||||||
|
returning a pointer to the datum if it is found and NULL
|
||||||
|
if it is not.
|
||||||
|
.Pp
|
||||||
|
.Fn Tsearch
|
||||||
|
is identical to
|
||||||
|
.Fn tfind
|
||||||
|
except that if no match is found,
|
||||||
|
.Fa key
|
||||||
|
is inserted into the tree and a pointer to it is returned. If
|
||||||
|
.Fa rootp
|
||||||
|
points to a NULL value a new binary search tree is created.
|
||||||
|
.Pp
|
||||||
|
.Fn Tdelete
|
||||||
|
deletes a node from the specified binary search tree and returns
|
||||||
|
a pointer to the parent of the node to be deleted.
|
||||||
|
It takes the same arguments as
|
||||||
|
.Fn tfind
|
||||||
|
and
|
||||||
|
.Fn tsearch .
|
||||||
|
If the node to be deleted is the root of the binary search tree,
|
||||||
|
.Fa rootp
|
||||||
|
will be adjusted.
|
||||||
|
.Pp
|
||||||
|
.Fn Twalk
|
||||||
|
walks the binary search tree rooted in
|
||||||
|
.Fa root
|
||||||
|
and calls the function
|
||||||
|
.Fa action
|
||||||
|
on each node.
|
||||||
|
.Fa Action
|
||||||
|
is called with three arguments: a pointer to the current node,
|
||||||
|
a value from the enum
|
||||||
|
.Sy "typedef enum { preorder, postorder, endorder, leaf } VISIT;"
|
||||||
|
specifying the traversal type, and a node level (where level
|
||||||
|
zero is the root of the tree).
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr bsearch 3 ,
|
||||||
|
.Xr hsearch 3 ,
|
||||||
|
.Xr lsearch 3
|
||||||
|
.Sh RETURN VALUES
|
||||||
|
The
|
||||||
|
.Fn tsearch
|
||||||
|
function returns NULL if allocation of a new node fails (usually
|
||||||
|
due to a lack of free memory).
|
||||||
|
.Pp
|
||||||
|
.Fn Tfind ,
|
||||||
|
.Fn tsearch ,
|
||||||
|
and
|
||||||
|
.Fn tdelete
|
||||||
|
return NULL if
|
||||||
|
.Fa rootp
|
||||||
|
is NULL or the datum cannot be found.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fn twalk
|
||||||
|
function returns no value.
|
58
newlib/libc/search/tsearch.c
Normal file
58
newlib/libc/search/tsearch.c
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/* $NetBSD: tsearch.c,v 1.3 1999/09/16 11:45:37 lukem Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tree search generalized from Knuth (6.2.2) Algorithm T just like
|
||||||
|
* the AT&T man page says.
|
||||||
|
*
|
||||||
|
* The node_t structure is for internal use only, lint doesn't grok it.
|
||||||
|
*
|
||||||
|
* Written by reading the System V Interface Definition, not the code.
|
||||||
|
*
|
||||||
|
* Totally public domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#if 0
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
__RCSID("$NetBSD: tsearch.c,v 1.3 1999/09/16 11:45:37 lukem Exp $");
|
||||||
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#define _SEARCH_PRIVATE
|
||||||
|
#include <search.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* find or insert datum into search tree */
|
||||||
|
void *
|
||||||
|
tsearch(vkey, vrootp, compar)
|
||||||
|
const void *vkey; /* key to be located */
|
||||||
|
void **vrootp; /* address of tree root */
|
||||||
|
int (*compar)(const void *, const void *);
|
||||||
|
{
|
||||||
|
node_t *q;
|
||||||
|
node_t **rootp = (node_t **)vrootp;
|
||||||
|
|
||||||
|
if (rootp == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while (*rootp != NULL) { /* Knuth's T1: */
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if ((r = (*compar)(vkey, (*rootp)->key)) == 0) /* T2: */
|
||||||
|
return *rootp; /* we found it! */
|
||||||
|
|
||||||
|
rootp = (r < 0) ?
|
||||||
|
&(*rootp)->llink : /* T3: follow left branch */
|
||||||
|
&(*rootp)->rlink; /* T4: follow right branch */
|
||||||
|
}
|
||||||
|
|
||||||
|
q = malloc(sizeof(node_t)); /* T5: key not found */
|
||||||
|
if (q != 0) { /* make new node */
|
||||||
|
*rootp = q; /* link new node to old */
|
||||||
|
/* LINTED const castaway ok */
|
||||||
|
q->key = (void *)vkey; /* initialize new node */
|
||||||
|
q->llink = q->rlink = NULL;
|
||||||
|
}
|
||||||
|
return q;
|
||||||
|
}
|
58
newlib/libc/search/twalk.c
Normal file
58
newlib/libc/search/twalk.c
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/* $NetBSD: twalk.c,v 1.1 1999/02/22 10:33:16 christos Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tree search generalized from Knuth (6.2.2) Algorithm T just like
|
||||||
|
* the AT&T man page says.
|
||||||
|
*
|
||||||
|
* The node_t structure is for internal use only, lint doesn't grok it.
|
||||||
|
*
|
||||||
|
* Written by reading the System V Interface Definition, not the code.
|
||||||
|
*
|
||||||
|
* Totally public domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#if 0
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
__RCSID("$NetBSD: twalk.c,v 1.1 1999/02/22 10:33:16 christos Exp $");
|
||||||
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#define _SEARCH_PRIVATE
|
||||||
|
#include <search.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static void trecurse(const node_t *,
|
||||||
|
void (*action)(const void *, VISIT, int), int level);
|
||||||
|
|
||||||
|
/* Walk the nodes of a tree */
|
||||||
|
static void
|
||||||
|
trecurse(root, action, level)
|
||||||
|
const node_t *root; /* Root of the tree to be walked */
|
||||||
|
void (*action)(const void *, VISIT, int);
|
||||||
|
int level;
|
||||||
|
{
|
||||||
|
|
||||||
|
if (root->llink == NULL && root->rlink == NULL)
|
||||||
|
(*action)(root, leaf, level);
|
||||||
|
else {
|
||||||
|
(*action)(root, preorder, level);
|
||||||
|
if (root->llink != NULL)
|
||||||
|
trecurse(root->llink, action, level + 1);
|
||||||
|
(*action)(root, postorder, level);
|
||||||
|
if (root->rlink != NULL)
|
||||||
|
trecurse(root->rlink, action, level + 1);
|
||||||
|
(*action)(root, endorder, level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Walk the nodes of a tree */
|
||||||
|
void
|
||||||
|
twalk(vroot, action)
|
||||||
|
const void *vroot; /* Root of the tree to be walked */
|
||||||
|
void (*action)(const void *, VISIT, int);
|
||||||
|
{
|
||||||
|
if (vroot != NULL && action != NULL)
|
||||||
|
trecurse(vroot, action, 0);
|
||||||
|
}
|
@ -18,7 +18,6 @@ LIB_SOURCES = \
|
|||||||
atoff.c \
|
atoff.c \
|
||||||
atoi.c \
|
atoi.c \
|
||||||
atol.c \
|
atol.c \
|
||||||
bsearch.c \
|
|
||||||
calloc.c \
|
calloc.c \
|
||||||
div.c \
|
div.c \
|
||||||
drand48.c \
|
drand48.c \
|
||||||
@ -59,7 +58,6 @@ LIB_SOURCES = \
|
|||||||
on_exit.c \
|
on_exit.c \
|
||||||
putenv.c \
|
putenv.c \
|
||||||
putenv_r.c \
|
putenv_r.c \
|
||||||
qsort.c \
|
|
||||||
rand.c \
|
rand.c \
|
||||||
rand48.c \
|
rand48.c \
|
||||||
rand_r.c \
|
rand_r.c \
|
||||||
@ -154,7 +152,6 @@ CHEWOUT_FILES= \
|
|||||||
atof.def \
|
atof.def \
|
||||||
ecvtbuf.def \
|
ecvtbuf.def \
|
||||||
atoi.def \
|
atoi.def \
|
||||||
bsearch.def \
|
|
||||||
calloc.def \
|
calloc.def \
|
||||||
div.def \
|
div.def \
|
||||||
efgcvt.def \
|
efgcvt.def \
|
||||||
@ -171,7 +168,6 @@ CHEWOUT_FILES= \
|
|||||||
mlock.def \
|
mlock.def \
|
||||||
mstats.def \
|
mstats.def \
|
||||||
on_exit.def \
|
on_exit.def \
|
||||||
qsort.def \
|
|
||||||
rand.def \
|
rand.def \
|
||||||
rand48.def \
|
rand48.def \
|
||||||
strtod.def \
|
strtod.def \
|
||||||
|
@ -122,7 +122,6 @@ LIB_SOURCES = \
|
|||||||
atoff.c \
|
atoff.c \
|
||||||
atoi.c \
|
atoi.c \
|
||||||
atol.c \
|
atol.c \
|
||||||
bsearch.c \
|
|
||||||
calloc.c \
|
calloc.c \
|
||||||
div.c \
|
div.c \
|
||||||
drand48.c \
|
drand48.c \
|
||||||
@ -163,7 +162,6 @@ LIB_SOURCES = \
|
|||||||
on_exit.c \
|
on_exit.c \
|
||||||
putenv.c \
|
putenv.c \
|
||||||
putenv_r.c \
|
putenv_r.c \
|
||||||
qsort.c \
|
|
||||||
rand.c \
|
rand.c \
|
||||||
rand48.c \
|
rand48.c \
|
||||||
rand_r.c \
|
rand_r.c \
|
||||||
@ -219,7 +217,6 @@ CHEWOUT_FILES = \
|
|||||||
atof.def \
|
atof.def \
|
||||||
ecvtbuf.def \
|
ecvtbuf.def \
|
||||||
atoi.def \
|
atoi.def \
|
||||||
bsearch.def \
|
|
||||||
calloc.def \
|
calloc.def \
|
||||||
div.def \
|
div.def \
|
||||||
efgcvt.def \
|
efgcvt.def \
|
||||||
@ -236,7 +233,6 @@ CHEWOUT_FILES = \
|
|||||||
mlock.def \
|
mlock.def \
|
||||||
mstats.def \
|
mstats.def \
|
||||||
on_exit.def \
|
on_exit.def \
|
||||||
qsort.def \
|
|
||||||
rand.def \
|
rand.def \
|
||||||
rand48.def \
|
rand48.def \
|
||||||
strtod.def \
|
strtod.def \
|
||||||
@ -273,9 +269,9 @@ LIBS = @LIBS@
|
|||||||
@USE_LIBTOOL_FALSE@__ten_mu.$(OBJEXT) _Exit.$(OBJEXT) a64l.$(OBJEXT) \
|
@USE_LIBTOOL_FALSE@__ten_mu.$(OBJEXT) _Exit.$(OBJEXT) a64l.$(OBJEXT) \
|
||||||
@USE_LIBTOOL_FALSE@abort.$(OBJEXT) abs.$(OBJEXT) assert.$(OBJEXT) \
|
@USE_LIBTOOL_FALSE@abort.$(OBJEXT) abs.$(OBJEXT) assert.$(OBJEXT) \
|
||||||
@USE_LIBTOOL_FALSE@atexit.$(OBJEXT) atof.$(OBJEXT) atoff.$(OBJEXT) \
|
@USE_LIBTOOL_FALSE@atexit.$(OBJEXT) atof.$(OBJEXT) atoff.$(OBJEXT) \
|
||||||
@USE_LIBTOOL_FALSE@atoi.$(OBJEXT) atol.$(OBJEXT) bsearch.$(OBJEXT) \
|
@USE_LIBTOOL_FALSE@atoi.$(OBJEXT) atol.$(OBJEXT) calloc.$(OBJEXT) \
|
||||||
@USE_LIBTOOL_FALSE@calloc.$(OBJEXT) div.$(OBJEXT) drand48.$(OBJEXT) \
|
@USE_LIBTOOL_FALSE@div.$(OBJEXT) drand48.$(OBJEXT) dtoa.$(OBJEXT) \
|
||||||
@USE_LIBTOOL_FALSE@dtoa.$(OBJEXT) dtoastub.$(OBJEXT) ecvtbuf.$(OBJEXT) \
|
@USE_LIBTOOL_FALSE@dtoastub.$(OBJEXT) ecvtbuf.$(OBJEXT) \
|
||||||
@USE_LIBTOOL_FALSE@efgcvt.$(OBJEXT) environ.$(OBJEXT) envlock.$(OBJEXT) \
|
@USE_LIBTOOL_FALSE@efgcvt.$(OBJEXT) environ.$(OBJEXT) envlock.$(OBJEXT) \
|
||||||
@USE_LIBTOOL_FALSE@eprintf.$(OBJEXT) erand48.$(OBJEXT) exit.$(OBJEXT) \
|
@USE_LIBTOOL_FALSE@eprintf.$(OBJEXT) erand48.$(OBJEXT) exit.$(OBJEXT) \
|
||||||
@USE_LIBTOOL_FALSE@getenv.$(OBJEXT) getenv_r.$(OBJEXT) getopt.$(OBJEXT) \
|
@USE_LIBTOOL_FALSE@getenv.$(OBJEXT) getenv_r.$(OBJEXT) getopt.$(OBJEXT) \
|
||||||
@ -287,15 +283,15 @@ LIBS = @LIBS@
|
|||||||
@USE_LIBTOOL_FALSE@mbtowc_r.$(OBJEXT) mlock.$(OBJEXT) mprec.$(OBJEXT) \
|
@USE_LIBTOOL_FALSE@mbtowc_r.$(OBJEXT) mlock.$(OBJEXT) mprec.$(OBJEXT) \
|
||||||
@USE_LIBTOOL_FALSE@mrand48.$(OBJEXT) msize.$(OBJEXT) mstats.$(OBJEXT) \
|
@USE_LIBTOOL_FALSE@mrand48.$(OBJEXT) msize.$(OBJEXT) mstats.$(OBJEXT) \
|
||||||
@USE_LIBTOOL_FALSE@mtrim.$(OBJEXT) nrand48.$(OBJEXT) on_exit.$(OBJEXT) \
|
@USE_LIBTOOL_FALSE@mtrim.$(OBJEXT) nrand48.$(OBJEXT) on_exit.$(OBJEXT) \
|
||||||
@USE_LIBTOOL_FALSE@putenv.$(OBJEXT) putenv_r.$(OBJEXT) qsort.$(OBJEXT) \
|
@USE_LIBTOOL_FALSE@putenv.$(OBJEXT) putenv_r.$(OBJEXT) rand.$(OBJEXT) \
|
||||||
@USE_LIBTOOL_FALSE@rand.$(OBJEXT) rand48.$(OBJEXT) rand_r.$(OBJEXT) \
|
@USE_LIBTOOL_FALSE@rand48.$(OBJEXT) rand_r.$(OBJEXT) realloc.$(OBJEXT) \
|
||||||
@USE_LIBTOOL_FALSE@realloc.$(OBJEXT) seed48.$(OBJEXT) setenv.$(OBJEXT) \
|
@USE_LIBTOOL_FALSE@seed48.$(OBJEXT) setenv.$(OBJEXT) setenv_r.$(OBJEXT) \
|
||||||
@USE_LIBTOOL_FALSE@setenv_r.$(OBJEXT) srand48.$(OBJEXT) \
|
@USE_LIBTOOL_FALSE@srand48.$(OBJEXT) strdup.$(OBJEXT) \
|
||||||
@USE_LIBTOOL_FALSE@strdup.$(OBJEXT) strdup_r.$(OBJEXT) strtod.$(OBJEXT) \
|
@USE_LIBTOOL_FALSE@strdup_r.$(OBJEXT) strtod.$(OBJEXT) strtol.$(OBJEXT) \
|
||||||
@USE_LIBTOOL_FALSE@strtol.$(OBJEXT) strtoll.$(OBJEXT) \
|
@USE_LIBTOOL_FALSE@strtoll.$(OBJEXT) strtoll_r.$(OBJEXT) \
|
||||||
@USE_LIBTOOL_FALSE@strtoll_r.$(OBJEXT) strtoul.$(OBJEXT) \
|
@USE_LIBTOOL_FALSE@strtoul.$(OBJEXT) strtoull.$(OBJEXT) \
|
||||||
@USE_LIBTOOL_FALSE@strtoull.$(OBJEXT) strtoull_r.$(OBJEXT) \
|
@USE_LIBTOOL_FALSE@strtoull_r.$(OBJEXT) system.$(OBJEXT) \
|
||||||
@USE_LIBTOOL_FALSE@system.$(OBJEXT) valloc.$(OBJEXT) wcstombs.$(OBJEXT) \
|
@USE_LIBTOOL_FALSE@valloc.$(OBJEXT) wcstombs.$(OBJEXT) \
|
||||||
@USE_LIBTOOL_FALSE@wcstombs_r.$(OBJEXT) wctomb.$(OBJEXT) \
|
@USE_LIBTOOL_FALSE@wcstombs_r.$(OBJEXT) wctomb.$(OBJEXT) \
|
||||||
@USE_LIBTOOL_FALSE@wctomb_r.$(OBJEXT)
|
@USE_LIBTOOL_FALSE@wctomb_r.$(OBJEXT)
|
||||||
LTLIBRARIES = $(noinst_LTLIBRARIES)
|
LTLIBRARIES = $(noinst_LTLIBRARIES)
|
||||||
@ -308,21 +304,20 @@ LTLIBRARIES = $(noinst_LTLIBRARIES)
|
|||||||
@USE_LIBTOOL_TRUE@libstdlib_la_OBJECTS = __adjust.lo __exp10.lo \
|
@USE_LIBTOOL_TRUE@libstdlib_la_OBJECTS = __adjust.lo __exp10.lo \
|
||||||
@USE_LIBTOOL_TRUE@__ten_mu.lo _Exit.lo a64l.lo abort.lo abs.lo \
|
@USE_LIBTOOL_TRUE@__ten_mu.lo _Exit.lo a64l.lo abort.lo abs.lo \
|
||||||
@USE_LIBTOOL_TRUE@assert.lo atexit.lo atof.lo atoff.lo atoi.lo atol.lo \
|
@USE_LIBTOOL_TRUE@assert.lo atexit.lo atof.lo atoff.lo atoi.lo atol.lo \
|
||||||
@USE_LIBTOOL_TRUE@bsearch.lo calloc.lo div.lo drand48.lo dtoa.lo \
|
@USE_LIBTOOL_TRUE@calloc.lo div.lo drand48.lo dtoa.lo dtoastub.lo \
|
||||||
@USE_LIBTOOL_TRUE@dtoastub.lo ecvtbuf.lo efgcvt.lo environ.lo \
|
@USE_LIBTOOL_TRUE@ecvtbuf.lo efgcvt.lo environ.lo envlock.lo eprintf.lo \
|
||||||
@USE_LIBTOOL_TRUE@envlock.lo eprintf.lo erand48.lo exit.lo getenv.lo \
|
@USE_LIBTOOL_TRUE@erand48.lo exit.lo getenv.lo getenv_r.lo getopt.lo \
|
||||||
@USE_LIBTOOL_TRUE@getenv_r.lo getopt.lo jrand48.lo l64a.lo labs.lo \
|
@USE_LIBTOOL_TRUE@jrand48.lo l64a.lo labs.lo lcong48.lo ldiv.lo \
|
||||||
@USE_LIBTOOL_TRUE@lcong48.lo ldiv.lo ldtoa.lo lrand48.lo malign.lo \
|
@USE_LIBTOOL_TRUE@ldtoa.lo lrand48.lo malign.lo malloc.lo mblen.lo \
|
||||||
@USE_LIBTOOL_TRUE@malloc.lo mblen.lo mblen_r.lo mbstowcs.lo \
|
@USE_LIBTOOL_TRUE@mblen_r.lo mbstowcs.lo mbstowcs_r.lo mbtowc.lo \
|
||||||
@USE_LIBTOOL_TRUE@mbstowcs_r.lo mbtowc.lo mbtowc_r.lo mlock.lo mprec.lo \
|
@USE_LIBTOOL_TRUE@mbtowc_r.lo mlock.lo mprec.lo mrand48.lo msize.lo \
|
||||||
@USE_LIBTOOL_TRUE@mrand48.lo msize.lo mstats.lo mtrim.lo nrand48.lo \
|
@USE_LIBTOOL_TRUE@mstats.lo mtrim.lo nrand48.lo on_exit.lo putenv.lo \
|
||||||
@USE_LIBTOOL_TRUE@on_exit.lo putenv.lo putenv_r.lo qsort.lo rand.lo \
|
@USE_LIBTOOL_TRUE@putenv_r.lo rand.lo rand48.lo rand_r.lo realloc.lo \
|
||||||
@USE_LIBTOOL_TRUE@rand48.lo rand_r.lo realloc.lo seed48.lo setenv.lo \
|
@USE_LIBTOOL_TRUE@seed48.lo setenv.lo setenv_r.lo srand48.lo strdup.lo \
|
||||||
@USE_LIBTOOL_TRUE@setenv_r.lo srand48.lo strdup.lo strdup_r.lo \
|
@USE_LIBTOOL_TRUE@strdup_r.lo strtod.lo strtol.lo strtoll.lo \
|
||||||
@USE_LIBTOOL_TRUE@strtod.lo strtol.lo strtoll.lo strtoll_r.lo \
|
@USE_LIBTOOL_TRUE@strtoll_r.lo strtoul.lo strtoull.lo strtoull_r.lo \
|
||||||
@USE_LIBTOOL_TRUE@strtoul.lo strtoull.lo strtoull_r.lo system.lo \
|
@USE_LIBTOOL_TRUE@system.lo valloc.lo wcstombs.lo wcstombs_r.lo \
|
||||||
@USE_LIBTOOL_TRUE@valloc.lo wcstombs.lo wcstombs_r.lo wctomb.lo \
|
@USE_LIBTOOL_TRUE@wctomb.lo wctomb_r.lo
|
||||||
@USE_LIBTOOL_TRUE@wctomb_r.lo
|
|
||||||
CFLAGS = @CFLAGS@
|
CFLAGS = @CFLAGS@
|
||||||
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||||
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||||
|
@ -11,7 +11,6 @@ The corresponding declarations are in the header file @file{stdlib.h}.
|
|||||||
* atexit:: Request execution of functions at program exit
|
* atexit:: Request execution of functions at program exit
|
||||||
* atof:: String to double or float
|
* atof:: String to double or float
|
||||||
* atoi:: String to integer
|
* atoi:: String to integer
|
||||||
* bsearch:: Binary search
|
|
||||||
* calloc:: Allocate space for arrays
|
* calloc:: Allocate space for arrays
|
||||||
* div:: Divide two integers
|
* div:: Divide two integers
|
||||||
* ecvtbuf:: Double or float to string of digits
|
* ecvtbuf:: Double or float to string of digits
|
||||||
@ -28,7 +27,6 @@ The corresponding declarations are in the header file @file{stdlib.h}.
|
|||||||
* mbstowcs:: Minimal multibyte string to wide string converter
|
* mbstowcs:: Minimal multibyte string to wide string converter
|
||||||
* mblen:: Minimal multibyte length
|
* mblen:: Minimal multibyte length
|
||||||
* mbtowc:: Minimal multibyte to wide character converter
|
* mbtowc:: Minimal multibyte to wide character converter
|
||||||
* qsort:: Sort an array
|
|
||||||
* rand:: Pseudo-random numbers
|
* rand:: Pseudo-random numbers
|
||||||
* rand48:: Uniformly distributed pseudo-random numbers
|
* rand48:: Uniformly distributed pseudo-random numbers
|
||||||
* strtod:: String to double or float
|
* strtod:: String to double or float
|
||||||
@ -57,9 +55,6 @@ The corresponding declarations are in the header file @file{stdlib.h}.
|
|||||||
@page
|
@page
|
||||||
@include stdlib/atoi.def
|
@include stdlib/atoi.def
|
||||||
|
|
||||||
@page
|
|
||||||
@include stdlib/bsearch.def
|
|
||||||
|
|
||||||
@page
|
@page
|
||||||
@include stdlib/calloc.def
|
@include stdlib/calloc.def
|
||||||
|
|
||||||
@ -105,9 +100,6 @@ The corresponding declarations are in the header file @file{stdlib.h}.
|
|||||||
@page
|
@page
|
||||||
@include stdlib/mbtowc.def
|
@include stdlib/mbtowc.def
|
||||||
|
|
||||||
@page
|
|
||||||
@include stdlib/qsort.def
|
|
||||||
|
|
||||||
@page
|
@page
|
||||||
@include stdlib/rand.def
|
@include stdlib/rand.def
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user