142 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			142 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* $Id: hash.h,v 1.4 2001/12/10 17:02:44 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 */
 |