Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
n_hash.h
Go to the documentation of this file.
1
8#ifndef NILOREA_HASH_HEADER_GUARD
9#define NILOREA_HASH_HEADER_GUARD
10
11#ifdef __cplusplus
12extern "C" {
13#endif
14
20#if defined( __linux__ ) || defined( _AIX ) || defined( __sun )
21#include <arpa/inet.h>
22#include <string.h>
23#else
24#include <string.h>
25#endif
26
27#include <stdint.h>
28
29#include "n_common.h"
30#include "n_list.h"
31
32 //#if defined(_MSC_VER)
33 //#include <stdlib.h>
35 //#define ROTL32(x,y) _rotl(x,y)
37 //#define ROTL64(x,y) _rotl64(x,y)
39 //#define BIG_CONSTANT(x) (x)
40 //#else
42 //#define ROTL32(x,y) rotl32(x,y)
44 //#define ROTL64(x,y) rotl64(x,y)
46 //#define BIG_CONSTANT(x) (x##LLU)
47 //#endif /* if defined MSVC ... */
48
50#define HASH_INT 1
52#define HASH_DOUBLE 2
54#define HASH_STRING 4
56#define HASH_PTR 8
58#define HASH_UNKNOWN 16
60#define HASH_CLASSIC 128
62#define HASH_TRIE 256
63
65 typedef size_t HASH_VALUE ;
66
69 {
71 int ival ;
73 double fval ;
75 void *ptr ;
77 char *string ;
78 };
79
81 typedef struct HASH_NODE
82 {
84 char *key ;
86 char key_id ;
90 int type ;
94 void (*destroy_func)( void *ptr );
96 int is_leaf ;
103 } HASH_NODE ;
104
105
107 typedef struct HASH_TABLE
108 {
110 size_t size;
112 size_t nb_keys ;
114 size_t seed ;
124 unsigned int mode ;
126 HASH_NODE *(*ht_get_node)( struct HASH_TABLE *table, const char *key );
128 int (*ht_put_int)( struct HASH_TABLE *table, const char *key, int val );
130 int (*ht_put_double)( struct HASH_TABLE *table, const char *key, double val );
132 int (*ht_put_ptr)( struct HASH_TABLE *table, const char *key, void *ptr, void (*destructor)( void *ptr ) );
134 int (*ht_put_string)( struct HASH_TABLE *table, const char *key, char *val );
136 int (*ht_put_string_ptr)( struct HASH_TABLE *table, const char *key, char *val );
138 int (*ht_get_int)( struct HASH_TABLE *table, const char *key, int *val );
140 int (*ht_get_double)( struct HASH_TABLE *table, const char *key, double *val );
142 int (*ht_get_ptr)( struct HASH_TABLE *table, const char *key, void **val );
144 int (*ht_get_string)( struct HASH_TABLE *table, const char *key, char **val );
146 int (*ht_remove)( struct HASH_TABLE *table, const char *key );
148 LIST *(*ht_search)( struct HASH_TABLE *table, int (*node_is_matching)( HASH_NODE *node ) );
150 int (*empty_ht)( struct HASH_TABLE *table );
152 int (*destroy_ht)( struct HASH_TABLE **table );
154 void (*ht_print)( struct HASH_TABLE *table );
155 } HASH_TABLE ;
156
158#define hash_val( node , type )\
159 ( (node && node -> ptr) ? ( (type *)( ( (HASH_NODE *)node -> ptr )-> data . ptr) ) : NULL )
160
162#define ht_foreach( __ITEM_ , __HASH_ ) \
163 if( !__HASH_ ) \
164 { \
165 n_log( LOG_ERR , "Error in ht_foreach, %s is NULL" , #__HASH_ ); \
166 } \
167 else if( __HASH_ -> mode != HASH_CLASSIC ) \
168 { \
169 n_log( LOG_ERR , "Error in ht_foreach( %s , %s ) unsupportted mode %d" , #__ITEM_ , #__HASH_ , __HASH_ -> mode ); \
170 } \
171 else \
172 for( size_t __hash_it = 0 ; __hash_it < __HASH_ -> size ; __hash_it ++ ) \
173 for( LIST_NODE *__ITEM_ = __HASH_ -> hash_table[ __hash_it ] -> start ; __ITEM_ != NULL; __ITEM_ = __ITEM_ -> next )
174
176#define ht_foreach_r( __ITEM_ , __HASH_ , __ITERATOR_ ) \
177 if( !__HASH_ ) \
178 { \
179 n_log( LOG_ERR , "Error in ht_foreach, %s is NULL" , #__HASH_ ); \
180 } \
181 else if( __HASH_ -> mode != HASH_CLASSIC ) \
182 { \
183 n_log( LOG_ERR , "Error in ht_foreach, %d is an unsupported mode" , __HASH_ -> mode ); \
184 } \
185 else \
186 for( size_t __ITERATOR_ = 0 ; __ITERATOR_ < __HASH_ -> size ; __ITERATOR_ ++ ) \
187 for( LIST_NODE *__ITEM_ = __HASH_ -> hash_table[ __ITERATOR_ ] -> start ; __ITEM_ != NULL; __ITEM_ = __ITEM_ -> next )
188
190#define HASH_VAL( node , type )\
191 ( (node && node -> data . ptr) ? ( (type *)node -> data . ptr ) : NULL )
192
194#define HT_FOREACH( __ITEM_ , __HASH_ , ... ) \
195 { \
196 do \
197 { \
198 if( !__HASH_ ) \
199 { \
200 n_log( LOG_ERR , "Error in ht_foreach, %s is NULL" , #__HASH_ ); \
201 } \
202 else \
203 { \
204 if( __HASH_ -> mode == HASH_CLASSIC ) \
205 { \
206 int CONCAT(__ht_node_trie_func_macro_break_flag_classic,__LINE__) = 0 ; \
207 for( size_t __hash_it = 0 ; __hash_it < __HASH_ -> size ; __hash_it ++ ) \
208 { \
209 for( LIST_NODE *__ht_list_node = __HASH_ -> hash_table[ __hash_it ] -> start ; __ht_list_node != NULL; __ht_list_node = __ht_list_node -> next ) \
210 { \
211 HASH_NODE *__ITEM_ = (HASH_NODE *)__ht_list_node -> ptr ; \
212 CONCAT(__ht_node_trie_func_macro_break_flag_classic,__LINE__) = 1 ; \
213 __VA_ARGS__ \
214 CONCAT(__ht_node_trie_func_macro_break_flag_classic,__LINE__) = 0 ; \
215 } \
216 if( CONCAT(__ht_node_trie_func_macro_break_flag_classic,__LINE__) == 1 ) \
217 break ; \
218 } \
219 } \
220 else if( __HASH_ -> mode == HASH_TRIE ) \
221 { \
222 int CONCAT(__ht_node_trie_func_macro,__LINE__)( HASH_NODE *__ITEM_ ) \
223 { \
224 if( !__ITEM_ ) return TRUE ; \
225 int CONCAT(__ht_node_trie_func_macro_break_flag,__LINE__) = 1 ; \
226 if( __ITEM_ -> is_leaf ) \
227 { \
228 do \
229 { \
230 __VA_ARGS__ \
231 CONCAT(__ht_node_trie_func_macro_break_flag,__LINE__) = 0 ; \
232 }while ( 0 ); \
233 } \
234 if( CONCAT(__ht_node_trie_func_macro_break_flag,__LINE__) == 1 ) return FALSE ; \
235 for( size_t it = 0 ; it < __ITEM_ -> alphabet_length ; it++ ) \
236 { \
237 if( CONCAT(__ht_node_trie_func_macro,__LINE__)( __ITEM_ -> children[ it ] ) == FALSE ) \
238 return FALSE ; \
239 } \
240 return TRUE ; \
241 } \
242 CONCAT(__ht_node_trie_func_macro,__LINE__)( __HASH_ -> root ); \
243 } \
244 else \
245 { \
246 n_log( LOG_ERR , "Error in ht_foreach, %d is an unsupported mode" , __HASH_ -> mode ); \
247 break ; \
248 } \
249 } \
250 }while( 0 ); \
251 }
252
254#define HT_FOREACH_R( __ITEM_ , __HASH_ , __ITERATOR , ... ) \
255 { \
256 do \
257 { \
258 if( !__HASH_ ) \
259 { \
260 n_log( LOG_ERR , "Error in ht_foreach, %s is NULL" , #__HASH_ ); \
261 } \
262 else \
263 { \
264 if( __HASH_ -> mode == HASH_CLASSIC ) \
265 { \
266 int CONCAT(__ht_node_trie_func_macro_break_flag_classic,__LINE__) = 0 ; \
267 for( size_t __ITERATOR = 0 ; __ITERATOR < __HASH_ -> size ; __ITERATOR ++ ) \
268 { \
269 for( LIST_NODE *__ht_list_node = __HASH_ -> hash_table[ __ITERATOR ] -> start ; __ht_list_node != NULL; __ht_list_node = __ht_list_node -> next ) \
270 { \
271 HASH_NODE *__ITEM_ = (HASH_NODE *)__ht_list_node -> ptr ; \
272 CONCAT(__ht_node_trie_func_macro_break_flag_classic,__LINE__) = 1 ; \
273 __VA_ARGS__ \
274 CONCAT(__ht_node_trie_func_macro_break_flag_classic,__LINE__) = 0 ; \
275 } \
276 if( CONCAT(__ht_node_trie_func_macro_break_flag_classic,__LINE__) == 1 ) \
277 break ; \
278 } \
279 } \
280 else if( __HASH_ -> mode == HASH_TRIE ) \
281 { \
282 int CONCAT(__ht_node_trie_func_macro,__LINE__)( HASH_NODE *__ITEM_ ) \
283 { \
284 if( !__ITEM_ ) return TRUE ; \
285 int CONCAT(__ht_node_trie_func_macro_break_flag,__LINE__) = 1 ; \
286 if( __ITEM_ -> is_leaf ) \
287 { \
288 do \
289 { \
290 __VA_ARGS__ \
291 CONCAT(__ht_node_trie_func_macro_break_flag,__LINE__) = 0 ; \
292 }while ( 0 ); \
293 } \
294 if( CONCAT(__ht_node_trie_func_macro_break_flag,__LINE__) == 1 ) return FALSE ; \
295 for( size_t it = 0 ; it < __ITEM_ -> alphabet_length ; it++ ) \
296 { \
297 if( CONCAT(__ht_node_trie_func_macro,__LINE__)( __ITEM_ -> children[ it ] ) == FALSE ) \
298 return FALSE ; \
299 } \
300 return TRUE ; \
301 } \
302 CONCAT(__ht_node_trie_func_macro,__LINE__)( __HASH_ -> root ); \
303 } \
304 else \
305 { \
306 n_log( LOG_ERR , "Error in ht_foreach, %d is an unsupported mode" , __HASH_ -> mode ); \
307 break ; \
308 } \
309 } \
310 }while( 0 ); \
311 }
312
313 void MurmurHash3_x86_32 ( const void * key, int len, uint32_t seed, void * out );
314 void MurmurHash3_x86_128 ( const void * key, int len, uint32_t seed, void * out );
315 void MurmurHash3_x64_128 ( const void * key, const size_t len, const uint64_t seed, void * out );
316#ifdef ENV_32BITS
318#define MurmurHash( __key , __len , __seed , __out ) MurmurHash3_x86_128( __key, __len, __seed, __out )
319#else
321#define MurmurHash( __key , __len , __seed , __out ) MurmurHash3_x64_128( __key, __len, __seed, __out )
322#endif
323
324
325
326 char *ht_node_type( HASH_NODE *node );
327 HASH_NODE *ht_get_node( HASH_TABLE *table, const char *key );
328
329 HASH_TABLE *new_ht( size_t size );
330 HASH_TABLE *new_ht_trie( size_t alphabet_size, size_t alphabet_offset );
331
332 int ht_get_double( HASH_TABLE *table, const char *key, double *val );
333 int ht_get_int( HASH_TABLE *table, const char *key, int *val );
334 int ht_get_ptr( HASH_TABLE *table, const char *key, void **val );
335 int ht_get_string( HASH_TABLE *table, const char *key, char **val );
336 int ht_put_double( HASH_TABLE *table, const char *key, double value );
337 int ht_put_int( HASH_TABLE *table, const char *key, int value );
338 int ht_put_ptr( HASH_TABLE *table, const char *key, void *ptr, void (*destructor)(void *ptr ) );
339 int ht_put_string( HASH_TABLE *table, const char *key, char *string );
340 int ht_put_string_ptr( HASH_TABLE *table, const char *key, char *string );
341 int ht_remove( HASH_TABLE *table, const char *key );
342 void ht_print( HASH_TABLE *table );
343 LIST *ht_search( HASH_TABLE *table, int (*node_is_matching)( HASH_NODE *node ) );
344 int empty_ht( HASH_TABLE *table );
345 int destroy_ht( HASH_TABLE **table );
346
347 HASH_NODE *ht_get_node_ex( HASH_TABLE *table, HASH_VALUE hash_value );
348 int ht_put_ptr_ex( HASH_TABLE *table, HASH_VALUE hash_value, void *val, void (*destructor)( void *ptr ) );
349 int ht_get_ptr_ex( HASH_TABLE *table, HASH_VALUE hash_value, void **val );
350 int ht_remove_ex( HASH_TABLE *table, HASH_VALUE hash_value );
351
352 LIST *ht_get_completion_list( HASH_TABLE *table, const char *keybud, size_t max_results );
353
354 int is_prime( int nb );
355 int next_prime( int nb );
356
358 int ht_get_optimal_size( HASH_TABLE *table );
359 int ht_resize( HASH_TABLE **table, size_t size );
360 int ht_optimize( HASH_TABLE **table );
361
366#ifdef __cplusplus
367}
368#endif
369
370#endif // header guard
371
size_t alphabet_length
HASH_TRIE mode: size of alphabet and so size of children allocated array.
Definition n_hash.h:102
int need_rehash
flag to mark a node for rehash
Definition n_hash.h:98
char key_id
key id of the node if any
Definition n_hash.h:86
int(* ht_get_string)(struct HASH_TABLE *table, const char *key, char **val)
get a char *string from a key's node
Definition n_hash.h:144
int(* ht_put_string)(struct HASH_TABLE *table, const char *key, char *val)
put an char *string
Definition n_hash.h:134
char * key
string key of the node if any, else NULL
Definition n_hash.h:84
int is_leaf
HASH_TRIE mode: does it have a value.
Definition n_hash.h:96
HASH_NODE * root
HASH_TRIE mode: Start of tree.
Definition n_hash.h:118
void * ptr
pointer type
Definition n_hash.h:75
union HASH_DATA data
data inside the node
Definition n_hash.h:92
int(* ht_get_ptr)(struct HASH_TABLE *table, const char *key, void **val)
get a pointer from a key's node
Definition n_hash.h:142
int type
type of the node
Definition n_hash.h:90
int(* empty_ht)(struct HASH_TABLE *table)
empty a hash table.
Definition n_hash.h:150
LIST ** hash_table
HASH_CLASSIC mode: preallocated hash table.
Definition n_hash.h:116
int(* ht_put_int)(struct HASH_TABLE *table, const char *key, int val)
put an integer
Definition n_hash.h:128
size_t alphabet_offset
HASH_TRIE mode: offset to deduce to individual key digits.
Definition n_hash.h:122
int(* ht_get_double)(struct HASH_TABLE *table, const char *key, double *val)
get a double from a key's node
Definition n_hash.h:140
size_t alphabet_length
HASH_TRIE mode: size of the alphabet.
Definition n_hash.h:120
unsigned int mode
hashing mode, murmurhash and classic HASH_MURMUR, or HASH_TRIE
Definition n_hash.h:124
size_t seed
table's seed
Definition n_hash.h:114
int(* destroy_ht)(struct HASH_TABLE **table)
destroy a hash table
Definition n_hash.h:152
int(* ht_put_string_ptr)(struct HASH_TABLE *table, const char *key, char *val)
put an char *string pointer
Definition n_hash.h:136
int(* ht_remove)(struct HASH_TABLE *table, const char *key)
remove given's key node from the table
Definition n_hash.h:146
void(* ht_print)(struct HASH_TABLE *table)
print table
Definition n_hash.h:154
char * string
char *type
Definition n_hash.h:77
int ival
integral type
Definition n_hash.h:71
int(* ht_put_double)(struct HASH_TABLE *table, const char *key, double val)
put a double
Definition n_hash.h:130
struct HASH_NODE ** children
HASH_TRIE mode: pointers to children.
Definition n_hash.h:100
HASH_VALUE hash_value
numeric key of the node if any, else < 0
Definition n_hash.h:88
double fval
double type
Definition n_hash.h:73
size_t size
size of the hash table
Definition n_hash.h:110
int(* ht_put_ptr)(struct HASH_TABLE *table, const char *key, void *ptr, void(*destructor)(void *ptr))
put a a pointer
Definition n_hash.h:132
size_t nb_keys
total number of used keys in the table
Definition n_hash.h:112
void(* destroy_func)(void *ptr)
destroy_func
Definition n_hash.h:94
int(* ht_get_int)(struct HASH_TABLE *table, const char *key, int *val)
get an int from a key's node
Definition n_hash.h:138
int ht_get_ptr(HASH_TABLE *table, const char *key, void **val)
get pointer at 'key' from 'table'
Definition n_hash.c:2283
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)
Definition n_hash.c:2527
int ht_get_int(HASH_TABLE *table, const char *key, int *val)
get node at 'key' from 'table'
Definition n_hash.c:2267
char * ht_node_type(HASH_NODE *node)
get the type of a node , text version
Definition n_hash.c:1423
LIST * ht_search(HASH_TABLE *table, int(*node_is_matching)(HASH_NODE *node))
seach table for matching nodes
Definition n_hash.c:2423
int destroy_ht(HASH_TABLE **table)
empty a table and destroy it
Definition n_hash.c:2449
int ht_remove(HASH_TABLE *table, const char *key)
remove and delete node at key in table
Definition n_hash.c:2395
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)
Definition n_hash.c:2463
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.
Definition n_hash.c:1048
HASH_TABLE * new_ht(size_t size)
Create a hash table with the given size.
Definition n_hash.c:2168
int ht_get_table_collision_percentage(HASH_TABLE *table)
get table collision percentage (HASH_CLASSIC mode only)
Definition n_hash.c:2739
int ht_get_double(HASH_TABLE *table, const char *key, double *val)
get double at 'key' from 'table'
Definition n_hash.c:2251
int next_prime(int nb)
compute next prime number after nb
Definition n_hash.c:2716
int empty_ht(HASH_TABLE *table)
empty a table
Definition n_hash.c:2436
int is_prime(int nb)
test if number is a prime number or not
Definition n_hash.c:2691
void ht_print(HASH_TABLE *table)
print contents of table
Definition n_hash.c:2408
LIST * ht_get_completion_list(HASH_TABLE *table, const char *keybud, size_t max_results)
get next matching keys in table tree
Definition n_hash.c:2631
size_t HASH_VALUE
type of a HASH_VALUE
Definition n_hash.h:65
int ht_put_double(HASH_TABLE *table, const char *key, double value)
put a double value with given key in the targeted hash table
Definition n_hash.c:2315
int ht_get_string(HASH_TABLE *table, const char *key, char **val)
get string at 'key' from 'table'
Definition n_hash.c:2299
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
Definition n_hash.c:2364
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.
Definition n_hash.c:1118
int ht_resize(HASH_TABLE **table, size_t size)
rehash table according to size (HASH_CLASSIC mode only)
Definition n_hash.c:2786
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.
Definition n_hash.c:1295
int ht_remove_ex(HASH_TABLE *table, HASH_VALUE hash_value)
Remove a key from a hash table (HASH_CLASSIC only)
Definition n_hash.c:2583
HASH_NODE * ht_get_node(HASH_TABLE *table, const char *key)
get node at 'key' from 'table'
Definition n_hash.c:2235
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
Definition n_hash.c:2124
int ht_put_int(HASH_TABLE *table, const char *key, int value)
put an integral value with given key in the targeted hash table
Definition n_hash.c:2331
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
Definition n_hash.c:2348
int ht_optimize(HASH_TABLE **table)
try an automatic optimization of the table
Definition n_hash.c:2882
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
Definition n_hash.c:2380
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...
Definition n_hash.c:2766
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.
Definition n_hash.c:2497
structure of a hash table node
Definition n_hash.h:82
structure of a hash table
Definition n_hash.h:108
union of the possibles data values of a node
Definition n_hash.h:69
Structure of a generic LIST container.
Definition n_list.h:45
Common headers and low-level hugly functions & define.
List structures and definitions.