00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef _HASH_H
00020 #define _HASH_H
00021
00022 #include <stdlib.h>
00023
00029 #define HASH_SIZE 137
00030
00031 typedef struct _htab_entry_struct *htab_entry_t;
00032
00033 typedef struct _htab_iterator *htab_iterator_t;
00034
00035 typedef struct _hashtab_t* hashtab_t;
00036
00037 typedef void* hash_elem;
00038 typedef void* hash_key;
00039
00040 typedef word_t (*hash_func)(hash_key);
00041 typedef int (*compare_func)(hash_key,hash_key);
00042
00043 struct _htab_entry_struct {
00044 hash_key key;
00045 hash_elem e;
00046 htab_entry_t next;
00047 word_t __pad;
00048 };
00049
00050
00051
00052 struct _hashtab_t {
00053 htab_entry_t table[HASH_SIZE];
00054 hash_func hash;
00055 compare_func keycmp;
00056 };
00057
00058
00059 #define HASH_NOVAL ((hash_elem)0)
00060
00061
00062 word_t default_hash_func(const char*);
00063
00064 word_t hash_str(char*);
00065
00066 word_t hash_ptr(void*);
00067 int cmp_ptr(void*,void*);
00068
00074 struct _htab_iterator {
00075 hashtab_t tab;
00076 word_t row;
00077 struct _htab_entry_struct*entry;
00078 };
00079
00081 static __inline int hi_incr(htab_iterator_t hi) {
00082 if(hi->entry&&hi->entry->next)
00083 hi->entry=hi->entry->next;
00084 do {
00085 ++hi->row;
00086 if(hi->row>=HASH_SIZE) {
00087 hi->entry=NULL;
00088 return 0;
00089 }
00090 } while(!hi->tab->table[hi->row]);
00091 hi->entry = hi->tab->table[hi->row];
00092 return 1;
00093 }
00094
00095
00097 static __inline void hi_init(htab_iterator_t hi,hashtab_t t) {
00098 hi->tab=t;
00099 hi->row=(word_t)-1;
00100 hi->entry=NULL;
00101 hi_incr(hi);
00102 }
00103
00104
00106 static __inline int hi_is_valid(htab_iterator_t hi) { return hi->entry!=NULL; }
00107
00109 static __inline hash_key hi_key(htab_iterator_t hi) { return hi->entry->key; }
00110
00112 static __inline hash_elem hi_value(htab_iterator_t hi) { return hi->entry->e; }
00113
00115 static __inline htab_entry_t hi_entry(htab_iterator_t hi) { return hi->entry; }
00116
00127 static __inline void init_hashtab(hashtab_t tab,hash_func hash,compare_func cmp) {
00128 int i;
00129 for(i=0;i<HASH_SIZE;i++)
00130 tab->table[i]=(htab_entry_t) HASH_NOVAL;
00131 tab->hash=hash;
00132 tab->keycmp=cmp;
00133 }
00134
00135
00136
00138 static __inline void hash_addelem(hashtab_t tab,hash_key key,hash_elem elem) {
00139 word_t i=tab->hash(key);
00140
00141
00142 htab_entry_t e=(htab_entry_t)malloc(sizeof(struct _htab_entry_struct));
00143
00144 if(!e) return;
00145 e->next=tab->table[i];
00146 e->key=key;
00147 e->e=elem;
00148 tab->table[i]=e;
00149 }
00150
00151
00152
00154 static __inline htab_entry_t hash_find_e(hashtab_t tab,hash_key key) {
00155 int i=tab->hash(key);
00156 htab_entry_t s=tab->table[i];
00157
00158 if(s) while(tab->keycmp(s->key,key)&&(s=s->next));
00159 return s;
00160 }
00161
00163 static __inline hash_elem hash_find(hashtab_t tab,hash_key key) {
00164 htab_entry_t s;
00165
00166 s=hash_find_e(tab,key);
00167 if(s) return s->e;
00168 return HASH_NOVAL;
00169 }
00170
00171
00173 static __inline void hash_delelem(hashtab_t tab,hash_key key) {
00174 htab_entry_t p=NULL;
00175 word_t i=tab->hash(key);
00176
00177 htab_entry_t s=tab->table[i];
00178 while(s&&tab->keycmp(s->key,key)) {
00179 p=s;
00180 s=s->next;
00181 }
00182 if(s) {
00183 if(p) p->next=s->next;
00184 else tab->table[i]=s->next;
00185
00186 free(s);
00187 }
00188 }
00189
00191 static __inline void clean_hashtab(hashtab_t tab,void(*callback)(htab_entry_t)) {
00192 int i;
00193 htab_entry_t s,p;
00194 for(i=0;i<HASH_SIZE;i++) {
00195 s=tab->table[i];
00196 while(s) {
00197 p=s;
00198 s=s->next;
00199
00200 if(callback) callback(p);
00201 free(p);
00202 }
00203 tab->table[i]=(htab_entry_t)HASH_NOVAL;
00204 }
00205 }
00206
00209 #endif
00210