home *** CD-ROM | disk | FTP | other *** search
- /*
-
-
- Copyright (C) 1990 Texas Instruments Incorporated.
-
- Permission is granted to any individual or institution to use, copy, modify,
- and distribute this software, provided that this complete copyright and
- permission notice is maintained, intact, in all copies and supporting
- documentation.
-
- Texas Instruments Incorporated provides this software "as is" without
- express or implied warranty.
-
-
- *
- * Edit history
- * Created: LGO 30-Mar-89 -- Initial design and implementation.
- *
- * Hash functions
- */
-
- #include "defmacio.h"
-
- void*
- next_hash(h, firstp)
- struct Hash_Table* h;
- Boolean firstp;
- {
- if(firstp) {
- h->current_bucket = 0;
- h->current_index = 0;
- }
- while (h->current_bucket < hash_primes[h->bucket_index]) {
- if (h->current_index < h->items_in_buckets[h->current_bucket])
- return h->table[h->current_bucket].data[h->current_index++].value;
- else {
- h->current_bucket += 1;
- h->current_index = 0;
- }
- }
- return NULL;
- }
-
- /* sxhash -- Hash function for char*
- * Input: Character string
- * Output: unsigned long hash value
- */
- unsigned long sxhash(string)
- char* string;
- {
- register unsigned long hash = *string++;
- if(*string != EOS) {
- hash = (hash << 7) ^ *string++;
- if (*string != EOS) {
- hash = (hash << 7) ^ *string++;
- if (*string != EOS) {
- hash = (hash << 7) ^ *string++;
- while (*string != EOS) { /* rotate hash left 7 bits */
- int rest = hash >> 25;
- hash = ((hash << 7) | rest) ^ *string++;
- }
- }
- }
- }
- return hash;
- }
-
- struct Hash_Table*
- init_Hash_Table() {
- struct Hash_Table* h = (struct Hash_Table*) getmem(sizeof(struct Hash_Table));
- int prime, i;
- h->entry_count = 0;
- h->bucket_index = 0;
- prime = hash_primes[h->bucket_index];
- h->items_in_buckets = (unsigned char*) getmem (prime);
- for (i = 0; i < prime; i++)
- h->items_in_buckets[i] = 0;
- h->table = (struct bucket*) getmem(sizeof(struct bucket)*prime);
- return h;
- }
-
- static void
- resize (h, n)
- struct Hash_Table* h;
- int n;
- {
- unsigned char* temp1;
- struct bucket* temp2;
- long old_prime, i, j, new_prime, hash;
- old_prime = hash_primes[h->bucket_index];
-
- while (hash_primes[h->bucket_index]*BUCKET_SIZE < n)
- h->bucket_index++;
-
- retry:
- new_prime = hash_primes[h->bucket_index];
- temp1 = (unsigned char*) getmem (new_prime);
- for (i = 0; i < new_prime; i++)
- temp1[i] = 0;
- temp2 = (struct bucket*) getmem(sizeof (struct bucket) * new_prime);
- for (i = 0; i < old_prime; i++) {
- for (j = 0; j < h->items_in_buckets[i]; j++) {
- char* key = h->table[i].data[j].key;
- hash = sxhash(key) % new_prime;
- if (temp1[hash] >= BUCKET_SIZE) { /* Bucket Overflow */
- free (temp1);
- free (temp2);
- h->bucket_index++;
- goto retry;
- }
- temp2[hash].data[temp1[hash]].key = key;
- temp2[hash].data[temp1[hash]].value = h->table[i].data[j].value;
- ++temp1[hash];
- }
- }
- free (h->items_in_buckets);
- free (h->table);
- h->items_in_buckets = temp1;
- h->table = temp2;
- }
-
- int
- get_entry_count (h)
- struct Hash_Table* h;
- {
- return (h->entry_count);
- }
-
- Boolean
- put_hash (h, key, value)
- struct Hash_Table* h;
- char* key;
- void* value;
- {
- long prime,hash;
- int next, i;
- retry:
- prime = hash_primes[h->bucket_index];
- hash = sxhash(key) % prime;
- for (i = 0; i < h->items_in_buckets[hash]; i++)
- if (!strcmp(key,h->table[hash].data[i].key))
- return FALSE;
- if (h->items_in_buckets[hash] >= BUCKET_SIZE) {
- resize (h, hash_primes[h->bucket_index+1]*BUCKET_SIZE);
- goto retry;
- }
- next = h->items_in_buckets[hash]++;
- h->table[hash].data[next].key = key;
- h->table[hash].data[next].value = value;
- h->entry_count++;
- return TRUE;
- }
-
- void*
- get_hash (h, key)
- struct Hash_Table* h;
- char* key;
- {
- long prime, hash;
- int i, len;
- prime = hash_primes[h->bucket_index];
- hash = sxhash(key) % prime;
- len = h->items_in_buckets[hash];
- for (i = 0; i < len; i++) {
- if (!strcmp(key,h->table[hash].data[i].key))
- return (h->table[hash].data[i].value);
- }
- return NULL;
- }
-
-