38 new_hash_node->
key = NULL;
71 for (
size_t it = 0;
key[it]; it++) {
74 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it,
key);
129 size_t last_index = 0;
130 for (
size_t it = 0;
key[it] !=
'\0'; it++) {
133 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it,
key);
139 if (it2 != (
unsigned)index && node->
children[it2]) {
162 size_t len = strlen(
key);
165 char* longest_prefix = NULL;
166 Malloc(longest_prefix,
char, len + 1);
168 memcpy(longest_prefix,
key, len);
172 if (branch_index > 0 && branch_index != SIZE_MAX) {
174 longest_prefix[branch_index - 1] =
'\0';
175 Realloc(longest_prefix,
char, (branch_index + 1));
176 if (!longest_prefix) {
177 n_log(
LOG_ERR,
"reallocation error, stopping find longest prefix");
182 return longest_prefix;
204 if (longest_prefix && longest_prefix[0] ==
'\0') {
205 Free(longest_prefix);
210 for (it = 0; longest_prefix[it] !=
'\0'; it++) {
213 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it,
key);
216 if (node->
children[index] != NULL) {
221 Free(longest_prefix);
227 for (;
key[it] !=
'\0'; it++) {
230 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it,
key);
240 Free(longest_prefix);
260 for (
size_t it = 0;
key[it] !=
'\0'; it++) {
263 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it,
key);
267 if (node->
children[index] == NULL) {
309 for (
size_t it = 0;
key[it] !=
'\0'; it++) {
312 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it,
key);
315 if (node->
children[index] == NULL) {
357 for (
size_t it = 0;
key[it] !=
'\0'; it++) {
360 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it,
key);
363 if (node->
children[index] == NULL) {
417 for (
size_t it = 0;
key[it] !=
'\0'; it++) {
420 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it,
key);
423 if (node->
children[index] == NULL) {
466 for (
size_t it = 0;
key[it] !=
'\0'; it++) {
469 n_log(
LOG_ERR,
"Invalid value %u for charater at position %d of %s, set to 0", index, it,
key);
472 if (node->
children[index] == NULL) {
509 if (
key[0] !=
'\0') {
511 for (
size_t it = 0;
key[it] !=
'\0'; it++) {
514 n_log(
LOG_DEBUG,
"Invalid value %d for charater at index %d of %s, set to 0", index, it,
key);
517 if (node->
children[index] == NULL) {
539 if (strlen(
key) == 0)
567 if (strlen(
key) == 0)
595 if (strlen(
key) == 0)
623 if (strlen(
key) == 0)
682 printf(
"key: %s, val: ", node->
key);
683 switch (node->
type) {
685 printf(
"int: %ld", (
long)node->
data.
ival);
688 printf(
"double: %f", node->
data.
fval);
691 printf(
"ptr: %p", node->
data.
ptr);
697 printf(
"unknwow type %d", node->
type);
733 if (node_is_matching(node) == TRUE) {
788#define ROTL64(x, r) (((x) << (r)) | ((x) >> (64 - (r))))
790#define ROTL32(x, r) (((x) << (r)) | ((x) >> (32 - (r))))
792#define BIG_CONSTANT(x) (x##LLU)
795#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__)
796#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
797#define BYTESWAP32(x) (x)
798#define BYTESWAP64(x) (x)
801#elif defined(__i386) || defined(__x86_64) || defined(__alpha) || defined(__vax)
803#define BYTESWAP32(x) (x)
804#define BYTESWAP64(x) (x)
806#elif defined(__GNUC__) || defined(__clang__)
808#if __has_builtin(__builtin_bswap32)
809#define BYTESWAP32(x) __builtin_bswap32(x)
811#if __has_builtin(__builtin_bswap64)
812#define BYTESWAP64(x) __builtin_bswap64(x)
819#define BYTESWAP32(x) ((((x) & 0xFF) << 24) | (((x) >> 24) & 0xFF) | (((x) & 0x0000FF00) << 8) | (((x) & 0x00FF0000) >> 8))
823#define BYTESWAP64(x) \
824 (((uint64_t)(x) << 56) | \
825 (((uint64_t)(x) << 40) & 0X00FF000000000000ULL) | \
826 (((uint64_t)(x) << 24) & 0X0000FF0000000000ULL) | \
827 (((uint64_t)(x) << 8) & 0X000000FF00000000ULL) | \
828 (((uint64_t)(x) >> 8) & 0X00000000FF000000ULL) | \
829 (((uint64_t)(x) >> 24) & 0X0000000000FF0000ULL) | \
830 (((uint64_t)(x) >> 40) & 0X000000000000FF00ULL) | \
831 ((uint64_t)(x) >> 56))
842 memcpy(&result, (
const uint8_t*)p + i * 4,
sizeof(result));
854 memcpy(&result, (
const uint8_t*)p + i * 8,
sizeof(result));
902 const uint8_t* data = (
const uint8_t*)
key;
903 const size_t nblocks = len / 4;
906 const uint32_t c1 = 0xcc9e2d51;
907 const uint32_t c2 = 0x1b873593;
909 const uint32_t* blocks = (
const uint32_t*)data;
911 for (
size_t i = 0; i < nblocks; i++) {
919 h1 = h1 * 5 + 0xe6546b64;
922 const uint8_t* tail = data + nblocks * 4;
926 k1 ^= (uint32_t)tail[2] << 16;
929 k1 ^= (uint32_t)tail[1] << 8;
932 k1 ^= (uint32_t)tail[0];
944 *(uint32_t*)out = h1;
960 const uint8_t* data = (
const uint8_t*)
key;
961 const size_t nblocks = len / 16;
968 const uint32_t c1 = 0x239b961b;
969 const uint32_t c2 = 0xab0e9789;
970 const uint32_t c3 = 0x38b34ae5;
971 const uint32_t c4 = 0xa1e38b93;
973 const uint32_t* blocks = (
const uint32_t*)data;
975 for (
size_t i = 0; i < nblocks; i++) {
987 h1 = h1 * 5 + 0x561ccd1b;
995 h2 = h2 * 5 + 0x0bcaa747;
1003 h3 = h3 * 5 + 0x96cd1c35;
1011 h4 = h4 * 5 + 0x32ac3b17;
1015 const uint8_t* tail = data + nblocks * 16;
1017 uint32_t k1 = 0, k2 = 0, k3 = 0, k4 = 0;
1021 k4 ^= (uint32_t)tail[14] << 16;
1024 k4 ^= (uint32_t)tail[13] << 8;
1027 k4 ^= (uint32_t)tail[12];
1035 k3 ^= (uint32_t)tail[11] << 24;
1038 k3 ^= (uint32_t)tail[10] << 16;
1041 k3 ^= (uint32_t)tail[9] << 8;
1044 k3 ^= (uint32_t)tail[8];
1052 k2 ^= (uint32_t)tail[7] << 24;
1055 k2 ^= (uint32_t)tail[6] << 16;
1058 k2 ^= (uint32_t)tail[5] << 8;
1061 k2 ^= (uint32_t)tail[4];
1069 k1 ^= (uint32_t)tail[3] << 24;
1072 k1 ^= (uint32_t)tail[2] << 16;
1075 k1 ^= (uint32_t)tail[1] << 8;
1078 k1 ^= (uint32_t)tail[0];
1089 h1 ^= (uint32_t)len;
1090 h2 ^= (uint32_t)len;
1091 h3 ^= (uint32_t)len;
1092 h4 ^= (uint32_t)len;
1109 ((uint32_t*)out)[0] = h1;
1110 ((uint32_t*)out)[1] = h2;
1111 ((uint32_t*)out)[2] = h3;
1112 ((uint32_t*)out)[3] = h4;
1128 const uint8_t* data = (
const uint8_t*)
key;
1129 const size_t nblocks = len / 16;
1134 const uint64_t c1 = 0x87c37b91114253d5ULL;
1135 const uint64_t c2 = 0x4cf5ad432745937fULL;
1138 const uint64_t* blocks = (
const uint64_t*)data;
1139 for (
size_t i = 0; i < nblocks; i++) {
1150 h1 = h1 * 5 + 0x52dce729;
1159 h2 = h2 * 5 + 0x38495ab5;
1163 const uint8_t* tail = data + nblocks * 16;
1170 k2 ^= ((uint64_t)tail[14]) << 48;
1173 k2 ^= ((uint64_t)tail[13]) << 40;
1176 k2 ^= ((uint64_t)tail[12]) << 32;
1179 k2 ^= ((uint64_t)tail[11]) << 24;
1182 k2 ^= ((uint64_t)tail[10]) << 16;
1185 k2 ^= ((uint64_t)tail[9]) << 8;
1188 k2 ^= ((uint64_t)tail[8]);
1196 k1 ^= ((uint64_t)tail[7]) << 56;
1199 k1 ^= ((uint64_t)tail[6]) << 48;
1202 k1 ^= ((uint64_t)tail[5]) << 40;
1205 k1 ^= ((uint64_t)tail[4]) << 32;
1208 k1 ^= ((uint64_t)tail[3]) << 24;
1211 k1 ^= ((uint64_t)tail[2]) << 16;
1214 k1 ^= ((uint64_t)tail[1]) << 8;
1217 k1 ^= ((uint64_t)tail[0]);
1240 ((uint64_t*)out)[0] = h1;
1241 ((uint64_t*)out)[1] = h2;
1250 static char* HASH_TYPE_STR[5] = {
"HASH_INT",
"HASH_DOUBLE",
"HASH_STRING",
"HASH_PTR",
"HASH_UNKNOWN"};
1255 return HASH_TYPE_STR[node->
type];
1279 index = (hash_value[0]) % (table->
size);
1286 if (!strcmp(
key, node_ptr->
key)) {
1307 if (strlen(
key) == 0)
1314 new_hash_node->
key = strdup(
key);
1315 new_hash_node->
key_id =
'\0';
1318 new_hash_node->
data.
ptr = NULL;
1325 return new_hash_node;
1341 if (new_hash_node) {
1345 n_log(
LOG_ERR,
"Could not get a new node in table %p with key %s", table,
key);
1347 return new_hash_node;
1363 if (new_hash_node) {
1367 n_log(
LOG_ERR,
"Could not get a new node in table %p with key %s", table,
key);
1369 return new_hash_node;
1385 if (new_hash_node) {
1392 n_log(
LOG_ERR,
"Could not get a new node in table %p with key %s", table,
key);
1394 return new_hash_node;
1410 if (new_hash_node) {
1414 n_log(
LOG_ERR,
"Could not get a new node in table %p with key %s", table,
key);
1416 return new_hash_node;
1433 if (new_hash_node) {
1434 new_hash_node->
data.
ptr = value;
1438 n_log(
LOG_ERR,
"Could not get a new node in table %p with key %s", table,
key);
1440 return new_hash_node;
1461 n_log(
LOG_ERR,
"Can't add key[\"%s\"] with type HASH_INT, key already exist with type %s", node_ptr->
key,
ht_node_type(node_ptr));
1465 int retcode = FALSE;
1470 if (retcode == TRUE) {
1495 n_log(
LOG_ERR,
"Can't add key[\"%s\"] with type HASH_DOUBLE, key already exist with type %s", node_ptr->
key,
ht_node_type(node_ptr));
1499 int retcode = FALSE;
1504 if (retcode == TRUE) {
1535 n_log(
LOG_ERR,
"Can't add key[\"%s\"] with type HASH_PTR , key already exist with type %s", node_ptr->
key,
ht_node_type(node_ptr));
1539 int retcode = FALSE;
1544 if (retcode == TRUE) {
1571 n_log(
LOG_ERR,
"Can't add key[\"%s\"] with type HASH_PTR , key already exist with type %s", node_ptr->
key,
ht_node_type(node_ptr));
1575 int retcode = FALSE;
1580 if (retcode == TRUE) {
1607 n_log(
LOG_ERR,
"Can't add key[\"%s\"] with type HASH_PTR , key already exist with type %s", node_ptr->
key,
ht_node_type(node_ptr));
1611 int retcode = FALSE;
1616 if (retcode == TRUE) {
1633 if (strlen(
key) == 0)
1662 if (strlen(
key) == 0)
1690 if (strlen(
key) == 0)
1717 if (strlen(
key) == 0)
1749 if (strlen(
key) == 0)
1753 index = (hash_value[0]) % (table->
size);
1763 if (!strcmp(
key, node_ptr->
key)) {
1764 node_to_kill = list_node;
1791 for (index = 0; index < table->
size; index++) {
1809 if ((*table)->hash_table) {
1813 for (it = 0; it < (*table)->size; it++) {
1814 if ((*table)->hash_table[it])
1817 Free((*table)->hash_table);
1831 printf(
"key:%s node:%s\n", ((
HASH_NODE*)node->ptr)->key, ((
HASH_NODE*)node->ptr)->key);
1851 if (node_is_matching(hnode) == TRUE) {
1902 n_log(
LOG_ERR,
"Couldn't allocate new_ht_trie with alphabet_length of %zu and alphabet offset of %d", alphabet_length, alphabet_offset);
1927 table->
seed = (uint32_t)rand() % 100000;
1935 for (it = 0; it < size; it++) {
1939 n_log(
LOG_ERR,
"Can't allocate table -> hash_table[ %d ] !", it);
1940 size_t it_delete = 0;
1941 for (it_delete = 0; it_delete < it; it_delete++) {
2130 return table->
ht_search(table, node_is_matching);
2150 return (*table)->destroy_ht(table);
2166 index = (hash_value) % (table->
size);
2221 index = (hash_value) % (table->
size);
2230 if (list_node->destroy_func) {
2231 list_node->destroy_func(node_ptr->
data.
ptr);
2233 list_node->destroy_func = destructor;
2237 n_log(
LOG_ERR,
"Can't add key[\"%s\"] with type HASH_PTR , key already exist with type %s", node_ptr->
key,
ht_node_type(node_ptr));
2245 new_hash_node->
key = NULL;
2247 new_hash_node->
data.
ptr = val;
2270 index = (hash_value) % (table->
size);
2272 n_log(
LOG_ERR,
"Can't remove key[\"%d\"], table is empty", hash_value);
2280 node_to_kill = list_node;
2292 n_log(
LOG_ERR,
"Can't delete key[\"%d\"]: inexisting key", hash_value);
2311 if (
list_push(results, strdup(keybud), &free) == TRUE) {
2318 char new_keybud[3] =
"";
2320 list_push(results, strdup(new_keybud), &free);
2327 if (strncasecmp(keybud, hnode->
key, strlen(keybud)) == 0) {
2328 char*
key = strdup(hnode->
key);
2339 if (results && results->
nb_items < 1)
2351 if (nb <= 1)
return FALSE;
2352 if (nb <= 3)
return TRUE;
2355 if ((nb % 2 == 0) || (nb % 3 == 0))
2359 for (
size_t it = 5; it * it <= nb; it = it + 6) {
2360 if ((nb % it == 0) || (nb % (it + 2) == 0))
2392 if (table->
size == 0)
return FALSE;
2394 size_t nb_collisionned_lists = 0;
2396 for (
size_t hash_it = 0; hash_it < table->
size; hash_it++) {
2398 nb_collisionned_lists++;
2401 size_t collision_percentage = (100 * nb_collisionned_lists) / table->
size;
2402 return (
int)collision_percentage;
2413 size_t optimum_size = (size_t)((
double)table->
nb_keys * 1.3);
2414 if (
is_prime(optimum_size) != TRUE)
2416 return optimum_size;
2429 n_log(
LOG_ERR,
"invalid size %d for hash table %p", size, (*table));
2434 if (size > (*table)->size) {
2436 if (!(*table)->hash_table) {
2437 n_log(
LOG_ERR,
"Realloc did not augment the size the table !");
2439 for (
size_t it = (*table)->size; it < size; it++) {
2442 if (!(*table)->hash_table[it]) {
2443 n_log(
LOG_ERR,
"Can't allocate table -> hash_table[ %d ] !", it);
2444 for (
size_t it_delete = 0; it_delete < it; it_delete++) {
2447 Free((*table)->hash_table);
2452 for (
size_t it = 0; it < size; it++) {
2453 if (((*table)->hash_table[it])) {
2454 while ((*table)->hash_table[it]->start) {
2461 size_t index = (hash_node->
hash_value) % (size);
2468 for (
size_t it = 0; it < (*table)->size; it++) {
2469 if (((*table)->hash_table[it])) {
2470 while ((*table)->hash_table[it]->start) {
2477 size_t index = (hash_node->
hash_value) % (size);
2482 for (
size_t it = size; it < (*table)->size; it++) {
2486 if (!(*table)->hash_table) {
2487 n_log(
LOG_ERR,
"Realloc did not reduce the resize the table !");
2490 (*table)->size = size;
2504 if (optimal_size == FALSE) {
2509 if (collision_percentage == FALSE)
2512 int resize_result =
ht_resize(&(*table), optimal_size);
2513 if (resize_result == FALSE) {
2518 if (collision_percentage == FALSE) {
#define FreeNoLog(__ptr)
Free Handler without log.
#define FALL_THROUGH
set windows if true
#define Malloc(__ptr, __struct, __size)
Malloc Handler to get errors and set to 0.
#define __n_assert(__ptr, __ret)
macro to assert things
#define FORCE_INLINE
FORCE_INLINE portable macro.
#define Realloc(__ptr, __struct, __size)
Realloc Handler to get errors.
#define Free(__ptr)
Free Handler to get errors.
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
HASH_NODE *(* ht_get_node)(struct HASH_TABLE *table, const char *key)
get HASH_NODE at 'key' from table
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
LIST *(* ht_search)(struct HASH_TABLE *table, int(*node_is_matching)(HASH_NODE *node))
search elements given an expression
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'
#define ht_foreach(__ITEM_, __HASH_)
ForEach macro helper (classic / old)
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)
#define HASH_PTR
value of pointer type inside the hash node
HASH_TABLE * new_ht(size_t size)
Create a hash table with the given size.
#define MurmurHash(__key, __len, __seed, __out)
Murmur hash macro helper 64 bits.
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'
#define HASH_DOUBLE
value of double type inside the hash node
int empty_ht(HASH_TABLE *table)
empty a table
#define HASH_STRING
value of char * type inside the hash node
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)
#define HASH_CLASSIC
Murmur hash using hash key string, hash key numeric value, index table with lists of elements.
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_length, size_t alphabet_offset)
create a TRIE hash table with the alphabet_size, each key value beeing decreased by alphabet_offset
#define HASH_TRIE
TRIE tree using hash key string.
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
#define HASH_INT
compatibility with existing rot func
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
#define HT_FOREACH(__ITEM_, __HASH_,...)
ForEach macro helper.
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.
#define HASH_UNKNOWN
value of unknow type inside the hash node
structure of a hash table node
structure of a hash table
size_t nb_max_items
maximum number of item in the list.
struct LIST_NODE * prev
pointer to the previous node
LIST_NODE * start
pointer to the start of the list
size_t nb_items
number of item currently in the list
struct LIST_NODE * next
pointer to the next node
int list_push(LIST *list, void *ptr, void(*destructor)(void *ptr))
Add a pointer to the end of the list.
#define list_foreach(__ITEM_, __LIST_)
ForEach macro helper.
#define remove_list_node(__LIST_, __NODE_, __TYPE_)
Remove macro helper for void pointer casting.
LIST_NODE * list_node_shift(LIST *list)
Get a LIST_NODE pointer from the start of the list.
int list_destroy(LIST **list)
Empty and Free a list container.
LIST * new_generic_list(size_t max_items)
Initialiaze a generic list container to max_items pointers.
#define MAX_LIST_ITEMS
flag to pass to new_generic_list for the maximum possible number of item in a list
int list_node_push(LIST *list, LIST_NODE *node)
Add a filled node to the end of the list.
Structure of a generic LIST container.
Structure of a generic list node.
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
#define LOG_DEBUG
debug-level messages
#define LOG_ERR
error conditions
Common headers and low-level functions & define.
void _ht_node_destroy(void *node)
destroy a HASH_NODE by first calling the HASH_NODE destructor
int _ht_get_int(HASH_TABLE *table, const char *key, int64_t *val)
Retrieve an integral value in the hash table, at the given key.
int _destroy_ht(HASH_TABLE **table)
Free and set the table to NULL.
int _ht_get_double(HASH_TABLE *table, const char *key, double *val)
Retrieve a double value in the hash table, at the given key.
int _ht_get_int_trie(HASH_TABLE *table, const char *key, int64_t *val)
Retrieve an integral value in the hash table, at the given key.
HASH_NODE * _ht_new_double_node(HASH_TABLE *table, const char *key, double value)
node creation, HASH_CLASSIC mode
int _ht_put_double(HASH_TABLE *table, const char *key, double value)
put a double value with given key in the targeted hash table
HASH_NODE * _ht_new_string_ptr_node(HASH_TABLE *table, const char *key, char *value)
node creation, HASH_CLASSIC mode, pointer to string value
int _ht_put_string_trie(HASH_TABLE *table, const char *key, char *string)
put a duplicate of the string value with given key in the targeted hash table [TRIE HASH TABLE)
uint32_t getblock32(const uint32_t *p, const size_t i)
Block read - modified from murmur's author, ajusted byte endianess.
int _ht_get_ptr(HASH_TABLE *table, const char *key, void **val)
Retrieve a pointer value in the hash table, at the given key.
HASH_NODE * _ht_new_node_trie(HASH_TABLE *table, const char key)
node creation, HASH_CLASSIC mode
int _ht_depth_first_search(HASH_NODE *node, LIST *results)
recursive, helper for ht_get_completion_list, get the list of leaf starting from node
HASH_NODE * _ht_new_int_node(HASH_TABLE *table, const char *key, int64_t value)
node creation, HASH_CLASSIC mode
uint32_t fmix32(uint32_t h)
Finalization mix - force all bits of a hash block to avalanche (from murmur's author)
void _ht_print_trie(HASH_TABLE *table)
Generic print func call for trie trees.
int _ht_get_string_trie(HASH_TABLE *table, const char *key, char **val)
Retrieve an char *string value in the hash table, at the given key.
int _ht_put_int_trie(HASH_TABLE *table, const char *key, int64_t value)
put an integral value with given key in the targeted hash table [TRIE HASH TABLE)
void _ht_print_trie_helper(HASH_TABLE *table, HASH_NODE *node)
Recursive function to print trie tree's keys and values.
HASH_NODE * _ht_get_node_trie(HASH_TABLE *table, const char *key)
retrieve a HASH_NODE at key from table
int _ht_put_string(HASH_TABLE *table, const char *key, char *string)
put a null terminated char *string with given key in the targeted hash table (copy of string)
HASH_NODE * _ht_new_ptr_node(HASH_TABLE *table, const char *key, void *value, void(*destructor)(void *ptr))
node creation, HASH_CLASSIC mode, pointer to string value
int _ht_put_string_ptr_trie(HASH_TABLE *table, const char *key, char *string)
put a pointer to the string value with given key in the targeted hash table [TRIE HASH TABLE)
int _ht_put_ptr(HASH_TABLE *table, const char *key, void *ptr, void(*destructor)(void *ptr))
put a pointer value with given key in the targeted hash table
void _ht_print(HASH_TABLE *table)
Generic print func call for classic hash tables.
HASH_NODE * _ht_new_node(HASH_TABLE *table, const char *key)
node creation, HASH_CLASSIC mode
char * _ht_find_longest_prefix_trie(HASH_TABLE *table, const char *key)
find the longest prefix string that is not the current key
int _ht_get_ptr_trie(HASH_TABLE *table, const char *key, void **val)
Retrieve a pointer value in the hash table, at the given key.
int _ht_get_string(HASH_TABLE *table, const char *key, char **val)
Retrieve a char *string value in the hash table, at the given key.
int _empty_ht(HASH_TABLE *table)
Empty a hash table (CLASSIC mode)
#define BIG_CONSTANT(x)
max unsigned long long
int _ht_is_leaf_node_trie(HASH_TABLE *table, const char *key)
Search a key and tell if it's holding a value (leaf)
int _ht_put_string_ptr(HASH_TABLE *table, const char *key, char *string)
put a null terminated char *string with given key in the targeted hash table (pointer)
LIST * _ht_search_trie(HASH_TABLE *table, int(*node_is_matching)(HASH_NODE *node))
Search tree's keys and apply a matching func to put results in the list.
size_t _ht_check_trie_divergence(HASH_TABLE *table, const char *key)
check and return branching index in key if any
int _ht_put_double_trie(HASH_TABLE *table, const char *key, double value)
put a double value with given key in the targeted hash table [TRIE HASH TABLE)
HASH_NODE * _ht_get_node(HASH_TABLE *table, const char *key)
return the associated key's node inside the hash_table
#define BYTESWAP64(x)
32 bits bytes swap
#define BYTESWAP32(x)
32 bits bytes swap
int _destroy_ht_trie(HASH_TABLE **table)
Free and set the table to NULL (TRIE mode)
int _ht_put_ptr_trie(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 [TRIE HASH TABLE)
int _empty_ht_trie(HASH_TABLE *table)
Empty a TRIE hash table.
int _ht_get_double_trie(HASH_TABLE *table, const char *key, double *val)
Retrieve an double value in the hash table, at the given key.
int _ht_remove(HASH_TABLE *table, const char *key)
Remove a key from a hash table.
uint64_t getblock64(const uint64_t *p, const size_t i)
Block read - modified from murmur's author, ajusted byte endianess.
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 [CLASSIC HASH TABLE)
int _ht_remove_trie(HASH_TABLE *table, const char *key)
Remove a key from a trie table and destroy the node.
LIST * _ht_search(HASH_TABLE *table, int(*node_is_matching)(HASH_NODE *node))
Search hash table's keys and apply a matching func to put results in the list.
HASH_NODE * _ht_new_string_node(HASH_TABLE *table, const char *key, char *value)
node creation, HASH_CLASSIC mode, strdup of value
void _ht_search_trie_helper(LIST *results, HASH_NODE *node, int(*node_is_matching)(HASH_NODE *node))
Recursive function to search tree's keys and apply a matching func to put results in the list.
#define ROTL64(x, r)
64 bit rotate left
uint64_t fmix64(uint64_t k)
Finalization mix - force all bits of a hash block to avalanche (from murmur's author)
#define ROTL32(x, r)
32 bit rotate left
Hash functions and table.
N_STR and string function declaration.