diff options
author | Marc Espie <espie@cvs.openbsd.org> | 2000-06-23 16:24:52 +0000 |
---|---|---|
committer | Marc Espie <espie@cvs.openbsd.org> | 2000-06-23 16:24:52 +0000 |
commit | 239c19f2c09a9a0d658c57e5bdffe8403f0bc7fb (patch) | |
tree | 3d3935e0d3d8b687feb4248871f759aafc7f6af8 /usr.bin/make/ohash | |
parent | 41e33b5b009c8bead85f37baffcdd523386c86da (diff) |
Open Hashing library, based on Knuth.
Some interface work to make it as fast as possible.
Diffstat (limited to 'usr.bin/make/ohash')
-rw-r--r-- | usr.bin/make/ohash/hash_create_entry.c | 53 | ||||
-rw-r--r-- | usr.bin/make/ohash/hash_delete.c | 45 | ||||
-rw-r--r-- | usr.bin/make/ohash/hash_do.c | 132 | ||||
-rw-r--r-- | usr.bin/make/ohash/hash_entries.c | 40 | ||||
-rw-r--r-- | usr.bin/make/ohash/hash_enum.c | 52 | ||||
-rw-r--r-- | usr.bin/make/ohash/hash_init.c | 58 | ||||
-rw-r--r-- | usr.bin/make/ohash/hash_interval.c | 46 | ||||
-rw-r--r-- | usr.bin/make/ohash/hash_lookup_interval.c | 84 | ||||
-rw-r--r-- | usr.bin/make/ohash/hash_lookup_memory.c | 81 | ||||
-rw-r--r-- | usr.bin/make/ohash/hash_lookup_string.c | 80 | ||||
-rw-r--r-- | usr.bin/make/ohash/hash_qlookup.c | 42 | ||||
-rw-r--r-- | usr.bin/make/ohash/hash_qlookupi.c | 44 | ||||
-rw-r--r-- | usr.bin/make/ohash/ohash.h | 90 | ||||
-rw-r--r-- | usr.bin/make/ohash/ohash_int.h | 13 |
14 files changed, 860 insertions, 0 deletions
diff --git a/usr.bin/make/ohash/hash_create_entry.c b/usr.bin/make/ohash/hash_create_entry.c new file mode 100644 index 00000000000..a1ed8597194 --- /dev/null +++ b/usr.bin/make/ohash/hash_create_entry.c @@ -0,0 +1,53 @@ +/* $OpenBSD: hash_create_entry.c,v 1.1 2000/06/23 16:24:50 espie Exp $ */ +/* ex:ts=8 sw=4: + */ + +/* + * Copyright (c) 1999 Marc Espie. + * + * Code written for the OpenBSD project. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD + * PROJECT 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 "ohash_int.h" + +/* This handles the common case of variable length keys, where the + * key is stored at the end of the record. + */ +void * +hash_create_entry(i, start, end) + struct hash_info *i; + const char *start; + const char **end; +{ + char *p; + + if (!*end) + *end = start + strlen(start); + p = (i->alloc)(i->key_offset + (*end - start) + 1, i->data); + if (p) { + memcpy(p+i->key_offset, start, *end-start); + p[i->key_offset + (*end - start)] = '\0'; + } + return (void *)p; +} diff --git a/usr.bin/make/ohash/hash_delete.c b/usr.bin/make/ohash/hash_delete.c new file mode 100644 index 00000000000..1506837e0b4 --- /dev/null +++ b/usr.bin/make/ohash/hash_delete.c @@ -0,0 +1,45 @@ +/* $OpenBSD: hash_delete.c,v 1.1 2000/06/23 16:24:50 espie Exp $ */ +/* ex:ts=8 sw=4: + */ + +/* + * Copyright (c) 1999 Marc Espie. + * + * Code written for the OpenBSD project. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD + * PROJECT 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 "ohash_int.h" +/* hash_delete only frees the hash structure. Use hash_first/hash_next + * to free entries as well. */ +void +hash_delete(h) + struct hash *h; +{ + (h->info.hfree)(h->t, sizeof(struct hash_record) * h->size, + h->info.data); +#ifndef NDEBUG + h->t = NULL; +#endif +} + diff --git a/usr.bin/make/ohash/hash_do.c b/usr.bin/make/ohash/hash_do.c new file mode 100644 index 00000000000..d1abe9b807d --- /dev/null +++ b/usr.bin/make/ohash/hash_do.c @@ -0,0 +1,132 @@ +/* $OpenBSD: hash_do.c,v 1.1 2000/06/23 16:24:50 espie Exp $ */ +/* ex:ts=8 sw=4: + */ + +/* + * Copyright (c) 1999 Marc Espie. + * + * Code written for the OpenBSD project. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD + * PROJECT 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 "ohash_int.h" + +static void hash_resize __P((struct hash *)); + +static void +hash_resize(h) + struct hash *h; +{ + struct hash_record *n; + unsigned ns, j; + unsigned i, incr; + + if (4 * h->deleted < h->total) + ns = h->size << 1; + else if (3 * h->deleted > 2 * h->total) + ns = h->size >> 1; + else + ns = h->size; + if (ns < MINSIZE) + ns = MINSIZE; +#ifdef STATS_HASH + STAT_HASH_EXPAND++; + STAT_HASH_SIZE += ns - h->size; +#endif + n = (h->info.halloc)(sizeof(struct hash_record) * ns, h->info.data); + if (!n) + return; + + for (j = 0; j < h->size; j++) { + if (h->t[j].p != NULL && h->t[j].p != DELETED) { + i = h->t[j].hv % ns; + incr = ((h->t[j].hv % (ns - 2)) & ~1) + 1; + while (n[i].p != NULL) { + i += incr; + if (i >= ns) + i -= ns; + } + n[i].hv = h->t[j].hv; + n[i].p = h->t[j].p; + } + } + (h->info.hfree)(h->t, sizeof(struct hash_record) * h->size, + h->info.data); + h->t = n; + h->size = ns; + h->total -= h->deleted; + h->deleted = 0; +} + +void * +hash_remove(h, i) + struct hash *h; + unsigned i; +{ + void *result = (void *)h->t[i].p; + + if (result == NULL || result == DELETED) + return NULL; + +#ifdef STATS_HASH + STAT_HASH_ENTRIES--; +#endif + h->t[i].p = DELETED; + h->deleted++; + if (h->deleted >= MINDELETED && 4 * h->deleted > h->total) + hash_resize(h); + return result; +} + +void * +hash_find(h, i) + struct hash *h; + unsigned i; +{ + if (h->t[i].p == DELETED) + return NULL; + else + return (void *)h->t[i].p; +} + +void * +hash_insert(h, i, p) + struct hash *h; + unsigned i; + void *p; +{ +#ifdef STATS_HASH + STAT_HASH_ENTRIES++; +#endif + if (h->t[i].p == DELETED) { + h->deleted--; + h->t[i].p = p; + } else { + h->t[i].p = p; + /* Arbitrary resize boundary. Tweak if not efficient enough. */ + if (++h->total * 4 > h->size * 3) + hash_resize(h); + } + return p; +} + diff --git a/usr.bin/make/ohash/hash_entries.c b/usr.bin/make/ohash/hash_entries.c new file mode 100644 index 00000000000..d8b9bcfb32d --- /dev/null +++ b/usr.bin/make/ohash/hash_entries.c @@ -0,0 +1,40 @@ +/* $OpenBSD: hash_entries.c,v 1.1 2000/06/23 16:24:50 espie Exp $ */ +/* ex:ts=8 sw=4: + */ + +/* + * Copyright (c) 1999 Marc Espie. + * + * Code written for the OpenBSD project. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD + * PROJECT 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 "ohash_int.h" + +unsigned +hash_entries(h) + struct hash *h; +{ + return h->total - h->deleted; +} + diff --git a/usr.bin/make/ohash/hash_enum.c b/usr.bin/make/ohash/hash_enum.c new file mode 100644 index 00000000000..57daaa0eb65 --- /dev/null +++ b/usr.bin/make/ohash/hash_enum.c @@ -0,0 +1,52 @@ +/* $OpenBSD: hash_enum.c,v 1.1 2000/06/23 16:24:50 espie Exp $ */ +/* ex:ts=8 sw=4: + */ + +/* + * Copyright (c) 1999 Marc Espie. + * + * Code written for the OpenBSD project. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD + * PROJECT 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 "ohash_int.h" + +void * +hash_first(h, pos) + struct hash *h; + unsigned *pos; +{ + *pos = 0; + return hash_next(h, pos); +} + +void * +hash_next(h, pos) + struct hash *h; + unsigned *pos; +{ + for (; *pos < h->size; (*pos)++) + if (h->t[*pos].p != DELETED && h->t[*pos].p != NULL) + return (void *)h->t[(*pos)++].p; + return NULL; +} diff --git a/usr.bin/make/ohash/hash_init.c b/usr.bin/make/ohash/hash_init.c new file mode 100644 index 00000000000..35d1af354c3 --- /dev/null +++ b/usr.bin/make/ohash/hash_init.c @@ -0,0 +1,58 @@ +/* $OpenBSD: hash_init.c,v 1.1 2000/06/23 16:24:50 espie Exp $ */ +/* ex:ts=8 sw=4: + */ + +/* + * Copyright (c) 1999 Marc Espie. + * + * Code written for the OpenBSD project. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD + * PROJECT 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 "ohash_int.h" + +void +hash_init(h, size, info) + struct hash *h; + unsigned size; + struct hash_info*info; +{ + h->size = 1UL << size; + if (h->size < MINSIZE) + h->size = MINSIZE; +#ifdef STATS_HASH + STAT_HASH_CREATION++; + STAT_HASH_SIZE += h->size; +#endif + /* Copy info so that caller may free it. */ + h->info.key_offset = info->key_offset; + h->info.halloc = info->halloc; + h->info.hfree = info->hfree; + h->info.alloc = info->alloc; + h->info.data = info->data; + h->t = (h->info.halloc)(sizeof(struct hash_record) * h->size, + h->info.data); + h->total = h->deleted = 0; +} + diff --git a/usr.bin/make/ohash/hash_interval.c b/usr.bin/make/ohash/hash_interval.c new file mode 100644 index 00000000000..23b2a283bb0 --- /dev/null +++ b/usr.bin/make/ohash/hash_interval.c @@ -0,0 +1,46 @@ +/* $OpenBSD: hash_interval.c,v 1.1 2000/06/23 16:24:50 espie Exp $ */ +/* ex:ts=8 sw=4: + */ + +/* + * Copyright (c) 1999 Marc Espie. + * + * Code written for the OpenBSD project. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD + * PROJECT 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 "ohash_int.h" + +u_int32_t +hash_interval(s, e) + const char *s; + const char **e; +{ + u_int32_t k; + + k = *s++; + while (*s && s != *e) + k = ((k << 2) | (k >> 30)) ^ *s++; + *e = s; + return k; +} diff --git a/usr.bin/make/ohash/hash_lookup_interval.c b/usr.bin/make/ohash/hash_lookup_interval.c new file mode 100644 index 00000000000..a68ffd628c3 --- /dev/null +++ b/usr.bin/make/ohash/hash_lookup_interval.c @@ -0,0 +1,84 @@ +/* $OpenBSD: hash_lookup_interval.c,v 1.1 2000/06/23 16:24:50 espie Exp $ */ +/* ex:ts=8 sw=4: + */ + +/* + * Copyright (c) 1999 Marc Espie. + * + * Code written for the OpenBSD project. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD + * PROJECT 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 "ohash_int.h" + +unsigned +hash_lookup_interval(h, start, end, hv) + struct hash *h; + const char *start; + const char *end; + u_int32_t hv; +{ + unsigned i, incr; + unsigned empty; + +#ifdef STATS_HASH + STAT_HASH_LOOKUP++; +#endif + empty = NONE; + i = hv % h->size; + incr = ((hv % (h->size-2)) & ~1) + 1; + while (h->t[i].p != NULL) { +#ifdef STATS_HASH + STAT_HASH_LENGTH++; +#endif + if (h->t[i].p == DELETED) { + if (empty == NONE) + empty = i; + } else if (h->t[i].hv == hv && + strncmp(h->t[i].p+h->info.key_offset, start, + end - start) == 0 && + (h->t[i].p+h->info.key_offset)[end-start] == '\0') { + if (empty != NONE) { + h->t[empty].hv = hv; + h->t[empty].p = h->t[i].p; + h->t[i].p = DELETED; + return empty; + } else { +#ifdef STATS_HASH + STAT_HASH_POSITIVE++; +#endif + return i; + } + } + i += incr; + if (i >= h->size) + i -= h->size; + } + + /* Found an empty position. */ + if (empty != NONE) + i = empty; + h->t[i].hv = hv; + return i; +} + diff --git a/usr.bin/make/ohash/hash_lookup_memory.c b/usr.bin/make/ohash/hash_lookup_memory.c new file mode 100644 index 00000000000..80750e39ac0 --- /dev/null +++ b/usr.bin/make/ohash/hash_lookup_memory.c @@ -0,0 +1,81 @@ +/* $OpenBSD: hash_lookup_memory.c,v 1.1 2000/06/23 16:24:50 espie Exp $ */ +/* ex:ts=8 sw=4: + */ + +/* + * Copyright (c) 1999 Marc Espie. + * + * Code written for the OpenBSD project. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD + * PROJECT 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 "ohash_int.h" + +unsigned +hash_lookup_memory(h, k, size, hv) + struct hash *h; + const char *k; + size_t size; + u_int32_t hv; +{ + unsigned i, incr; + unsigned empty; + +#ifdef STATS_HASH + STAT_HASH_LOOKUP++; +#endif + empty = NONE; + i = hv % h->size; + incr = ((hv % (h->size-2)) & ~1) + 1; + while (h->t[i].p != NULL) { +#ifdef STATS_HASH + STAT_HASH_LENGTH++; +#endif + if (h->t[i].p == DELETED) { + if (empty == NONE) + empty = i; + } else if (h->t[i].hv == hv && + memcmp(h->t[i].p+h->info.key_offset, k, size) == 0) { + if (empty != NONE) { + h->t[empty].hv = hv; + h->t[empty].p = h->t[i].p; + h->t[i].p = DELETED; + return empty; + } else { +#ifdef STATS_HASH + STAT_HASH_POSITIVE++; +#endif + } return i; + } + i += incr; + if (i >= h->size) + i -= h->size; + } + + /* Found an empty position. */ + if (empty != NONE) + i = empty; + h->t[i].hv = hv; + return i; +} + diff --git a/usr.bin/make/ohash/hash_lookup_string.c b/usr.bin/make/ohash/hash_lookup_string.c new file mode 100644 index 00000000000..f9efcac57b0 --- /dev/null +++ b/usr.bin/make/ohash/hash_lookup_string.c @@ -0,0 +1,80 @@ +/* $OpenBSD: hash_lookup_string.c,v 1.1 2000/06/23 16:24:50 espie Exp $ */ +/* ex:ts=8 sw=4: + */ + +/* + * Copyright (c) 1999 Marc Espie. + * + * Code written for the OpenBSD project. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD + * PROJECT 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 "ohash_int.h" + +unsigned +hash_lookup_string(h, k, hv) + struct hash *h; + const char *k; + u_int32_t hv; +{ + unsigned i, incr; + unsigned empty; + +#ifdef STATS_HASH + STAT_HASH_LOOKUP++; +#endif + empty = NONE; + i = hv % h->size; + incr = ((hv % (h->size-2)) & ~1) + 1; + while (h->t[i].p != NULL) { +#ifdef STATS_HASH + STAT_HASH_LENGTH++; +#endif + if (h->t[i].p == DELETED) { + if (empty == NONE) + empty = i; + } else if (h->t[i].hv == hv && + strcmp(h->t[i].p+h->info.key_offset, k) == 0) { + if (empty != NONE) { + h->t[empty].hv = hv; + h->t[empty].p = h->t[i].p; + h->t[i].p = DELETED; + return empty; + } else { +#ifdef STATS_HASH + STAT_HASH_POSITIVE++; +#endif + return i; + } + } + i += incr; + if (i >= h->size) + i -= h->size; + } + + /* Found an empty position. */ + if (empty != NONE) + i = empty; + h->t[i].hv = hv; + return i; +} diff --git a/usr.bin/make/ohash/hash_qlookup.c b/usr.bin/make/ohash/hash_qlookup.c new file mode 100644 index 00000000000..0f7ff8f49d0 --- /dev/null +++ b/usr.bin/make/ohash/hash_qlookup.c @@ -0,0 +1,42 @@ +/* $OpenBSD: hash_qlookup.c,v 1.1 2000/06/23 16:24:50 espie Exp $ */ +/* ex:ts=8 sw=4: + */ + +/* + * Copyright (c) 1999 Marc Espie. + * + * Code written for the OpenBSD project. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD + * PROJECT 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 "ohash_int.h" + +unsigned +hash_qlookup(h, s) + struct hash *h; + const char *s; +{ + const char *e = NULL; + return hash_qlookupi(h, s, &e); +} + diff --git a/usr.bin/make/ohash/hash_qlookupi.c b/usr.bin/make/ohash/hash_qlookupi.c new file mode 100644 index 00000000000..4e1985b4f8f --- /dev/null +++ b/usr.bin/make/ohash/hash_qlookupi.c @@ -0,0 +1,44 @@ +/* $OpenBSD: hash_qlookupi.c,v 1.1 2000/06/23 16:24:51 espie Exp $ */ +/* ex:ts=8 sw=4: + */ + +/* + * Copyright (c) 1999 Marc Espie. + * + * Code written for the OpenBSD project. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD + * PROJECT 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 "ohash_int.h" + +unsigned +hash_qlookupi(h, s, e) + struct hash *h; + const char *s; + const char **e; +{ + u_int32_t hv; + + hv = hash_interval(s, e); + return hash_lookup_interval(h, s, *e, hv); +} diff --git a/usr.bin/make/ohash/ohash.h b/usr.bin/make/ohash/ohash.h new file mode 100644 index 00000000000..73ca0039301 --- /dev/null +++ b/usr.bin/make/ohash/ohash.h @@ -0,0 +1,90 @@ +#ifndef OHASH_H +#define OHASH_H +/* $OpenBSD: ohash.h,v 1.1 2000/06/23 16:24:51 espie Exp $ */ +/* ex:ts=8 sw=4: + */ + +/* + * Copyright (c) 1999 Marc Espie. + * + * Code written for the OpenBSD project. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD + * PROJECT 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. + */ + +/* Open hashing support. + * Open hashing was chosen because it is much lighter than other hash + * techniques, and more efficient in most cases. + */ + +struct hash_info { + ptrdiff_t key_offset; + void *data; /* user data */ + void *(*halloc) __P((size_t, void *)); + void (*hfree) __P((void *, size_t, void *)); + void *(*alloc) __P((size_t, void *)); +}; + +struct hash { + struct hash_record *t; + struct hash_info info; + unsigned size; + unsigned total; + unsigned deleted; +}; + +struct hash_record { + unsigned hv; + const char *p; +}; + +#define hash_to_info(h) (&(h)->info) + +/* For this to be tweakable, we use small primitives, and leave part of the + * logic to the client application. e.g., hashing is left to the client + * application. We also provide a simple table entry lookup that yields + * a hashing table index (opaque) to be used in find/insert/remove. + * The keys are stored at a known position in the client data. + */ +void hash_init __P((struct hash *, unsigned, struct hash_info *)); +void hash_delete __P((struct hash *)); + +unsigned hash_lookup_string __P((struct hash *, const char *, u_int32_t)); +unsigned hash_lookup_interval __P((struct hash *, const char *, \ + const char *, u_int32_t)); +unsigned hash_lookup_memory __P((struct hash *, const char *, \ + size_t, u_int32_t)); +void *hash_find __P((struct hash *, unsigned)); +void *hash_remove __P((struct hash *, unsigned)); +void *hash_insert __P((struct hash *, unsigned, void *)); +void *hash_first __P((struct hash *, unsigned *)); +void *hash_next __P((struct hash *, unsigned *)); +unsigned hash_entries __P((struct hash *)); + +void *hash_create_entry __P((struct hash_info *, const char *, const char **)); +u_int32_t hash_interval __P((const char *, const char **)); + +unsigned hash_qlookupi __P((struct hash *, const char *, const char **)); +unsigned hash_qlookup __P((struct hash *, const char *)); + +#endif + diff --git a/usr.bin/make/ohash/ohash_int.h b/usr.bin/make/ohash/ohash_int.h new file mode 100644 index 00000000000..0c5f16b9457 --- /dev/null +++ b/usr.bin/make/ohash/ohash_int.h @@ -0,0 +1,13 @@ +#include <sys/types.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include "ohash.h" + +#define DELETED ((const char *)h) +#define NONE (h->size) + +/* Don't bother changing the hash table if the change is small enough. */ +#define MINSIZE (1UL << 4) +#define MINDELETED 4 + |