/* hash.h */ #ifndef __hash_h #define __hash_h #include "buffer.h" typedef struct _hash_slot hash_slot; /* A key in the hash. The key data follows it * inline. */ struct _hash_slot { long link; /* Offset of next link in chain */ size_t key_len; /* Length of key (key data is inline after this) */ void *v; /* Value pointer */ }; struct _hash; typedef int ( *hash_cb_kc ) ( struct _hash * h, void *d, const char *k, void *v ); /* A hash */ typedef struct _hash { buffer buf; /* Buffer for keys */ long *slot; /* Array of buckets */ long cap; /* Size of bucket array */ long state; /* Incremented every time the hash's state changes so that we * can spot the case where an iterator gets out of sync with * the hash it's iterating over. */ size_t size; size_t deleted; /* Optional callbacks for value addition, deletion */ void *cbd; int ( *cb_add ) ( struct _hash * h, void *d, void **v ); int ( *cb_del ) ( struct _hash * h, void *d, void *v ); int ( *cb_upd ) ( struct _hash * h, void *d, void *ov, void **nv ); } hash; typedef struct { long state; long bucket; long sl; } hash_iter; extern void *hash_NULL; #define hash_PUTNULL(p) ((p) ? (p) : hash_NULL) #define hash_GETNULL(p) ((p) == hash_NULL ? NULL : p) int hash_new( long capacity, hash ** hh ); int hash_set_callbacks( hash * h, void *cbd, int ( *cb_add ) ( hash * h, void *d, void **v ), int ( *cb_del ) ( hash * h, void *d, void *v ), int ( *cb_upd ) ( struct _hash * h, void *d, void *ov, void **nv ) ); int hash_delete( hash * h ); int hash_put( hash * h, const void *key, size_t key_len, void *val ); int hash_delete_key( hash * h, const void *key, size_t key_len ); void *hash_get( hash * h, const void *key, size_t key_len ); size_t hash_size( hash * h ); const void *hash_get_first_key( hash * h, hash_iter * i, size_t * key_len ); const void *hash_get_next_key( hash * h, hash_iter * i, size_t * key_len ); #endif /* __hash_h */