00001
00002 #ifndef BGLIBS__GENERIC_HASH__H__
00003 #define BGLIBS__GENERIC_HASH__H__
00004
00005 #include <adt/common.h>
00006
00026 struct ghash
00027 {
00030 void** table;
00032 unsigned count;
00034 unsigned size;
00035
00037 unsigned long keysize;
00039 unsigned long entrysize;
00040
00042 adt_hash_fn* hashfn;
00044 adt_cmp_fn* keycmp;
00046 adt_copy_fn* keycopy;
00048 adt_copy_fn* datacopy;
00050 adt_free_fn* keyfree;
00052 adt_free_fn* datafree;
00053 };
00054
00056 #define ghash_entry_hash(P) (*(adt_hash_t*)(P))
00057
00058 #define ghash_entry_keyptr(P) ((P)+sizeof(adt_hash_t))
00059
00061 #define ghash_entry_dataptr(P,L) ((P)+sizeof(adt_hash_t)+(L))
00062
00064 #define ghash_hashb adt_hashb
00065
00066 #define ghash_hashs adt_hashs
00067
00068 #define ghash_hashsp adt_hashsp
00069
00070 void ghash_insert(struct ghash* d, void* e);
00071 void* ghash_add(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)&((struct PREFIX##_entry*)0)->key)
00101
00102 #define GHASH_DATAOFFSET(PREFIX) ((unsigned)&((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##_get(struct ghash* d, \
00118 KTYPE const* key); \
00119 extern int PREFIX##_rebuild(struct ghash* d); \
00120 extern int PREFIX##_rehash(struct ghash* d); \
00121 extern int PREFIX##_remove(struct ghash* d, KTYPE const* key); \
00122 extern void PREFIX##_foreach(struct ghash* d, \
00123 void (*fn)(struct PREFIX##_entry*)); \
00124 extern struct PREFIX##_entry* PREFIX##_search(struct ghash* d, \
00125 int (*fn)(const struct PREFIX##_entry*));
00126
00128 #define GHASH_INIT_DEFN(PREFIX,KTYPE,DTYPE,HASHFN,CMP,KCOPY,DCOPY,KFREE,DFREE)\
00129 void PREFIX##_init(struct ghash* d) { \
00130 ghash_init(d, \
00131 GHASH_KEYSIZE(PREFIX), \
00132 sizeof(struct PREFIX##_entry), \
00133 (adt_hash_fn*)HASHFN, \
00134 (adt_cmp_fn*)CMP, \
00135 (adt_copy_fn*)KCOPY, \
00136 (adt_copy_fn*)DCOPY, \
00137 (adt_free_fn*)KFREE, \
00138 (adt_free_fn*)DFREE); \
00139 }
00140
00142 #define GHASH_FREE_DEFN(PREFIX) \
00143 void PREFIX##_free(struct ghash* d) { \
00144 ghash_free(d); \
00145 }
00146
00148 #define GHASH_ADD_DEFN(PREFIX,KTYPE,DTYPE) \
00149 struct PREFIX##_entry* PREFIX##_add(struct ghash* d, \
00150 KTYPE const* key, DTYPE const* data) { \
00151 return ghash_add(d, key, data); \
00152 }
00153
00155 #define GHASH_GET_DEFN(PREFIX,KTYPE) \
00156 struct PREFIX##_entry* PREFIX##_get(struct ghash* d, KTYPE const* key) { \
00157 return ghash_get(d, key); \
00158 }
00159
00161 #define GHASH_REBUILD_DEFN(PREFIX) \
00162 int PREFIX##_rebuild(struct ghash* d) { \
00163 return ghash_rebuild(d); \
00164 }
00165
00167 #define GHASH_REHASH_DEFN(PREFIX) \
00168 int PREFIX##_rehash(struct ghash* d) { \
00169 return ghash_rehash(d); \
00170 }
00171
00173 #define GHASH_REMOVE_DEFN(PREFIX,KTYPE) \
00174 extern int PREFIX##_remove(struct ghash* d, KTYPE const* key) { \
00175 return ghash_remove(d, (void*)key); \
00176 }
00177
00179 #define GHASH_FOREACH_DEFN(PREFIX) \
00180 void PREFIX##_foreach(struct ghash* d, void (*fn)(struct PREFIX##_entry*)) { \
00181 ghash_foreach(d, (void (*)(void*))fn); \
00182 }
00183
00185 #define GHASH_SEARCH_DEFN(PREFIX) \
00186 struct PREFIX##_entry* PREFIX##_search(struct ghash* d, int (*fn)(const struct PREFIX##_entry*)) { \
00187 return ghash_search(d, (int (*)(const void*))fn); \
00188 }
00189
00194 #define GHASH_DEFN(PREFIX,KTYPE,DTYPE,HASHFN,CMPFN,KCOPY,DCOPY,KFREE,DFREE) \
00195 GHASH_INIT_DEFN(PREFIX,KTYPE,DTYPE,HASHFN,CMPFN,KCOPY,DCOPY,KFREE,DFREE) \
00196 GHASH_FREE_DEFN(PREFIX) \
00197 GHASH_ADD_DEFN(PREFIX,KTYPE,DTYPE) \
00198 GHASH_GET_DEFN(PREFIX,KTYPE) \
00199 GHASH_REBUILD_DEFN(PREFIX) \
00200 GHASH_REHASH_DEFN(PREFIX) \
00201 GHASH_REMOVE_DEFN(PREFIX,KTYPE) \
00202 GHASH_FOREACH_DEFN(PREFIX) \
00203 GHASH_SEARCH_DEFN(PREFIX)
00204
00206 struct ghashiter
00207 {
00209 const struct ghash* ghashp;
00211 unsigned index;
00213 void* entry;
00214 };
00215
00216 void ghashiter_first(struct ghashiter*, const struct ghash*);
00217 int ghashiter_valid(const struct ghashiter*);
00218 void ghashiter_next(struct ghashiter*);
00221 #define ghashiter_loop(I,G) \
00222 for(ghashiter_first(I,G);ghashiter_valid(I);ghashiter_next(I))
00223
00226 #endif