summaryrefslogtreecommitdiff
path: root/c_src/hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'c_src/hash.c')
-rw-r--r--c_src/hash.c402
1 files changed, 0 insertions, 402 deletions
diff --git a/c_src/hash.c b/c_src/hash.c
deleted file mode 100644
index 75d3999..0000000
--- a/c_src/hash.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * 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. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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 table functions
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-RCSID("$Id: hash.c,v 1.18 2002/05/23 15:21:41 lha Exp $");
-#endif
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <ctype.h>
-//#include <bool.h>
-#include "hash.h"
-#include "arlamath.h"
-
-
-struct ht_bucket {
- Hashentry *e;
- int len;
-};
-
-
-struct hashtab { /* Hash table */
- int (*cmp)(void *, void *); /* Compare function */
- unsigned (*hash)(void *); /* hash function */
- int flags; /* flags */
- int sz; /* Size */
- int maxbucketlen; /* max bucket length */
- struct ht_bucket *tab; /* The table */
-};
-
-struct hashentry { /* Entry in bucket */
- struct hashentry **prev;
- struct hashentry *next;
- void *ptr;
-};
-
-#define HASHTAB_INITAL_SIZE 17
-#define HASHTAB_MAX_BUCKET_LEN 20
-
-static Hashentry *_search(Hashtab * htab, /* The hash table */
- void *ptr); /* And key */
-static void *_add(Hashtab * htab,
- void *ptr,
- int unique);
-
-static void _might_resize(Hashtab *htab, /* The hash table */
- int bucket_len); /* Hash bucket len */
-
-Hashtab *
-hashtabnew(int sz,
- int (*cmp) (void *, void *),
- unsigned (*hash) (void *))
-{
- return hashtabnewf(sz, cmp, hash, 0);
-}
-
-Hashtab *
-hashtabnewf(int sz,
- int (*cmp) (void *, void *),
- unsigned (*hash) (void *),
- int flags)
-{
- Hashtab *htab;
- int i;
-
- assert(sz > 0 || (flags & HASHTAB_GROW));
-
- htab = (Hashtab *) malloc(sizeof(Hashtab));
-
- if (htab == NULL)
- return NULL;
-
- if (sz == 0 && (flags & HASHTAB_GROW))
- sz = HASHTAB_INITAL_SIZE;
-
- htab->tab = malloc(sz * sizeof(struct ht_bucket));
- if (htab->tab == NULL){
- free(htab);
- return NULL;
- }
-
- for (i = 0; i < sz; ++i) {
- htab->tab[i].e = NULL;
- htab->tab[i].len = 0;
- }
-
- htab->cmp = cmp;
- htab->hash = hash;
- htab->sz = sz;
- htab->maxbucketlen = HASHTAB_MAX_BUCKET_LEN;
- htab->flags = flags;
-
- return htab;
-}
-
-/* Intern search function */
-
-static Hashentry *
-_search(Hashtab * htab, void *ptr)
-{
- Hashentry *hptr;
-
- assert(htab && ptr);
-
- for (hptr = htab->tab[(*htab->hash) (ptr) % htab->sz].e;
- hptr;
- hptr = hptr->next)
- if ((*htab->cmp) (ptr, hptr->ptr) == 0)
- break;
- return hptr;
-}
-
-/* Interal resize function */
-
-static int
-_resize(void *ptr, void *arg)
-{
- Hashtab *h = arg;
- _add(h, ptr, TRUE);
- return TRUE;
-}
-
-static void
-_might_resize(Hashtab *htab, int bucket_len)
-{
- if (bucket_len > htab->maxbucketlen) {
- Hashtab *nhtab;
- struct ht_bucket *tab;
- int new_size, old_size;
-
- new_size = arlautil_findprime(htab->sz * 2);
- fprintf(stderr, "trying resize to %d\n", new_size);
- assert (new_size > htab->sz);
-
- nhtab = hashtabnewf(new_size, htab->cmp,
- htab->hash, htab->flags);
- if (nhtab == NULL)
- return;
-
- hashtabcleantab(htab, _resize, nhtab);
-
- /* switch place between the tab and size */
- tab = htab->tab;
- htab->tab = nhtab->tab;
- nhtab->tab = tab;
-
- old_size = htab->sz;
- htab->sz = nhtab->sz;
- nhtab->sz = old_size;
-
- hashtabrelease(nhtab);
- }
-}
-
-
-/* Search for element in hash table */
-
-void *
-hashtabsearch(Hashtab * htab, void *ptr)
-{
- Hashentry *tmp;
-
- tmp = _search(htab, ptr);
- return tmp ? tmp->ptr : tmp;
-}
-
-/* add element to hash table */
-/* if already there, set new value */
-/* !NULL if succesful */
-
-static void *
-_add(Hashtab * htab, void *ptr, int unique)
-{
- Hashentry *h = _search(htab, ptr);
- Hashentry **tabptr;
- struct ht_bucket *hb;
-
- assert(htab && ptr);
-
- if (h) {
- if (unique)
- return NULL;
- free((void *) h->ptr);
- h->ptr = ptr;
- } else {
- h = (Hashentry *) malloc(sizeof(Hashentry));
- if (h == NULL) {
- return NULL;
- }
- hb = &htab->tab[(*htab->hash) (ptr) % htab->sz];
- hb->len++;
- tabptr = &hb->e;
- h->next = *tabptr;
- h->prev = tabptr;
- if (h->next)
- h->next->prev = &h->next;
- h->ptr = ptr;
- *tabptr = h;
-#if 0
- if (hb->len > htab->maxbucketlen) {
- struct nodecache {
- uint32_t entries[4];
- char key[];
- };
- {
- struct nodecache *node = (struct nodecache *)ptr;
-
- fprintf(stderr, "bucket %u full: %d, searching for %s\n", (*htab->hash) (ptr) % htab->sz, hb->len, node->key);
- }
- for (Hashentry *hptr = htab->tab[(*htab->hash) (ptr) % htab->sz].e;
- hptr;
- hptr = hptr->next) {
- struct nodecache *node = (struct nodecache *)hptr->ptr;
- fprintf(stderr, "\tothers in bucket: %s\n", node->key);
- }
- }
-#endif
- if (htab->flags & HASHTAB_GROW)
- _might_resize(htab, hb->len);
- }
- return h;
-}
-
-void *
-hashtabaddreplace (Hashtab *htab, void *ptr)
-{
- return _add (htab, ptr, FALSE);
-}
-
-void *
-hashtabadd (Hashtab *htab, void *ptr)
-{
- return _add (htab, ptr, TRUE);
-}
-
-/* delete element with key key. Iff freep, free Hashentry->ptr */
-
-int
-_hashtabdel(Hashtab * htab, void *ptr, int freep)
-{
- Hashentry *h;
-
- assert(htab && ptr);
-
- h = _search(htab, ptr);
- if (h) {
- if (freep)
- free(h->ptr);
- if ((*(h->prev) = h->next))
- h->next->prev = h->prev;
- free(h);
- return 0;
- } else
- return -1;
-}
-
-/* Do something for each element */
-
-void
-hashtabforeach(Hashtab * htab, int(*func) (void *ptr, void *arg),
- void *arg)
-{
- struct ht_bucket *h;
- Hashentry *g, *next;
-
- assert(htab);
-
- for (h = htab->tab; h < &htab->tab[htab->sz]; ++h)
- for (g = h->e; g; g = next) {
- next = g->next;
- if ((*func) (g->ptr, arg))
- return;
- }
-}
-
-
-/* Clean out all elements that meet condition */
-
-void
-hashtabcleantab(Hashtab * htab, int(*cond) (void *ptr, void *arg),
- void *arg)
-{
- struct ht_bucket *h;
- Hashentry *g, *f;
-
- assert(htab);
-
- for (h = htab->tab; h < &htab->tab[htab->sz]; ++h) {
- for (g = h->e; g;) {
- if ((*cond) (g->ptr, arg)) {
- f = g ;
- g = g->next ;
- if ((*(f->prev) = f->next))
- f->next->prev = f->prev;
- free(f);
- assert(h->len > 0);
- h->len--;
- } else {
- g = g->next;
- }
- }
- }
-}
-
-static int
-true_cond(void *ptr, void *arg)
-{
- return TRUE;
-}
-
-/* Free the hashtab and all items in it */
-
-void
-hashtabrelease(Hashtab *htab)
-{
- hashtabcleantab(htab, true_cond, NULL);
- free(htab->tab);
- free(htab);
-}
-
-
-/* standard hash-functions for strings */
-
-unsigned
-hashadd(const char *s)
-{ /* Standard hash function */
- unsigned i;
-
- assert(s);
-
- for (i = 0; *s; ++s)
- i += *s;
- return i;
-}
-
-unsigned
-hashcaseadd(const char *s)
-{ /* Standard hash function */
- unsigned i;
-
- assert(s);
-
- for (i = 0; *s; ++s)
- i += toupper((unsigned char)*s);
- return i;
-}
-
-#define TWELVE (sizeof(unsigned))
-#define SEVENTYFIVE (6*sizeof(unsigned))
-#define HIGH_BITS (~((unsigned)(~0) >> TWELVE))
-
-unsigned
-hashjpw(const char *ss)
-{ /* another hash function */
- unsigned h = 0;
- unsigned g;
- unsigned const char *s = (unsigned const char *) ss;
-
- for (; *s; ++s) {
- h = (h << TWELVE) + *s;
- if ((g = h & HIGH_BITS))
- h = (h ^ (g >> SEVENTYFIVE)) & ~HIGH_BITS;
- }
- return h;
-}