diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2004-06-24 04:43:34 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2004-06-24 04:43:34 +0000 |
commit | 9c06fe2ff2b8dfe77892a0dd3631241a1a789daa (patch) | |
tree | eee465ff5db7265f36a9600031374157fdf655fe /lib | |
parent | 25b5d0c61452ba19e289b1d9e8edfa2e0c823b2c (diff) |
Working hcreate(3) et al from NetBSD (cgd) via ray at cyth dot net.
Now passes the regress tests.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libc/db/hash/Makefile.inc | 4 | ||||
-rw-r--r-- | lib/libc/db/hash/hsearch.c | 109 | ||||
-rw-r--r-- | lib/libc/db/man/Makefile.inc | 5 | ||||
-rw-r--r-- | lib/libc/stdlib/Makefile.inc | 11 | ||||
-rw-r--r-- | lib/libc/stdlib/hcreate.3 (renamed from lib/libc/db/man/hcreate.3) | 12 | ||||
-rw-r--r-- | lib/libc/stdlib/hcreate.c | 200 |
6 files changed, 216 insertions, 125 deletions
diff --git a/lib/libc/db/hash/Makefile.inc b/lib/libc/db/hash/Makefile.inc index 8022fe41e68..5825ef8c976 100644 --- a/lib/libc/db/hash/Makefile.inc +++ b/lib/libc/db/hash/Makefile.inc @@ -1,6 +1,6 @@ -# $OpenBSD: Makefile.inc,v 1.4 1998/11/20 11:18:35 d Exp $ +# $OpenBSD: Makefile.inc,v 1.5 2004/06/24 04:43:33 millert Exp $ .PATH: ${LIBCSRCDIR}/db/hash SRCS+= hash.c hash_bigkey.c hash_buf.c hash_func.c hash_log2.c \ - hash_page.c hsearch.c ndbm.c + hash_page.c ndbm.c diff --git a/lib/libc/db/hash/hsearch.c b/lib/libc/db/hash/hsearch.c deleted file mode 100644 index ffd7d399e47..00000000000 --- a/lib/libc/db/hash/hsearch.c +++ /dev/null @@ -1,109 +0,0 @@ -/* $OpenBSD: hsearch.c,v 1.6 2003/06/02 20:18:34 millert Exp $ */ - -/*- - * 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. 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) -#if 0 -static char sccsid[] = "@(#)hsearch.c 8.5 (Berkeley) 9/21/94"; -#else -static const char rcsid[] = "$OpenBSD: hsearch.c,v 1.6 2003/06/02 20:18:34 millert Exp $"; -#endif -#endif /* LIBC_SCCS and not lint */ - -#include <sys/types.h> - -#include <fcntl.h> -#include <string.h> - -#include <db.h> -#include "search.h" - -static DB *dbp = NULL; -static ENTRY retval; - -extern int -hcreate(nel) - u_int nel; -{ - HASHINFO info; - - info.nelem = nel; - info.bsize = 256; - info.ffactor = 8; - info.cachesize = 0; - info.hash = NULL; - info.lorder = 0; - dbp = (DB *)__hash_open(NULL, O_CREAT | O_RDWR, 0600, &info, 0); - return (dbp != NULL); -} - -extern ENTRY * -hsearch(item, action) - ENTRY item; - ACTION action; -{ - DBT key, val; - int status; - - if (!dbp) - return (NULL); - key.data = (u_char *)item.key; - key.size = strlen(item.key) + 1; - - if (action == ENTER) { - val.data = (u_char *)item.data; - val.size = strlen(item.data) + 1; - status = (dbp->put)(dbp, &key, &val, R_NOOVERWRITE); - if (status) - return (NULL); - } else { - /* FIND */ - status = (dbp->get)(dbp, &key, &val, 0); - if (status) - return (NULL); - else - item.data = (char *)val.data; - } - retval.key = item.key; - retval.data = item.data; - return (&retval); -} - -extern void -hdestroy() -{ - if (dbp) { - (void)(dbp->close)(dbp); - dbp = NULL; - } -} diff --git a/lib/libc/db/man/Makefile.inc b/lib/libc/db/man/Makefile.inc index 7e03894fedc..6fad4927777 100644 --- a/lib/libc/db/man/Makefile.inc +++ b/lib/libc/db/man/Makefile.inc @@ -1,12 +1,11 @@ -# $OpenBSD: Makefile.inc,v 1.11 2001/04/16 00:08:46 millert Exp $ +# $OpenBSD: Makefile.inc,v 1.12 2004/06/24 04:43:33 millert Exp $ .PATH: ${LIBCSRCDIR}/db/man -MAN+= btree.3 dbm.3 dbopen.3 hash.3 hcreate.3 mpool.3 ndbm.3 recno.3 +MAN+= btree.3 dbm.3 dbopen.3 hash.3 mpool.3 ndbm.3 recno.3 MLINKS+= dbopen.3 db.3 MLINKS+= dbm.3 dbminit.3 dbm.3 dbmclose.3 dbm.3 fetch.3 dbm.3 store.3 MLINKS+= dbm.3 delete.3 dbm.3 firstkey.3 dbm.3 nextkey.3 -MLINKS+= hcreate.3 hdestroy.3 hcreate.3 hsearch.3 MLINKS+= mpool.3 mpool_open.3 mpool.3 mpool_filter.3 mpool.3 mpool_new.3 MLINKS+= mpool.3 mpool_delete.3 mpool.3 mpool_get.3 mpool.3 mpool_put.3 MLINKS+= mpool.3 mpool_sync.3 mpool.3 mpool_close.3 diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc index 80d3c221128..1d5ba5c9bd4 100644 --- a/lib/libc/stdlib/Makefile.inc +++ b/lib/libc/stdlib/Makefile.inc @@ -5,10 +5,10 @@ SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c atoll.c bsearch.c \ calloc.c cfree.c exit.c ecvt.c gcvt.c getenv.c getopt_long.c \ - getsubopt.c heapsort.c l64a.c llabs.c lsearch.c malloc.c merge.c \ - multibyte.c putenv.c qsort.c radixsort.c rand.c random.c realpath.c \ - setenv.c strtod.c strtol.c strtoll.c strtonum.c strtoul.c strtoull.c \ - system.c \ + getsubopt.c hcreate.c heapsort.c l64a.c llabs.c lsearch.c malloc.c \ + merge.c multibyte.c putenv.c qsort.c radixsort.c rand.c random.c \ + realpath.c setenv.c strtod.c strtol.c strtoll.c strtonum.c strtoul.c \ + strtoull.c system.c \ tfind.c tsearch.c _rand48.c drand48.c erand48.c jrand48.c lcong48.c \ lrand48.c mrand48.c nrand48.c seed48.c srand48.c qabs.c qdiv.c _Exit.c @@ -41,7 +41,7 @@ SRCS+= insque.c remque.c MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 atoll.3 \ bsearch.3 div.3 ecvt.3 exit.3 getenv.3 getopt.3 getopt_long.3 \ - getsubopt.3 insque.3 labs.3 ldiv.3 lsearch.3 malloc.3 qabs.3 \ + getsubopt.3 hcreate.3 insque.3 labs.3 ldiv.3 lsearch.3 malloc.3 qabs.3 \ qdiv.3 qsort.3 radixsort.3 rand48.3 rand.3 random.3 realpath.3 \ strtod.3 strtonum.3 strtol.3 strtoul.3 system.3 tsearch.3 @@ -49,6 +49,7 @@ MLINKS+=exit.3 _Exit.3 MLINKS+=ecvt.3 fcvt.3 ecvt.3 gcvt.3 MLINKS+=getenv.3 setenv.3 getenv.3 unsetenv.3 getenv.3 putenv.3 MLINKS+=getopt_long.3 getopt_long_only.3 +MLINKS+=hcreate.3 hdestroy.3 hcreate.3 hsearch.3 MLINKS+=insque.3 remque.3 MLINKS+=labs.3 llabs.3 MLINKS+=lsearch.3 lfind.3 diff --git a/lib/libc/db/man/hcreate.3 b/lib/libc/stdlib/hcreate.3 index 89286d15aeb..d1d4e5c1856 100644 --- a/lib/libc/db/man/hcreate.3 +++ b/lib/libc/stdlib/hcreate.3 @@ -1,5 +1,5 @@ -.\" $OpenBSD: hcreate.3,v 1.4 2003/05/30 13:11:14 jmc Exp $ -.\" $NetBSD: hcreate.3,v 1.2.4.1 2001/03/13 21:19:18 he Exp $ +.\" $OpenBSD: hcreate.3,v 1.1 2004/06/24 04:43:33 millert Exp $ +.\" $NetBSD: hcreate.3,v 1.6 2003/04/16 13:34:46 wiz Exp $ .\" .\" Copyright (c) 1999 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -44,7 +44,7 @@ .Nm hsearch .Nd manage hash search table .Sh SYNOPSIS -.Fd #include <search.h> +.In search.h .Ft int .Fn hcreate "size_t nel" .Ft void @@ -66,8 +66,7 @@ The .Fa nel argument specifies an estimate of the maximum number of entries to be held by the table. -Unless further memory allocation fails, supplying an -insufficient +Unless further memory allocation fails, supplying an insufficient .Fa nel value will not result in functional harm, although a performance degradation may occur. @@ -87,7 +86,8 @@ the data can no longer be accessed. The .Fn hsearch function is used to search to the hash table. -It returns a pointer into the hash table indicating the address of an item. +It returns a pointer into the +hash table indicating the address of an item. The .Fa item argument is of type diff --git a/lib/libc/stdlib/hcreate.c b/lib/libc/stdlib/hcreate.c new file mode 100644 index 00000000000..14e6fa41f23 --- /dev/null +++ b/lib/libc/stdlib/hcreate.c @@ -0,0 +1,200 @@ +/* $OpenBSD: hcreate.c,v 1.1 2004/06/24 04:43:33 millert Exp $ */ +/* $NetBSD: hcreate.c,v 1.5 2004/04/23 02:48:12 simonb 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... + */ + +#ifndef lint +static const char copyright[] = +"@(#) Copyright (c) 2001 Christopher G. Demetriou. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static const char rcsid[] = "$OpenBSD: hcreate.c,v 1.1 2004/06/24 04:43:33 millert Exp $"; +#endif /* not lint */ + +#include "namespace.h" +#include <assert.h> +#include <errno.h> +#include <inttypes.h> +#include <search.h> +#include <stdlib.h> +#include <string.h> +#include <sys/queue.h> + +#ifndef _DIAGASSERT +#define _DIAGASSERT +#endif + +/* + * 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 u_int32_t (*__default_hash)(const void *, size_t); + +static struct internal_head *htable; +static size_t htablesize; + +int +hcreate(size_t nel) +{ + size_t idx; + unsigned int p2; + + /* Make sure this isn't called when a table already exists. */ + _DIAGASSERT(htable == NULL); + if (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; + _DIAGASSERT(p2 <= MAX_BUCKETS_LG2); + nel = 1 << p2; + } + + /* Allocate the table. */ + htablesize = nel; + htable = malloc(htablesize * sizeof htable[0]); + if (htable == NULL) { + errno = ENOMEM; + return 0; + } + + /* Initialize it. */ + for (idx = 0; idx < htablesize; idx++) + SLIST_INIT(&htable[idx]); + + return 1; +} + +void +hdestroy(void) +{ + struct internal_entry *ie; + size_t idx; + + _DIAGASSERT(htable != NULL); + if (htable == NULL) + return; + + for (idx = 0; idx < htablesize; idx++) { + while (!SLIST_EMPTY(&htable[idx])) { + ie = SLIST_FIRST(&htable[idx]); + SLIST_REMOVE_HEAD(&htable[idx], link); + free(ie->ent.key); + free(ie); + } + } + free(htable); + htable = NULL; +} + +ENTRY * +hsearch(ENTRY item, ACTION action) +{ + struct internal_head *head; + struct internal_entry *ie; + uint32_t hashval; + size_t len; + + _DIAGASSERT(htable != NULL); + _DIAGASSERT(item.key != NULL); + _DIAGASSERT(action == ENTER || action == FIND); + + len = strlen(item.key); + hashval = (*__default_hash)(item.key, len); + + head = &htable[hashval & (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) + return &ie->ent; + else if (action == FIND) + return NULL; + + ie = malloc(sizeof *ie); + if (ie == NULL) + return NULL; + ie->ent.key = item.key; + ie->ent.data = item.data; + + SLIST_INSERT_HEAD(head, ie, link); + return &ie->ent; +} |