/* $Id: hash.h,v 1.6 2003/09/24 18:48:59 ukai Exp $ */ #ifndef HASH_H #define HASH_H /* hash table */ #define defhash(keytype,type,sym) \ typedef struct HashItem_##sym { \ keytype key; \ type value; \ struct HashItem_##sym *next; \ } HashItem_##sym; \ typedef struct Hash_##sym { \ int size; \ struct HashItem_##sym **tab; \ } Hash_##sym; \ extern Hash_##sym *newHash_##sym(int size); \ extern void putHash_##sym(Hash_##sym *t, keytype key, type value); \ extern type getHash_##sym(Hash_##sym *t, keytype key, type failval); defhash(char *, int, si) defhash(char *, char *, ss) defhash(char *, void *, sv) defhash(int, void *, iv) #define defhashfunc(keytype,type,sym) \ Hash_##sym * \ newHash_##sym(int size)\ {\ struct Hash_##sym *hash;\ int i;\ \ hash = (Hash_##sym*)GC_malloc(sizeof(Hash_##sym));\ hash->size = size;\ hash->tab = (HashItem_##sym**)GC_malloc(size*sizeof(HashItem_##sym*));\ for (i = 0; i < size; i++)\ hash->tab[i] = NULL;\ return hash;\ }\ \ static HashItem_##sym* \ lookupHash_##sym(Hash_##sym *t, keytype key, int *hashval_return)\ {\ HashItem_##sym *hi;\ \ *hashval_return = hashfunc(key)%t->size;\ for (hi = t->tab[*hashval_return]; hi != NULL; hi = hi->next) {\ if (keycomp(hi->key,key))\ return hi;\ }\ return NULL;\ }\ \ void \ putHash_##sym(Hash_##sym *t, keytype key, type value)\ {\ int h;\ HashItem_##sym *hi;\ \ hi = lookupHash_##sym(t,key,&h);\ if (hi) {\ hi->value = value;\ return;\ }\ \ hi = (HashItem_##sym*)GC_malloc(sizeof(HashItem_##sym));\ hi->key = key;\ hi->value = value;\ hi->next = t->tab[h];\ t->tab[h] = hi;\ }\ \ type \ getHash_##sym(Hash_##sym *t, keytype key, type failval)\ {\ int h;\ HashItem_##sym *hi;\ \ hi = lookupHash_##sym(t,key,&h);\ if (hi == NULL)\ return failval;\ return hi->value;\ } #define defhashfunc_i(keytype,type,sym) \ Hash_##sym * \ newHash_##sym(int size)\ {\ struct Hash_##sym *hash;\ int i;\ \ hash = (Hash_##sym*)GC_malloc(sizeof(Hash_##sym));\ hash->size = size;\ hash->tab = (HashItem_##sym**)GC_malloc(size*sizeof(HashItem_##sym*));\ for (i = 0; i < size; i++)\ hash->tab[i] = NULL;\ return hash;\ }\ \ static HashItem_##sym* \ lookupHash_##sym(Hash_##sym *t, keytype key, int *hashval_return)\ {\ HashItem_##sym *hi;\ \ *hashval_return = key%t->size;\ for (hi = t->tab[*hashval_return]; hi != NULL; hi = hi->next) {\ if (hi->key == key)\ return hi;\ }\ return NULL;\ }\ \ void \ putHash_##sym(Hash_##sym *t, keytype key, type value)\ {\ int h;\ HashItem_##sym *hi;\ \ hi = lookupHash_##sym(t,key,&h);\ if (hi) {\ hi->value = value;\ return;\ }\ \ hi = (HashItem_##sym*)GC_malloc(sizeof(HashItem_##sym));\ hi->key = key;\ hi->value = value;\ hi->next = t->tab[h];\ t->tab[h] = hi;\ }\ \ type \ getHash_##sym(Hash_##sym *t, keytype key, type failval)\ {\ int h;\ HashItem_##sym *hi;\ \ hi = lookupHash_##sym(t,key,&h);\ if (hi == NULL)\ return failval;\ return hi->value;\ } #endif /* not HASH_H */