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