56 new_hash_node->
key = NULL;
89 for (
size_t it = 0;
key[it]; it++) {
92 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it,
key);
149 size_t last_index = 0;
150 for (
size_t it = 0;
key[it] !=
'\0'; it++) {
153 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it,
key);
159 if (it2 != (
unsigned)index && node->
children[it2]) {
182 size_t len = strlen(
key);
185 char* longest_prefix = NULL;
186 Malloc(longest_prefix,
char, len + 1);
188 memcpy(longest_prefix,
key, len);
190 longest_prefix[len] =
'\0';
194 if (branch_index > 0 && branch_index != SIZE_MAX) {
196 longest_prefix[branch_index - 1] =
'\0';
199 Realloc(longest_prefix,
char, branch_index + 1);
201 return longest_prefix;
223 if (!longest_prefix) {
227 if (longest_prefix[0] ==
'\0') {
228 Free(longest_prefix);
233 for (it = 0; longest_prefix[it] !=
'\0'; it++) {
236 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it,
key);
239 if (node->
children[index] != NULL) {
244 Free(longest_prefix);
250 for (;
key[it] !=
'\0'; it++) {
253 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it,
key);
263 Free(longest_prefix);
283 for (
size_t it = 0;
key[it] !=
'\0'; it++) {
286 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it,
key);
290 if (node->
children[index] == NULL) {
338 for (
size_t it = 0;
key[it] !=
'\0'; it++) {
341 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it,
key);
344 if (node->
children[index] == NULL) {
393 for (
size_t it = 0;
key[it] !=
'\0'; it++) {
396 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it,
key);
399 if (node->
children[index] == NULL) {
460 for (
size_t it = 0;
key[it] !=
'\0'; it++) {
463 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it,
key);
466 if (node->
children[index] == NULL) {
517 for (
size_t it = 0;
key[it] !=
'\0'; it++) {
520 n_log(
LOG_ERR,
"Invalid value %zu for character at position %zu of %s, set to 0", index, it,
key);
523 if (node->
children[index] == NULL) {
576 if (
key[0] !=
'\0') {
578 for (
size_t it = 0;
key[it] !=
'\0'; it++) {
581 n_log(
LOG_DEBUG,
"Invalid value %d for charater at index %d of %s, set to 0", index, it,
key);
584 if (node->
children[index] == NULL) {
606 if (strlen(
key) == 0)
634 if (strlen(
key) == 0)
662 if (strlen(
key) == 0)
690 if (strlen(
key) == 0)
749 printf(
"key: %s, val: ", node->
key);
750 switch (node->
type) {
752 printf(
"int: %ld", (
long)node->
data.
ival);
755 printf(
"double: %f", node->
data.
fval);
758 printf(
"ptr: %p", node->
data.
ptr);
764 printf(
"unknwow type %d", node->
type);
800 if (node_is_matching(node) == TRUE) {
855#define ROTL64(x, r) (((x) << (r)) | ((x) >> (64 - (r))))
857#define ROTL32(x, r) (((x) << (r)) | ((x) >> (32 - (r))))
859#define BIG_CONSTANT(x) (x##LLU)
862#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__)
863#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
864#define BYTESWAP32(x) (x)
865#define BYTESWAP64(x) (x)
868#elif defined(__i386) || defined(__x86_64) || defined(__alpha) || defined(__vax)
870#define BYTESWAP32(x) (x)
871#define BYTESWAP64(x) (x)
873#elif defined(__GNUC__) || defined(__clang__)
875#if __has_builtin(__builtin_bswap32)
876#define BYTESWAP32(x) __builtin_bswap32(x)
878#if __has_builtin(__builtin_bswap64)
879#define BYTESWAP64(x) __builtin_bswap64(x)
886#define BYTESWAP32(x) ((((x) & 0xFF) << 24) | (((x) >> 24) & 0xFF) | (((x) & 0x0000FF00) << 8) | (((x) & 0x00FF0000) >> 8))
890#define BYTESWAP64(x) \
891 (((uint64_t)(x) << 56) | \
892 (((uint64_t)(x) << 40) & 0X00FF000000000000ULL) | \
893 (((uint64_t)(x) << 24) & 0X0000FF0000000000ULL) | \
894 (((uint64_t)(x) << 8) & 0X000000FF00000000ULL) | \
895 (((uint64_t)(x) >> 8) & 0X00000000FF000000ULL) | \
896 (((uint64_t)(x) >> 24) & 0X0000000000FF0000ULL) | \
897 (((uint64_t)(x) >> 40) & 0X000000000000FF00ULL) | \
898 ((uint64_t)(x) >> 56))
909 memcpy(&result, (
const uint8_t*)p + i * 4,
sizeof(result));
921 memcpy(&result, (
const uint8_t*)p + i * 8,
sizeof(result));
969 const uint8_t* data = (
const uint8_t*)
key;
970 const size_t nblocks = len / 4;
973 const uint32_t c1 = 0xcc9e2d51;
974 const uint32_t c2 = 0x1b873593;
976 const uint32_t* blocks = (
const uint32_t*)data;
978 for (
size_t i = 0; i < nblocks; i++) {
986 h1 = h1 * 5 + 0xe6546b64;
989 const uint8_t* tail = data + nblocks * 4;
993 k1 ^= (uint32_t)tail[2] << 16;
996 k1 ^= (uint32_t)tail[1] << 8;
999 k1 ^= (uint32_t)tail[0];
1009 h1 ^= (uint32_t)len;
1011 *(uint32_t*)out = h1;
1027 const uint8_t* data = (
const uint8_t*)
key;
1028 const size_t nblocks = len / 16;
1035 const uint32_t c1 = 0x239b961b;
1036 const uint32_t c2 = 0xab0e9789;
1037 const uint32_t c3 = 0x38b34ae5;
1038 const uint32_t c4 = 0xa1e38b93;
1040 const uint32_t* blocks = (
const uint32_t*)data;
1042 for (
size_t i = 0; i < nblocks; i++) {
1054 h1 = h1 * 5 + 0x561ccd1b;
1062 h2 = h2 * 5 + 0x0bcaa747;
1070 h3 = h3 * 5 + 0x96cd1c35;
1078 h4 = h4 * 5 + 0x32ac3b17;
1082 const uint8_t* tail = data + nblocks * 16;
1084 uint32_t k1 = 0, k2 = 0, k3 = 0, k4 = 0;
1088 k4 ^= (uint32_t)tail[14] << 16;
1091 k4 ^= (uint32_t)tail[13] << 8;
1094 k4 ^= (uint32_t)tail[12];
1102 k3 ^= (uint32_t)tail[11] << 24;
1105 k3 ^= (uint32_t)tail[10] << 16;
1108 k3 ^= (uint32_t)tail[9] << 8;
1111 k3 ^= (uint32_t)tail[8];
1119 k2 ^= (uint32_t)tail[7] << 24;
1122 k2 ^= (uint32_t)tail[6] << 16;
1125 k2 ^= (uint32_t)tail[5] << 8;
1128 k2 ^= (uint32_t)tail[4];
1136 k1 ^= (uint32_t)tail[3] << 24;
1139 k1 ^= (uint32_t)tail[2] << 16;
1142 k1 ^= (uint32_t)tail[1] << 8;
1145 k1 ^= (uint32_t)tail[0];
1156 h1 ^= (uint32_t)len;
1157 h2 ^= (uint32_t)len;
1158 h3 ^= (uint32_t)len;
1159 h4 ^= (uint32_t)len;
1176 ((uint32_t*)out)[0] = h1;
1177 ((uint32_t*)out)[1] = h2;
1178 ((uint32_t*)out)[2] = h3;
1179 ((uint32_t*)out)[3] = h4;
1195 const uint8_t* data = (
const uint8_t*)
key;
1196 const size_t nblocks = len / 16;
1201 const uint64_t c1 = 0x87c37b91114253d5ULL;
1202 const uint64_t c2 = 0x4cf5ad432745937fULL;
1205 const uint64_t* blocks = (
const uint64_t*)data;
1206 for (
size_t i = 0; i < nblocks; i++) {
1217 h1 = h1 * 5 + 0x52dce729;
1226 h2 = h2 * 5 + 0x38495ab5;
1230 const uint8_t* tail = data + nblocks * 16;
1237 k2 ^= ((uint64_t)tail[14]) << 48;
1240 k2 ^= ((uint64_t)tail[13]) << 40;
1243 k2 ^= ((uint64_t)tail[12]) << 32;
1246 k2 ^= ((uint64_t)tail[11]) << 24;
1249 k2 ^= ((uint64_t)tail[10]) << 16;
1252 k2 ^= ((uint64_t)tail[9]) << 8;
1255 k2 ^= ((uint64_t)tail[8]);
1263 k1 ^= ((uint64_t)tail[7]) << 56;
1266 k1 ^= ((uint64_t)tail[6]) << 48;
1269 k1 ^= ((uint64_t)tail[5]) << 40;
1272 k1 ^= ((uint64_t)tail[4]) << 32;
1275 k1 ^= ((uint64_t)tail[3]) << 24;
1278 k1 ^= ((uint64_t)tail[2]) << 16;
1281 k1 ^= ((uint64_t)tail[1]) << 8;
1284 k1 ^= ((uint64_t)tail[0]);
1307 ((uint64_t*)out)[0] = h1;
1308 ((uint64_t*)out)[1] = h2;
1319 switch (node->
type) {
1323 return "HASH_DOUBLE";
1325 return "HASH_STRING";
1329 return "HASH_UNKNOWN";
1350 index = (hash_value[0]) % (table->
size);
1357 if (!strcmp(
key, node_ptr->
key)) {
1378 if (strlen(
key) == 0)
1385 new_hash_node->
key = strdup(
key);
1386 new_hash_node->
key_id =
'\0';
1389 new_hash_node->
data.
ptr = NULL;
1396 return new_hash_node;
1412 if (new_hash_node) {
1416 n_log(
LOG_ERR,
"Could not get a new node in table %p with key %s", table,
key);
1418 return new_hash_node;
1434 if (new_hash_node) {
1438 n_log(
LOG_ERR,
"Could not get a new node in table %p with key %s", table,
key);
1440 return new_hash_node;
1456 if (new_hash_node) {
1463 n_log(
LOG_ERR,
"Could not get a new node in table %p with key %s", table,
key);
1465 return new_hash_node;
1481 if (new_hash_node) {
1485 n_log(
LOG_ERR,
"Could not get a new node in table %p with key %s", table,
key);
1487 return new_hash_node;
1505 if (new_hash_node) {
1506 new_hash_node->
data.
ptr = value;
1511 n_log(
LOG_ERR,
"Could not get a new node in table %p with key %s", table,
key);
1513 return new_hash_node;
1534 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));
1538 int retcode = FALSE;
1543 if (retcode == TRUE) {
1568 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));
1572 int retcode = FALSE;
1577 if (retcode == TRUE) {
1612 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));
1616 int retcode = FALSE;
1621 if (retcode == TRUE) {
1644 char* new_str = NULL;
1646 new_str = strdup(
string);
1648 n_log(
LOG_ERR,
"could not strdup char *string at %p, didn't overwrite %s",
string,
key);
1656 n_log(
LOG_ERR,
"Can't add key[\"%s\"] with type HASH_STRING , key already exist with type %s", node_ptr->
key,
ht_node_type(node_ptr));
1660 int retcode = FALSE;
1665 if (retcode == TRUE) {
1692 n_log(
LOG_ERR,
"Can't add key[\"%s\"] with type HASH_STRING , key already exist with type %s", node_ptr->
key,
ht_node_type(node_ptr));
1696 int retcode = FALSE;
1701 if (retcode == TRUE) {
1718 if (strlen(
key) == 0)
1747 if (strlen(
key) == 0)
1775 if (strlen(
key) == 0)
1802 if (strlen(
key) == 0)
1834 if (strlen(
key) == 0)
1838 index = (hash_value[0]) % (table->
size);
1848 if (!strcmp(
key, node_ptr->
key)) {
1849 node_to_kill = list_node;
1874 for (index = 0; index < table->
size; index++) {
1892 if ((*table)->hash_table) {
1896 for (it = 0; it < (*table)->size; it++) {
1897 if ((*table)->hash_table[it])
1900 Free((*table)->hash_table);
1916 printf(
"key:%s node:%s\n", ht_node->
key, ht_node->
key);
1936 if (node_is_matching(hnode) == TRUE) {
1987 n_log(
LOG_ERR,
"Couldn't allocate new_ht_trie with alphabet_length of %zu and alphabet offset of %zu", alphabet_length, alphabet_offset);
2012 table->
seed = (uint32_t)rand() % 100000;
2020 for (it = 0; it < size; it++) {
2024 n_log(
LOG_ERR,
"Can't allocate table -> hash_table[ %d ] !", it);
2025 size_t it_delete = 0;
2026 for (it_delete = 0; it_delete < it; it_delete++) {
2157 return table->
ht_put_ptr(table,
key, ptr, destructor, duplicator);
2216 return table->
ht_search(table, node_is_matching);
2236 return (*table)->destroy_ht(table);
2249 size_t index = (hash_value) % (table->
size);
2305 index = (hash_value) % (table->
size);
2317 n_log(
LOG_ERR,
"Can't free previous key[\"%s\"] with type HASH_PTR , no hash node destroy func", node_ptr->
key);
2324 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));
2332 new_hash_node->
key = NULL;
2334 new_hash_node->
data.
ptr = val;
2358 index = (hash_value) % (table->
size);
2360 n_log(
LOG_ERR,
"Can't remove key[\"%zu\"], table is empty", hash_value);
2368 node_to_kill = list_node;
2380 n_log(
LOG_ERR,
"Can't delete key[\"%zu\"]: inexisting key", hash_value);
2399 if (
list_push(results, strdup(keybud), &free) == TRUE) {
2406 char new_keybud[3] =
"";
2408 list_push(results, strdup(new_keybud), &free);
2415 if (strncasecmp(keybud, hnode->
key, strlen(keybud)) == 0) {
2416 char*
key = strdup(hnode->
key);
2418 n_log(
LOG_ERR,
"not enough space in list or memory error, key %s not pushed !",
key);
2428 if (results && results->
nb_items < 1)
2440 if (nb <= 1)
return FALSE;
2441 if (nb <= 3)
return TRUE;
2444 if ((nb % 2 == 0) || (nb % 3 == 0))
2448 for (
size_t it = 5; it * it <= nb; it = it + 6) {
2449 if ((nb % it == 0) || (nb % (it + 2) == 0))
2483 if (table->
size == 0)
return FALSE;
2485 size_t nb_collisionned_lists = 0;
2487 for (
size_t hash_it = 0; hash_it < table->
size; hash_it++) {
2489 nb_collisionned_lists++;
2492 size_t collision_percentage = (100 * nb_collisionned_lists) / table->
size;
2493 return (
int)collision_percentage;
2508 size_t optimum_size = (size_t)((
double)table->
nb_keys * 1.3);
2509 if (
is_prime(optimum_size) != TRUE)
2511 return optimum_size;
2527 n_log(
LOG_ERR,
"invalid size %zu for hash table %p", size, (
void*)(*table));
2533 if (size > (*table)->size) {
2534 if (
Realloc((*table)->hash_table,
LIST*, size) == FALSE) {
2537 for (
size_t it = (*table)->size; it < size; it++) {
2539 if (!(*table)->hash_table[it]) {
2540 n_log(
LOG_ERR,
"Can't allocate table -> hash_table[ %zu ] !", it);
2542 for (
size_t it_delete = (*table)->size; it_delete < it; it_delete++) {
2547 Realloc((*table)->hash_table,
LIST*, (*table)->size);
2552 for (
size_t it = 0; it < size; it++) {
2553 if ((*table)->hash_table[it]) {
2554 while ((*table)->hash_table[it]->start) {
2561 size_t index = (hash_node->
hash_value) % (size);
2568 for (
size_t it = 0; it < (*table)->size; it++) {
2569 if ((*table)->hash_table[it]) {
2570 while ((*table)->hash_table[it]->start) {
2577 size_t index = (hash_node->
hash_value) % (size);
2583 for (
size_t it = size; it < (*table)->size; it++) {
2592 (*table)->size = size;
2610 if (optimal_size == FALSE) {
2615 if (collision_percentage == FALSE)
2618 int resize_result =
ht_resize(table, optimal_size);
2619 if (resize_result == FALSE) {
2624 if (collision_percentage == FALSE) {
2646 if (!duplicated_table) {
2647 n_log(
LOG_ERR,
"couldn't allocate duplicated table of %zu elements", table->
size);
2653 int has_succeeded = TRUE;
2654 switch (hash_node->
type) {
2665 if (!duplicated_ptr) {
2666 n_log(
LOG_ERR,
"duplicate_func returned NULL for key [%s]", hash_node->
key);
2667 has_succeeded = FALSE;
2681 n_log(
LOG_ERR,
"unknown node type %d for key [%s], skipping", hash_node->
type, hash_node->
key);
2685 if (has_succeeded == FALSE) {
2686 n_log(
LOG_ERR,
"problem when trying to duplicate value in %p, duplication cancelled", table);
2692 return duplicated_table;
static size_t max_results
#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(* ht_put_ptr)(struct HASH_TABLE *table, const char *key, void *ptr, void(*destructor)(void *ptr), void *(*duplicator)(void *ptr))
put a a pointer
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.
void *(* duplicate_func)(void *ptr)
duplicator_func
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_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)
LIST * ht_search(HASH_TABLE *table, int(*node_is_matching)(HASH_NODE *node))
seach table for matching nodes
HASH_TABLE * ht_duplicate(HASH_TABLE *table)
duplicate a hash table (all pointers should have a duplicator func set)
int destroy_ht(HASH_TABLE **table)
empty a table and destroy it
int ht_put_ptr_ex(HASH_TABLE *table, HASH_VALUE hash_value, void *val, void(*destructor)(void *ptr), void *(*duplicator)(void *ptr))
put a pointer value with given key in the targeted hash table (HASH_CLASSIC only)
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_put_ptr(HASH_TABLE *table, const char *key, void *ptr, void(*destructor)(void *ptr), void *(*duplicator)(void *ptr))
put an arbitrary pointer 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 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_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 (HASH_CLASSIC mode only)
char * ht_node_type(const HASH_NODE *node)
get the type of a node , text version
#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.
structure of a hash table node
structure of a hash table
size_t nb_max_items
Maximum number of items 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, safe for node removal during iteration.
#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.
HASH_NODE * _ht_new_node(const HASH_TABLE *table, const char *key)
node creation, HASH_CLASSIC mode
void _ht_node_destroy(void *node)
destroy a HASH_NODE by first calling the HASH_NODE destructor
int _ht_put_ptr(HASH_TABLE *table, const char *key, void *ptr, void(*destructor)(void *ptr), void *(*duplicator)(void *ptr))
put a pointer value with given key in the targeted hash table
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)
HASH_NODE * _ht_new_ptr_node(HASH_TABLE *table, const char *key, void *value, void(*destructor)(void *ptr), void *(*duplicator)(void *ptr))
node creation, HASH_CLASSIC mode, pointer to string value
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)
int _ht_put_ptr_trie(HASH_TABLE *table, const char *key, void *ptr, void(*destructor)(void *ptr), void *(*duplicator)(void *ptr))
put a pointer to the string 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_string_node(HASH_TABLE *table, const char *key, const char *value)
node creation, HASH_CLASSIC mode, strdup of 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)
void _ht_print(HASH_TABLE *table)
Generic print func call for classic hash tables.
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 _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.
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.