/* $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 */