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
159#define hash_val( node , type )\
160 ( (node && node -> ptr) ? ( (type *)( ( (HASH_NODE *)node -> ptr )-> data . ptr) ) : NULL )
163#define ht_foreach( __ITEM_ , __HASH_ ) \
166 n_log( LOG_ERR , "Error in ht_foreach, %s is NULL" , #__HASH_ ); \
168 else if( __HASH_ -> mode != HASH_CLASSIC ) \
170 n_log( LOG_ERR , "Error in ht_foreach( %s , %s ) unsupportted mode %d" , #__ITEM_ , #__HASH_ , __HASH_ -> mode ); \
173 for( size_t __hash_it = 0 ; __hash_it < __HASH_ -> size ; __hash_it ++ ) \
174 for( LIST_NODE *__ITEM_ = __HASH_ -> hash_table[ __hash_it ] -> start ; __ITEM_ != NULL; __ITEM_ = __ITEM_ -> next )
177#define ht_foreach_r( __ITEM_ , __HASH_ , __ITERATOR_ ) \
180 n_log( LOG_ERR , "Error in ht_foreach, %s is NULL" , #__HASH_ ); \
182 else if( __HASH_ -> mode != HASH_CLASSIC ) \
184 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_ , ... ) \
201 n_log( LOG_ERR , "Error in ht_foreach, %s is NULL" , #__HASH_ ); \
205 if( __HASH_ -> mode == HASH_CLASSIC ) \
207 int CONCAT(__ht_node_trie_func_macro_break_flag_classic,__LINE__) = 0 ; \
208 for( size_t __hash_it = 0 ; __hash_it < __HASH_ -> size ; __hash_it ++ ) \
210 for( LIST_NODE *__ht_list_node = __HASH_ -> hash_table[ __hash_it ] -> start ; __ht_list_node != NULL; __ht_list_node = __ht_list_node -> next ) \
212 HASH_NODE *__ITEM_ = (HASH_NODE *)__ht_list_node -> ptr ; \
213 CONCAT(__ht_node_trie_func_macro_break_flag_classic,__LINE__) = 1 ; \
215 CONCAT(__ht_node_trie_func_macro_break_flag_classic,__LINE__) = 0 ; \
217 if( CONCAT(__ht_node_trie_func_macro_break_flag_classic,__LINE__) == 1 ) \
221 else if( __HASH_ -> mode == HASH_TRIE ) \
223 int CONCAT(__ht_node_trie_func_macro,__LINE__)( HASH_NODE *__ITEM_ ) \
225 if( !__ITEM_ ) return TRUE ; \
226 int CONCAT(__ht_node_trie_func_macro_break_flag,__LINE__) = 1 ; \
227 if( __ITEM_ -> is_leaf ) \
232 CONCAT(__ht_node_trie_func_macro_break_flag,__LINE__) = 0 ; \
235 if( CONCAT(__ht_node_trie_func_macro_break_flag,__LINE__) == 1 ) return FALSE ; \
236 for( size_t it = 0 ; it < __ITEM_ -> alphabet_length ; it++ ) \
238 if( CONCAT(__ht_node_trie_func_macro,__LINE__)( __ITEM_ -> children[ it ] ) == FALSE ) \
243 CONCAT(__ht_node_trie_func_macro,__LINE__)( __HASH_ -> root ); \
247 n_log( LOG_ERR , "Error in ht_foreach, %d is an unsupported mode" , __HASH_ -> mode ); \
255#define HT_FOREACH_R( __ITEM_ , __HASH_ , __ITERATOR , ... ) \
261 n_log( LOG_ERR , "Error in ht_foreach, %s is NULL" , #__HASH_ ); \
265 if( __HASH_ -> mode == HASH_CLASSIC ) \
267 int CONCAT(__ht_node_trie_func_macro_break_flag_classic,__LINE__) = 0 ; \
268 for( size_t __ITERATOR = 0 ; __ITERATOR < __HASH_ -> size ; __ITERATOR ++ ) \
270 for( LIST_NODE *__ht_list_node = __HASH_ -> hash_table[ __ITERATOR ] -> start ; __ht_list_node != NULL; __ht_list_node = __ht_list_node -> next ) \
272 HASH_NODE *__ITEM_ = (HASH_NODE *)__ht_list_node -> 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 ) \
281 else if( __HASH_ -> mode == HASH_TRIE ) \
283 int CONCAT(__ht_node_trie_func_macro,__LINE__)( HASH_NODE *__ITEM_ ) \
285 if( !__ITEM_ ) return TRUE ; \
286 int CONCAT(__ht_node_trie_func_macro_break_flag,__LINE__) = 1 ; \
287 if( __ITEM_ -> is_leaf ) \
292 CONCAT(__ht_node_trie_func_macro_break_flag,__LINE__) = 0 ; \
295 if( CONCAT(__ht_node_trie_func_macro_break_flag,__LINE__) == 1 ) return FALSE ; \
296 for( size_t it = 0 ; it < __ITEM_ -> alphabet_length ; it++ ) \
298 if( CONCAT(__ht_node_trie_func_macro,__LINE__)( __ITEM_ -> children[ it ] ) == FALSE ) \
303 CONCAT(__ht_node_trie_func_macro,__LINE__)( __HASH_ -> root ); \
307 n_log( LOG_ERR , "Error in ht_foreach, %d is an unsupported mode" , __HASH_ -> mode ); \
319#define MurmurHash( __key , __len , __seed , __out ) MurmurHash3_x86_128( __key, __len, __seed, __out )
322#define MurmurHash( __key , __len , __seed , __out ) MurmurHash3_x64_128( __key, __len, __seed, __out )
339 int ht_put_ptr(
HASH_TABLE *table,
const char *key,
void *ptr,
void (*destructor)(
void *ptr ) );
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
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.
int(* ht_put_int)(struct HASH_TABLE *table, const char *key, int val)
put an integer
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
size_t nb_keys
total number of used keys in the table
void(* destroy_func)(void *ptr)
destroy_func
int(* ht_get_int)(struct HASH_TABLE *table, const char *key, int *val)
get an int from a key's node
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)
int ht_get_int(HASH_TABLE *table, const char *key, int *val)
get node at 'key' from 'table'
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)
void MurmurHash3_x86_32(const void *key, int len, uint32_t seed, void *out)
MurmurHash3 was written by Austin Appleby, and is placed in the public domain.
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 next_prime(int nb)
compute next prime number after nb
int empty_ht(HASH_TABLE *table)
empty a table
int is_prime(int nb)
test if number is a prime number or not
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
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
void MurmurHash3_x86_128(const void *key, int len, uint32_t seed, void *out)
MurmurHash3 was written by Austin Appleby, and is placed in the public domain.
int ht_resize(HASH_TABLE **table, size_t size)
rehash table according to size (HASH_CLASSIC mode only)
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_int(HASH_TABLE *table, const char *key, int value)
put an integral value with given key in the targeted hash table
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
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_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_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 hugly functions & define.
List structures and definitions.