8#ifndef NILOREA_HASH_HEADER_GUARD
9#define NILOREA_HASH_HEADER_GUARD
20#if defined(__linux__) || defined(_AIX) || defined(__sun)
58#define HASH_UNKNOWN 16
60#define HASH_CLASSIC 128
66#define MurmurHash(__key, __len, __seed, __out) MurmurHash3_x86_128(__key, __len, __seed, __out)
67#define HASH_INT_TYPE int32_t
70#define MurmurHash(__key, __len, __seed, __out) MurmurHash3_x64_128(__key, __len, __seed, __out)
71#define HASH_INT_TYPE int64_t
164#define hash_val(node, type) \
165 ((node && node->ptr) ? ((type*)(((HASH_NODE*)node->ptr)->data.ptr)) : NULL)
168#define ht_foreach(__ITEM_, __HASH_) \
170 n_log(LOG_ERR, "Error in ht_foreach, %s is NULL", #__HASH_); \
171 } else if (__HASH_->mode != HASH_CLASSIC) { \
172 n_log(LOG_ERR, "Error in ht_foreach( %s , %s ) unsupportted mode %d", #__ITEM_, #__HASH_, __HASH_->mode); \
174 for (size_t __hash_it = 0; __hash_it < __HASH_->size; __hash_it++) \
175 for (LIST_NODE* __ITEM_ = __HASH_->hash_table[__hash_it]->start; __ITEM_ != NULL; __ITEM_ = __ITEM_->next)
178#define ht_foreach_r(__ITEM_, __HASH_, __ITERATOR_) \
180 n_log(LOG_ERR, "Error in ht_foreach, %s is NULL", #__HASH_); \
181 } else if (__HASH_->mode != HASH_CLASSIC) { \
182 n_log(LOG_ERR, "Error in ht_foreach, %d is an unsupported mode", __HASH_->mode); \
184 for (size_t __ITERATOR_ = 0; __ITERATOR_ < __HASH_->size; __ITERATOR_++) \
185 for (LIST_NODE* __ITEM_ = __HASH_->hash_table[__ITERATOR_]->start; __ITEM_ != NULL; __ITEM_ = __ITEM_->next)
188#define HASH_VAL(node, type) \
189 ((node && node->data.ptr) ? ((type*)node->data.ptr) : NULL)
192#define HT_FOREACH(__ITEM_, __HASH_, ...) \
196 n_log(LOG_ERR, "Error in ht_foreach, %s is NULL", #__HASH_); \
198 if (__HASH_->mode == HASH_CLASSIC) { \
199 int CONCAT(__ht_node_trie_func_macro_break_flag_classic, __LINE__) = 0; \
200 for (size_t __hash_it = 0; __hash_it < __HASH_->size; __hash_it++) { \
201 for (LIST_NODE* __ht_list_node = __HASH_->hash_table[__hash_it]->start; __ht_list_node != NULL; __ht_list_node = __ht_list_node->next) { \
202 HASH_NODE* __ITEM_ = (HASH_NODE*)__ht_list_node->ptr; \
203 CONCAT(__ht_node_trie_func_macro_break_flag_classic, __LINE__) = 1; \
205 CONCAT(__ht_node_trie_func_macro_break_flag_classic, __LINE__) = 0; \
207 if (CONCAT(__ht_node_trie_func_macro_break_flag_classic, __LINE__) == 1) \
210 } else if (__HASH_->mode == HASH_TRIE) { \
211 int CONCAT(__ht_node_trie_func_macro, __LINE__)(HASH_NODE * __ITEM_) { \
212 if (!__ITEM_) return TRUE; \
213 int CONCAT(__ht_node_trie_func_macro_break_flag, __LINE__) = 1; \
214 if (__ITEM_->is_leaf) { \
217 CONCAT(__ht_node_trie_func_macro_break_flag, __LINE__) = 0; \
220 if (CONCAT(__ht_node_trie_func_macro_break_flag, __LINE__) == 1) return FALSE; \
221 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__)++) { \
222 if (CONCAT(__ht_node_trie_func_macro, __LINE__)(__ITEM_->children[CONCAT(__ht_node_trie_func_it, __LINE__)]) == FALSE) \
227 CONCAT(__ht_node_trie_func_macro, __LINE__) \
230 n_log(LOG_ERR, "Error in ht_foreach, %d is an unsupported mode", __HASH_->mode); \
238#define HT_FOREACH_R(__ITEM_, __HASH_, __ITERATOR, ...) \
242 n_log(LOG_ERR, "Error in ht_foreach, %s is NULL", #__HASH_); \
244 if (__HASH_->mode == HASH_CLASSIC) { \
245 int CONCAT(__ht_node_trie_func_macro_break_flag_classic, __LINE__) = 0; \
246 LIST_NODE* CONCAT(__ht_list_node_r, __LINE__) = NULL; \
247 for (size_t __ITERATOR = 0; __ITERATOR < __HASH_->size; __ITERATOR++) { \
248 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) { \
249 HASH_NODE* __ITEM_ = (HASH_NODE*)CONCAT(__ht_list_node_r, __LINE__)->ptr; \
250 CONCAT(__ht_node_trie_func_macro_break_flag_classic, __LINE__) = 1; \
252 CONCAT(__ht_node_trie_func_macro_break_flag_classic, __LINE__) = 0; \
254 if (CONCAT(__ht_node_trie_func_macro_break_flag_classic, __LINE__) == 1) \
257 } else if (__HASH_->mode == HASH_TRIE) { \
258 int CONCAT(__ht_node_trie_func_macro, __LINE__)(HASH_NODE * __ITEM_) { \
259 if (!__ITEM_) return TRUE; \
260 int CONCAT(__ht_node_trie_func_macro_break_flag, __LINE__) = 1; \
261 if (__ITEM_->is_leaf) { \
264 CONCAT(__ht_node_trie_func_macro_break_flag, __LINE__) = 0; \
267 if (CONCAT(__ht_node_trie_func_macro_break_flag, __LINE__) == 1) return FALSE; \
268 for (size_t it = 0; it < __ITEM_->alphabet_length; it++) { \
269 if (CONCAT(__ht_node_trie_func_macro, __LINE__)(__ITEM_->children[it]) == FALSE) \
274 CONCAT(__ht_node_trie_func_macro, __LINE__) \
277 n_log(LOG_ERR, "Error in ht_foreach, %d is an unsupported mode", __HASH_->mode); \
317int is_prime(
size_t nb);
318size_t next_prime(
size_t nb);
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 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)
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_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.