9#ifndef NILOREA_HASH_HEADER_GUARD
10#define NILOREA_HASH_HEADER_GUARD
21#if defined(__linux__) || defined(_AIX) || defined(__sun)
59#define HASH_UNKNOWN 16
61#define HASH_CLASSIC 128
67#define MurmurHash(__key, __len, __seed, __out) MurmurHash3_x86_128(__key, __len, __seed, __out)
69#define HASH_INT_TYPE int32_t
72#define MurmurHash(__key, __len, __seed, __out) MurmurHash3_x64_128(__key, __len, __seed, __out)
74#define HASH_INT_TYPE int64_t
167#define hash_val(node, type) \
168 ((node && node->ptr) ? ((type*)(((HASH_NODE*)node->ptr)->data.ptr)) : NULL)
171#define ht_foreach(__ITEM_, __HASH_) \
173 n_log(LOG_ERR, "Error in ht_foreach, %s is NULL", #__HASH_); \
174 } else if (__HASH_->mode != HASH_CLASSIC) { \
175 n_log(LOG_ERR, "Error in ht_foreach( %s , %s ) unsupportted mode %d", #__ITEM_, #__HASH_, __HASH_->mode); \
177 for (size_t __hash_it = 0; __hash_it < __HASH_->size; __hash_it++) \
178 for (LIST_NODE* __ITEM_ = __HASH_->hash_table[__hash_it]->start; __ITEM_ != NULL; __ITEM_ = __ITEM_->next)
181#define ht_foreach_r(__ITEM_, __HASH_, __ITERATOR_) \
183 n_log(LOG_ERR, "Error in ht_foreach, %s is NULL", #__HASH_); \
184 } else if (__HASH_->mode != HASH_CLASSIC) { \
185 n_log(LOG_ERR, "Error in ht_foreach, %d is an unsupported mode", __HASH_->mode); \
187 for (size_t __ITERATOR_ = 0; __ITERATOR_ < __HASH_->size; __ITERATOR_++) \
188 for (LIST_NODE* __ITEM_ = __HASH_->hash_table[__ITERATOR_]->start; __ITEM_ != NULL; __ITEM_ = __ITEM_->next)
191#define HASH_VAL(node, type) \
192 ((node && node->data.ptr) ? ((type*)node->data.ptr) : NULL)
195#define HT_FOREACH(__ITEM_, __HASH_, ...) \
199 n_log(LOG_ERR, "Error in ht_foreach, %s is NULL", #__HASH_); \
201 if (__HASH_->mode == HASH_CLASSIC) { \
202 int CONCAT(__ht_node_trie_func_macro_break_flag_classic, __LINE__) = 0; \
203 for (size_t __hash_it = 0; __hash_it < __HASH_->size; __hash_it++) { \
204 for (LIST_NODE* __ht_list_node = __HASH_->hash_table[__hash_it]->start; __ht_list_node != NULL; __ht_list_node = __ht_list_node->next) { \
205 HASH_NODE* __ITEM_ = (HASH_NODE*)__ht_list_node->ptr; \
206 CONCAT(__ht_node_trie_func_macro_break_flag_classic, __LINE__) = 1; \
208 CONCAT(__ht_node_trie_func_macro_break_flag_classic, __LINE__) = 0; \
210 if (CONCAT(__ht_node_trie_func_macro_break_flag_classic, __LINE__) == 1) \
213 } else if (__HASH_->mode == HASH_TRIE) { \
214 int CONCAT(__ht_node_trie_func_macro, __LINE__)(HASH_NODE * __ITEM_) { \
215 if (!__ITEM_) return TRUE; \
216 int CONCAT(__ht_node_trie_func_macro_break_flag, __LINE__) = 1; \
217 if (__ITEM_->is_leaf) { \
220 CONCAT(__ht_node_trie_func_macro_break_flag, __LINE__) = 0; \
223 if (CONCAT(__ht_node_trie_func_macro_break_flag, __LINE__) == 1) return FALSE; \
224 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__)++) { \
225 if (CONCAT(__ht_node_trie_func_macro, __LINE__)(__ITEM_->children[CONCAT(__ht_node_trie_func_it, __LINE__)]) == FALSE) \
230 CONCAT(__ht_node_trie_func_macro, __LINE__) \
233 n_log(LOG_ERR, "Error in ht_foreach, %d is an unsupported mode", __HASH_->mode); \
241#define HT_FOREACH_R(__ITEM_, __HASH_, __ITERATOR, ...) \
245 n_log(LOG_ERR, "Error in ht_foreach, %s is NULL", #__HASH_); \
247 if (__HASH_->mode == HASH_CLASSIC) { \
248 int CONCAT(__ht_node_trie_func_macro_break_flag_classic, __LINE__) = 0; \
249 LIST_NODE* CONCAT(__ht_list_node_r, __LINE__) = NULL; \
250 for (size_t __ITERATOR = 0; __ITERATOR < __HASH_->size; __ITERATOR++) { \
251 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) { \
252 HASH_NODE* __ITEM_ = (HASH_NODE*)CONCAT(__ht_list_node_r, __LINE__)->ptr; \
253 CONCAT(__ht_node_trie_func_macro_break_flag_classic, __LINE__) = 1; \
255 CONCAT(__ht_node_trie_func_macro_break_flag_classic, __LINE__) = 0; \
257 if (CONCAT(__ht_node_trie_func_macro_break_flag_classic, __LINE__) == 1) \
260 } else if (__HASH_->mode == HASH_TRIE) { \
261 int CONCAT(__ht_node_trie_func_macro, __LINE__)(HASH_NODE * __ITEM_) { \
262 if (!__ITEM_) return TRUE; \
263 int CONCAT(__ht_node_trie_func_macro_break_flag, __LINE__) = 1; \
264 if (__ITEM_->is_leaf) { \
267 CONCAT(__ht_node_trie_func_macro_break_flag, __LINE__) = 0; \
270 if (CONCAT(__ht_node_trie_func_macro_break_flag, __LINE__) == 1) return FALSE; \
271 for (size_t it = 0; it < __ITEM_->alphabet_length; it++) { \
272 if (CONCAT(__ht_node_trie_func_macro, __LINE__)(__ITEM_->children[it]) == FALSE) \
277 CONCAT(__ht_node_trie_func_macro, __LINE__) \
280 n_log(LOG_ERR, "Error in ht_foreach, %d is an unsupported mode", __HASH_->mode); \
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 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_put_ptr)(struct HASH_TABLE *table, const char *key, void *ptr, void(*destructor)(void *ptr))
put a a pointer
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 pointer at 'key' from 'table'
int ht_put_ptr_ex(HASH_TABLE *table, HASH_VALUE hash_value, void *val, void(*destructor)(void *ptr))
put a pointer value with given key in the targeted hash table (HASH_CLASSIC only)
char * ht_node_type(HASH_NODE *node)
get the type of a node , text version
LIST * ht_search(HASH_TABLE *table, int(*node_is_matching)(HASH_NODE *node))
seach table for matching nodes
int destroy_ht(HASH_TABLE **table)
empty a table and destroy it
int ht_remove(HASH_TABLE *table, const char *key)
remove and delete node at key in table
HASH_NODE * ht_get_node_ex(HASH_TABLE *table, HASH_VALUE hash_value)
return the associated key's node inside the hash_table (HASH_CLASSIC only)
HASH_TABLE * new_ht(size_t size)
Create a hash table with the given size.
int ht_get_table_collision_percentage(HASH_TABLE *table)
get table collision percentage (HASH_CLASSIC mode only)
int ht_get_double(HASH_TABLE *table, const char *key, double *val)
get double at 'key' from 'table'
int empty_ht(HASH_TABLE *table)
empty a table
void ht_print(HASH_TABLE *table)
print contents of table
LIST * ht_get_completion_list(HASH_TABLE *table, const char *keybud, size_t max_results)
get next matching keys in table tree
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 with given key in the targeted hash table
size_t ht_get_optimal_size(HASH_TABLE *table)
get optimal array size based on nb=(number_of_key*1.3) && if( !isprime(nb) )nb=nextprime(nb) (HASH_CL...
int ht_get_string(HASH_TABLE *table, const char *key, char **val)
get string at 'key' from 'table'
int is_prime(size_t nb)
test if number is a prime number or not
#define HASH_INT_TYPE
type of a HASH_INT in 64 bits
size_t next_prime(size_t nb)
compute next prime number after nb
int ht_put_string(HASH_TABLE *table, const char *key, char *string)
put a string value (copy/dup) with given key in the targeted hash table
int ht_resize(HASH_TABLE **table, size_t size)
rehash table according to size (HASH_CLASSIC mode only)
void MurmurHash3_x86_128(const void *key, const size_t len, const uint32_t seed, void *out)
MurmurHash3 was written by Austin Appleby, and is placed in the public domain.
void MurmurHash3_x64_128(const void *key, const size_t len, const uint64_t seed, void *out)
MurmurHash3 was written by Austin Appleby, and is placed in the public domain.
int ht_remove_ex(HASH_TABLE *table, HASH_VALUE hash_value)
Remove a key from a hash table (HASH_CLASSIC only)
int ht_get_int(HASH_TABLE *table, const char *key, int64_t *val)
get node at 'key' from 'table'
HASH_NODE * ht_get_node(HASH_TABLE *table, const char *key)
get node at 'key' from 'table'
HASH_TABLE * new_ht_trie(size_t alphabet_size, size_t alphabet_offset)
create a TRIE hash table with the alphabet_size, each key value beeing decreased by alphabet_offset
int ht_put_ptr(HASH_TABLE *table, const char *key, void *ptr, void(*destructor)(void *ptr))
put a pointer to the string value with given key in the targeted hash table
int ht_put_int(HASH_TABLE *table, const char *key, int64_t value)
put an integral value with given key in the targeted hash table
int ht_optimize(HASH_TABLE **table)
try an automatic optimization of the table
void MurmurHash3_x86_32(const void *key, const size_t len, const uint32_t seed, void *out)
MurmurHash3 was written by Austin Appleby, and is placed in the public domain.
int ht_put_string_ptr(HASH_TABLE *table, const char *key, char *string)
put a string value (pointer) with given key in the targeted hash table
int ht_get_ptr_ex(HASH_TABLE *table, HASH_VALUE hash_value, void **val)
Retrieve a pointer value in the hash table, at the given key.
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.