diff options
Diffstat (limited to 'hash.h')
-rw-r--r-- | hash.h | 141 |
1 files changed, 141 insertions, 0 deletions
@@ -0,0 +1,141 @@ +/* $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 */ |