27#ifndef NILOREA_HASH_HEADER_GUARD
28#define NILOREA_HASH_HEADER_GUARD
39#if defined(__linux__) || defined(_AIX) || defined(__sun)
77#define HASH_UNKNOWN 16
79#define HASH_CLASSIC 128
85#define MurmurHash(__key, __len, __seed, __out) MurmurHash3_x86_128(__key, __len, __seed, __out)
87#define HASH_INT_TYPE int32_t
90#define MurmurHash(__key, __len, __seed, __out) MurmurHash3_x64_128(__key, __len, __seed, __out)
92#define HASH_INT_TYPE int64_t
125 void* (*duplicate_func)(
void* ptr);
161 int (*
ht_put_ptr)(
struct HASH_TABLE* table,
const char*
key,
void* ptr, void (*destructor)(
void* ptr),
void* (*duplicator)(
void* ptr));
187#define hash_val(node, type) \
188 ((node && node->ptr) ? ((type*)(((HASH_NODE*)node->ptr)->data.ptr)) : NULL)
191#define ht_foreach(__ITEM_, __HASH_) \
193 n_log(LOG_ERR, "Error in ht_foreach, %s is NULL", #__HASH_); \
194 } else if (__HASH_->mode != HASH_CLASSIC) { \
195 n_log(LOG_ERR, "Error in ht_foreach( %s , %s ) unsupportted mode %d", #__ITEM_, #__HASH_, __HASH_->mode); \
197 for (size_t __hash_it = 0; __hash_it < __HASH_->size; __hash_it++) \
198 for (LIST_NODE* __ITEM_ = __HASH_->hash_table[__hash_it]->start; __ITEM_ != NULL; __ITEM_ = __ITEM_->next)
201#define ht_foreach_r(__ITEM_, __HASH_, __ITERATOR_) \
203 n_log(LOG_ERR, "Error in ht_foreach, %s is NULL", #__HASH_); \
204 } else if (__HASH_->mode != HASH_CLASSIC) { \
205 n_log(LOG_ERR, "Error in ht_foreach, %d is an unsupported mode", __HASH_->mode); \
207 for (size_t __ITERATOR_ = 0; __ITERATOR_ < __HASH_->size; __ITERATOR_++) \
208 for (LIST_NODE* __ITEM_ = __HASH_->hash_table[__ITERATOR_]->start; __ITEM_ != NULL; __ITEM_ = __ITEM_->next)
211#define HASH_VAL(node, type) \
212 ((node && node->data.ptr) ? ((type*)node->data.ptr) : NULL)
215#define HT_FOREACH(__ITEM_, __HASH_, ...) \
219 n_log(LOG_ERR, "Error in ht_foreach, %s is NULL", #__HASH_); \
221 if (__HASH_->mode == HASH_CLASSIC) { \
222 int CONCAT(__ht_node_trie_func_macro_break_flag_classic, __LINE__) = 0; \
223 for (size_t __hash_it = 0; __hash_it < __HASH_->size; __hash_it++) { \
224 for (LIST_NODE* __ht_list_node = __HASH_->hash_table[__hash_it]->start; __ht_list_node != NULL; __ht_list_node = __ht_list_node->next) { \
225 HASH_NODE* __ITEM_ = (HASH_NODE*)__ht_list_node->ptr; \
226 CONCAT(__ht_node_trie_func_macro_break_flag_classic, __LINE__) = 1; \
228 CONCAT(__ht_node_trie_func_macro_break_flag_classic, __LINE__) = 0; \
230 if (CONCAT(__ht_node_trie_func_macro_break_flag_classic, __LINE__) == 1) \
233 } else if (__HASH_->mode == HASH_TRIE) { \
234 int CONCAT(__ht_node_trie_func_macro, __LINE__)(HASH_NODE * __ITEM_) { \
235 if (!__ITEM_) return TRUE; \
236 int CONCAT(__ht_node_trie_func_macro_break_flag, __LINE__) = 1; \
237 if (__ITEM_->is_leaf) { \
240 CONCAT(__ht_node_trie_func_macro_break_flag, __LINE__) = 0; \
243 if (CONCAT(__ht_node_trie_func_macro_break_flag, __LINE__) == 1) return FALSE; \
244 for (size_t CONCAT(__ht_node_trie_func_it, __LINE__) = 0; CONCAT(__ht_node_trie_func_it, __LINE__) < __ITEM_->alphabet_length; CONCAT(__ht_node_trie_func_it, __LINE__)++) { \
245 if (CONCAT(__ht_node_trie_func_macro, __LINE__)(__ITEM_->children[CONCAT(__ht_node_trie_func_it, __LINE__)]) == FALSE) \
250 CONCAT(__ht_node_trie_func_macro, __LINE__) \
253 n_log(LOG_ERR, "Error in ht_foreach, %d is an unsupported mode", __HASH_->mode); \
261#define HT_FOREACH_R(__ITEM_, __HASH_, __ITERATOR, ...) \
265 n_log(LOG_ERR, "Error in ht_foreach, %s is NULL", #__HASH_); \
267 if (__HASH_->mode == HASH_CLASSIC) { \
268 int CONCAT(__ht_node_trie_func_macro_break_flag_classic, __LINE__) = 0; \
269 LIST_NODE* CONCAT(__ht_list_node_r, __LINE__) = NULL; \
270 for (size_t __ITERATOR = 0; __ITERATOR < __HASH_->size; __ITERATOR++) { \
271 for (CONCAT(__ht_list_node_r, __LINE__) = __HASH_->hash_table[__ITERATOR]->start; CONCAT(__ht_list_node_r, __LINE__) != NULL; CONCAT(__ht_list_node_r, __LINE__) = CONCAT(__ht_list_node_r, __LINE__)->next) { \
272 HASH_NODE* __ITEM_ = (HASH_NODE*)CONCAT(__ht_list_node_r, __LINE__)->ptr; \
273 CONCAT(__ht_node_trie_func_macro_break_flag_classic, __LINE__) = 1; \
275 CONCAT(__ht_node_trie_func_macro_break_flag_classic, __LINE__) = 0; \
277 if (CONCAT(__ht_node_trie_func_macro_break_flag_classic, __LINE__) == 1) \
280 } else if (__HASH_->mode == HASH_TRIE) { \
281 int CONCAT(__ht_node_trie_func_macro, __LINE__)(HASH_NODE * __ITEM_) { \
282 if (!__ITEM_) return TRUE; \
283 int CONCAT(__ht_node_trie_func_macro_break_flag, __LINE__) = 1; \
284 if (__ITEM_->is_leaf) { \
287 CONCAT(__ht_node_trie_func_macro_break_flag, __LINE__) = 0; \
290 if (CONCAT(__ht_node_trie_func_macro_break_flag, __LINE__) == 1) return FALSE; \
291 for (size_t it = 0; it < __ITEM_->alphabet_length; it++) { \
292 if (CONCAT(__ht_node_trie_func_macro, __LINE__)(__ITEM_->children[it]) == FALSE) \
297 CONCAT(__ht_node_trie_func_macro, __LINE__) \
300 n_log(LOG_ERR, "Error in ht_foreach, %d is an unsupported mode", __HASH_->mode); \
338int ht_put_ptr(
HASH_TABLE* table,
const char*
key,
void* ptr,
void (*destructor)(
void* ptr),
void* (*duplicator)(
void* ptr));
static size_t max_results
int(* ht_put_int)(struct HASH_TABLE *table, const char *key, int64_t val)
put an integer
size_t alphabet_length
HASH_TRIE mode: size of alphabet and so size of children allocated array.
int need_rehash
flag to mark a node for rehash
char key_id
key id of the node if any
int(* ht_get_string)(struct HASH_TABLE *table, const char *key, char **val)
get a char *string from a key's node
int(* ht_put_string)(struct HASH_TABLE *table, const char *key, char *val)
put an char *string
char * key
string key of the node if any, else NULL
int64_t ival
integral type
int(* ht_put_ptr)(struct HASH_TABLE *table, const char *key, void *ptr, void(*destructor)(void *ptr), void *(*duplicator)(void *ptr))
put a a pointer
int is_leaf
HASH_TRIE mode: does it have a value.
HASH_NODE * root
HASH_TRIE mode: Start of tree.
union HASH_DATA data
data inside the node
int(* ht_get_ptr)(struct HASH_TABLE *table, const char *key, void **val)
get a pointer from a key's node
int(* empty_ht)(struct HASH_TABLE *table)
empty a hash table.
LIST ** hash_table
HASH_CLASSIC mode: preallocated hash table.
size_t alphabet_offset
HASH_TRIE mode: offset to deduce to individual key digits.
int(* ht_get_double)(struct HASH_TABLE *table, const char *key, double *val)
get a double from a key's node
size_t alphabet_length
HASH_TRIE mode: size of the alphabet.
unsigned int mode
hashing mode, murmurhash and classic HASH_MURMUR, or HASH_TRIE
int(* destroy_ht)(struct HASH_TABLE **table)
destroy a hash table
int(* ht_put_string_ptr)(struct HASH_TABLE *table, const char *key, char *val)
put an char *string pointer
int(* ht_remove)(struct HASH_TABLE *table, const char *key)
remove given's key node from the table
void(* ht_print)(struct HASH_TABLE *table)
print table
int(* ht_put_double)(struct HASH_TABLE *table, const char *key, double val)
put a double
struct HASH_NODE ** children
HASH_TRIE mode: pointers to children.
HASH_VALUE hash_value
numeric key of the node if any, else < 0
size_t size
size of the hash table
int(* ht_get_int)(struct HASH_TABLE *table, const char *key, int64_t *val)
get an int from a key's node
size_t nb_keys
total number of used keys in the table
void(* destroy_func)(void *ptr)
destroy_func
int ht_get_ptr(HASH_TABLE *table, const char *key, void **val)
get a pointer value from the hash table by key
LIST * ht_search(HASH_TABLE *table, int(*node_is_matching)(HASH_NODE *node))
search the hash table for nodes matching a predicate
HASH_TABLE * ht_duplicate(HASH_TABLE *table)
duplicate a hash table
int destroy_ht(HASH_TABLE **table)
destroy a hash table and free all resources
int ht_put_ptr_ex(HASH_TABLE *table, HASH_VALUE hash_value, void *val, void(*destructor)(void *ptr), void *(*duplicator)(void *ptr))
put a pointer value by numeric hash value
int ht_remove(HASH_TABLE *table, const char *key)
remove a node from the hash table by key
HASH_NODE * ht_get_node_ex(HASH_TABLE *table, HASH_VALUE hash_value)
get a HASH_NODE by numeric hash value
HASH_TABLE * new_ht(size_t size)
create a new classic hash table of the given size
int ht_get_table_collision_percentage(HASH_TABLE *table)
get the collision percentage of the hash table
int ht_get_double(HASH_TABLE *table, const char *key, double *val)
get a double value from the hash table by key
int empty_ht(HASH_TABLE *table)
empty a hash table, freeing all nodes
void ht_print(HASH_TABLE *table)
print the contents of a hash table
LIST * ht_get_completion_list(HASH_TABLE *table, const char *keybud, size_t max_results)
get a list of key completions matching the given prefix
size_t HASH_VALUE
type of a HASH_VALUE
int ht_put_double(HASH_TABLE *table, const char *key, double value)
put a double value into the hash table
size_t ht_get_optimal_size(HASH_TABLE *table)
compute the optimal size for the hash table
int ht_put_ptr(HASH_TABLE *table, const char *key, void *ptr, void(*destructor)(void *ptr), void *(*duplicator)(void *ptr))
put a pointer value into the hash table with destructor and duplicator
int ht_get_string(HASH_TABLE *table, const char *key, char **val)
get a string value from the hash table by key
int is_prime(size_t nb)
check if a number is prime
#define HASH_INT_TYPE
type of a HASH_INT in 64 bits
size_t next_prime(size_t nb)
return the next prime number greater than or equal to nb
int ht_put_string(HASH_TABLE *table, const char *key, char *string)
put a string value (duplicated) into the hash table
int ht_resize(HASH_TABLE **table, size_t size)
resize a hash table to the given size
void MurmurHash3_x86_128(const void *key, const size_t len, const uint32_t seed, void *out)
compute a 128-bit MurmurHash3 hash for x86
void MurmurHash3_x64_128(const void *key, const size_t len, const uint64_t seed, void *out)
compute a 128-bit MurmurHash3 hash for x64
int ht_remove_ex(HASH_TABLE *table, HASH_VALUE hash_value)
remove a node by numeric hash value
int ht_get_int(HASH_TABLE *table, const char *key, int64_t *val)
get an integer value from the hash table by key
HASH_NODE * ht_get_node(HASH_TABLE *table, const char *key)
get the HASH_NODE associated with the given key
HASH_TABLE * new_ht_trie(size_t alphabet_size, size_t alphabet_offset)
create a new trie hash table with the given alphabet size and offset
int ht_put_int(HASH_TABLE *table, const char *key, int64_t value)
put an integer value into the hash table
int ht_optimize(HASH_TABLE **table)
optimize a hash table by resizing to the optimal size
char * ht_node_type(const HASH_NODE *node)
return the type of a hash node as a string
void MurmurHash3_x86_32(const void *key, const size_t len, const uint32_t seed, void *out)
compute a 32-bit MurmurHash3 hash
int ht_put_string_ptr(HASH_TABLE *table, const char *key, char *string)
put a string pointer into the hash table without copying
int ht_get_ptr_ex(HASH_TABLE *table, HASH_VALUE hash_value, void **val)
get a pointer value by numeric hash value
structure of a hash table node
structure of a hash table
union of the possibles data values of a node
Structure of a generic LIST container.
Common headers and low-level functions & define.
List structures and definitions.