00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include "hash_table.h"
00004 #include "table.h"
00005 #include "xassert.h"
00006 #include "xmem.h"
00007
00008 unsigned long long hash_universal_hash(const void *v)
00009 {
00010 char *c = (char *) v;
00011 unsigned long long sum = 0;
00012
00013 while ( c && *c )
00014 {
00015 if (sum > ULLONG_MAX / 13)
00016 {
00017
00018 sum /= 17;
00019 }
00020
00021 sum += ((unsigned long long) *c++) + 13*sum;
00022 }
00023
00024 return sum;
00025 }
00026
00027 void hash_init(Hash_Table_t *h, const unsigned int hashprime,
00028 const int initbinsize,
00029 int (*not_equal)(const void *, const void *),
00030 unsigned long long (*hash)(const void *))
00031 {
00032 unsigned int i;
00033
00034 h->hashprime = hashprime;
00035 h->hash = hash;
00036 h->not_equal = not_equal;
00037 h->list = (Table_t *) malloc(hashprime*sizeof(Table_t));
00038 XASSERT(h->list);
00039 for(i=0; i<hashprime; i++)
00040 table_init(initbinsize,&(h->list[i]),not_equal);
00041 }
00042
00043
00044
00045 void hash_copy(Hash_Table_t *dst, Hash_Table_t *src)
00046 {
00047 unsigned int i;
00048
00049 dst->hashprime = src->hashprime;
00050 dst->not_equal = src->not_equal;
00051 dst->hash = src->hash;
00052 dst->list = (Table_t *) malloc(dst->hashprime*sizeof(Table_t));
00053 XASSERT(dst->list);
00054 for(i=0; i<dst->hashprime; i++)
00055 table_copy(&(dst->list[i]), &(src->list[i]));
00056 }
00057
00058 void hash_free(Hash_Table_t *h)
00059 {
00060 unsigned int i;
00061 if (h->list)
00062 {
00063 for(i=0; i<h->hashprime; i++)
00064 table_free(&(h->list[i]));
00065 free(h->list);
00066 h->list = NULL;
00067 }
00068 }
00069
00070 void hash_insert(Hash_Table_t *h, const void *key, const void *contents)
00071 {
00072 table_insert(&(h->list[h->hash(key) % h->hashprime]),key,contents);
00073 }
00074
00075 void hash_remove(Hash_Table_t *h, const void *key)
00076 {
00077 table_remove(&(h->list[h->hash(key) % h->hashprime]),key);
00078 }
00079
00080 int hash_member(Hash_Table_t *h, const void *key)
00081 {
00082 return table_member(&(h->list[h->hash(key) % h->hashprime]),key);
00083 }
00084
00085 const void *hash_lookup(Hash_Table_t *h, const void *key)
00086 {
00087 return table_lookup(&(h->list[h->hash(key) % h->hashprime]),key);
00088 }
00089
00090 int hash_size(Hash_Table_t *h)
00091 {
00092 unsigned int i,size;
00093 for(i=0,size=0; i<h->hashprime; i++)
00094 size += table_len(&(h->list[i]));
00095 return size;
00096 }
00097
00098 void hash_stat(Hash_Table_t *h)
00099 {
00100 unsigned int i, len;
00101 for(i=0; i<h->hashprime; i++) {
00102 len = table_len(&(h->list[i]));
00103 if ( len > 0)
00104 printf("%4u: %4u\n",i,len);
00105 }
00106 }
00107
00108 void hash_map(Hash_Table_t *h, void (*f)(const void *, const void *))
00109 {
00110 unsigned int i, len;
00111 for(i=0; i<h->hashprime; i++)
00112 {
00113 len = table_len(&(h->list[i]));
00114 if ( len > 0 )
00115 {
00116
00117 table_map(&(h->list[i]),f);
00118 }
00119 }
00120 }
00121
00122 void hash_map_data(Hash_Table_t *h, void (*f)(const void *, const void *, const void *data), const void *data)
00123 {
00124 unsigned int i, len;
00125 for(i=0; i<h->hashprime; i++)
00126 {
00127 len = table_len(&(h->list[i]));
00128 if ( len > 0 )
00129 {
00130 table_map_data(&(h->list[i]),f,data);
00131 }
00132 }
00133 }