00001 #ifndef BGLIBS__GENERIC_HASH__H__ 00002 #define BGLIBS__GENERIC_HASH__H__ 00003 00004 #include <adt/common.h> 00005 00025 struct ghash 00026 { 00029 void** table; 00031 unsigned count; 00033 unsigned size; 00034 00036 unsigned long keysize; 00038 unsigned long entrysize; 00039 00041 adt_hash_fn* hashfn; 00043 adt_cmp_fn* keycmp; 00045 adt_copy_fn* keycopy; 00047 adt_copy_fn* datacopy; 00049 adt_free_fn* keyfree; 00051 adt_free_fn* datafree; 00052 }; 00053 00055 #define ghash_entry_hash(P) (*(adt_hash_t*)(P)) 00056 00057 #define ghash_entry_keyptr(P) ((P)+sizeof(adt_hash_t)) 00058 00060 #define ghash_entry_dataptr(P,L) ((P)+sizeof(adt_hash_t)+(L)) 00061 00063 #define ghash_hashb adt_hashb 00064 00065 #define ghash_hashs adt_hashs 00066 00067 #define ghash_hashsp adt_hashsp 00068 00069 void ghash_insert(struct ghash* d, void* e); 00070 void* ghash_add(struct ghash* d, const void* key, const void* data); 00071 void* ghash_set(struct ghash* d, const void* key, const void* data); 00072 void ghash_free(struct ghash* d); 00073 void** ghash_find(struct ghash* d, const void* key); 00074 void* ghash_get(struct ghash* d, const void* key); 00075 void ghash_init(struct ghash* d, 00076 unsigned long keysize, 00077 unsigned long entrysize, 00078 adt_hash_fn* hashfn, 00079 adt_cmp_fn* keycmp, 00080 adt_copy_fn* keycopy, 00081 adt_copy_fn* datacopy, 00082 adt_free_fn* keyfree, 00083 adt_free_fn* datafree); 00084 int ghash_rebuild(struct ghash* d); 00085 int ghash_rehash(struct ghash* d); 00086 int ghash_remove(struct ghash* d, const void* key); 00087 void ghash_foreach(struct ghash* d, void (*fn)(void* entry)); 00088 void* ghash_search(struct ghash* d, int (*fn)(const void* entry)); 00089 00092 #define GHASH_STRUCT_ENTRY(PREFIX,KTYPE,DTYPE) \ 00093 struct PREFIX##_entry { \ 00094 adt_hash_t hash; \ 00095 KTYPE key; \ 00096 DTYPE data; \ 00097 } 00098 00100 #define GHASH_KEYOFFSET(PREFIX) ((unsigned long)&((struct PREFIX##_entry*)0)->key) 00101 00102 #define GHASH_DATAOFFSET(PREFIX) ((unsigned long)&((struct PREFIX##_entry*)0)->data) 00103 00104 #define GHASH_KEYSIZE(PREFIX) ( \ 00105 GHASH_DATAOFFSET(PREFIX)-GHASH_KEYOFFSET(PREFIX) \ 00106 ) 00107 00110 #define GHASH_DECL(PREFIX,KTYPE,DTYPE) \ 00111 GHASH_STRUCT_ENTRY(PREFIX,KTYPE,DTYPE); \ 00112 extern void PREFIX##_init(struct ghash* d); \ 00113 extern void PREFIX##_free(struct ghash* d); \ 00114 extern struct PREFIX##_entry* PREFIX##_add(struct ghash* d, \ 00115 KTYPE const* key, \ 00116 DTYPE const* data); \ 00117 extern struct PREFIX##_entry* PREFIX##_set(struct ghash* d, \ 00118 KTYPE const* key, \ 00119 DTYPE const* data); \ 00120 extern struct PREFIX##_entry* PREFIX##_get(struct ghash* d, \ 00121 KTYPE const* key); \ 00122 extern int PREFIX##_rebuild(struct ghash* d); \ 00123 extern int PREFIX##_rehash(struct ghash* d); \ 00124 extern int PREFIX##_remove(struct ghash* d, KTYPE const* key); \ 00125 extern void PREFIX##_foreach(struct ghash* d, \ 00126 void (*fn)(struct PREFIX##_entry*)); \ 00127 extern struct PREFIX##_entry* PREFIX##_search(struct ghash* d, \ 00128 int (*fn)(const struct PREFIX##_entry*)); 00129 00131 #define GHASH_INIT_DEFN(PREFIX,KTYPE,DTYPE,HASHFN,CMP,KCOPY,DCOPY,KFREE,DFREE)\ 00132 void PREFIX##_init(struct ghash* d) { \ 00133 ghash_init(d, \ 00134 GHASH_KEYSIZE(PREFIX), \ 00135 sizeof(struct PREFIX##_entry), \ 00136 (adt_hash_fn*)HASHFN, \ 00137 (adt_cmp_fn*)CMP, \ 00138 (adt_copy_fn*)KCOPY, \ 00139 (adt_copy_fn*)DCOPY, \ 00140 (adt_free_fn*)KFREE, \ 00141 (adt_free_fn*)DFREE); \ 00142 } 00143 00145 #define GHASH_FREE_DEFN(PREFIX) \ 00146 void PREFIX##_free(struct ghash* d) { \ 00147 ghash_free(d); \ 00148 } 00149 00151 #define GHASH_ADD_DEFN(PREFIX,KTYPE,DTYPE) \ 00152 struct PREFIX##_entry* PREFIX##_add(struct ghash* d, \ 00153 KTYPE const* key, DTYPE const* data) { \ 00154 return ghash_add(d, key, data); \ 00155 } 00156 00158 #define GHASH_SET_DEFN(PREFIX,KTYPE,DTYPE) \ 00159 struct PREFIX##_entry* PREFIX##_set(struct ghash* d, \ 00160 KTYPE const* key, DTYPE const* data) { \ 00161 return ghash_set(d, key, data); \ 00162 } 00163 00165 #define GHASH_GET_DEFN(PREFIX,KTYPE) \ 00166 struct PREFIX##_entry* PREFIX##_get(struct ghash* d, KTYPE const* key) { \ 00167 return ghash_get(d, key); \ 00168 } 00169 00171 #define GHASH_REBUILD_DEFN(PREFIX) \ 00172 int PREFIX##_rebuild(struct ghash* d) { \ 00173 return ghash_rebuild(d); \ 00174 } 00175 00177 #define GHASH_REHASH_DEFN(PREFIX) \ 00178 int PREFIX##_rehash(struct ghash* d) { \ 00179 return ghash_rehash(d); \ 00180 } 00181 00183 #define GHASH_REMOVE_DEFN(PREFIX,KTYPE) \ 00184 extern int PREFIX##_remove(struct ghash* d, KTYPE const* key) { \ 00185 return ghash_remove(d, (void*)key); \ 00186 } 00187 00189 #define GHASH_FOREACH_DEFN(PREFIX) \ 00190 void PREFIX##_foreach(struct ghash* d, void (*fn)(struct PREFIX##_entry*)) { \ 00191 ghash_foreach(d, (void (*)(void*))fn); \ 00192 } 00193 00195 #define GHASH_SEARCH_DEFN(PREFIX) \ 00196 struct PREFIX##_entry* PREFIX##_search(struct ghash* d, int (*fn)(const struct PREFIX##_entry*)) { \ 00197 return ghash_search(d, (int (*)(const void*))fn); \ 00198 } 00199 00204 #define GHASH_DEFN(PREFIX,KTYPE,DTYPE,HASHFN,CMPFN,KCOPY,DCOPY,KFREE,DFREE) \ 00205 GHASH_INIT_DEFN(PREFIX,KTYPE,DTYPE,HASHFN,CMPFN,KCOPY,DCOPY,KFREE,DFREE) \ 00206 GHASH_FREE_DEFN(PREFIX) \ 00207 GHASH_ADD_DEFN(PREFIX,KTYPE,DTYPE) \ 00208 GHASH_SET_DEFN(PREFIX,KTYPE,DTYPE) \ 00209 GHASH_GET_DEFN(PREFIX,KTYPE) \ 00210 GHASH_REBUILD_DEFN(PREFIX) \ 00211 GHASH_REHASH_DEFN(PREFIX) \ 00212 GHASH_REMOVE_DEFN(PREFIX,KTYPE) \ 00213 GHASH_FOREACH_DEFN(PREFIX) \ 00214 GHASH_SEARCH_DEFN(PREFIX) 00215 00217 struct ghashiter 00218 { 00220 const struct ghash* ghashp; 00222 unsigned index; 00224 void* entry; 00225 }; 00226 00227 void ghashiter_first(struct ghashiter*, const struct ghash*); 00228 int ghashiter_valid(const struct ghashiter*); 00229 void ghashiter_next(struct ghashiter*); 00232 #define ghashiter_loop(I,G) \ 00233 for(ghashiter_first(I,G);ghashiter_valid(I);ghashiter_next(I)) 00234 00237 #endif