57 new_hash_node->
key = NULL;
90 for (
size_t it = 0;
key[it]; it++) {
93 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it,
key);
151 size_t last_index = 0;
159 for (
size_t it = 0; node &&
key[it] !=
'\0'; it++) {
162 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it,
key);
169 if (it2 != (
unsigned)index && node->
children[it2]) {
192 size_t len = strlen(
key);
195 char* longest_prefix = NULL;
196 Malloc(longest_prefix,
char, len + 1);
198 memcpy(longest_prefix,
key, len);
200 longest_prefix[len] =
'\0';
204 if (branch_index > 0 && branch_index != SIZE_MAX) {
206 longest_prefix[branch_index - 1] =
'\0';
209 Realloc(longest_prefix,
char, branch_index + 1);
211 return longest_prefix;
233 if (!longest_prefix) {
237 if (longest_prefix[0] ==
'\0') {
238 Free(longest_prefix);
243 for (it = 0; longest_prefix[it] !=
'\0'; it++) {
246 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it,
key);
249 if (node->
children[index] != NULL) {
254 Free(longest_prefix);
260 for (;
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);
273 Free(longest_prefix);
293 for (
size_t it = 0;
key[it] !=
'\0'; it++) {
296 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it,
key);
300 if (node->
children[index] == NULL) {
348 for (
size_t it = 0;
key[it] !=
'\0'; it++) {
351 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it,
key);
354 if (node->
children[index] == NULL) {
403 for (
size_t it = 0;
key[it] !=
'\0'; it++) {
406 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it,
key);
409 if (node->
children[index] == NULL) {
470 for (
size_t it = 0;
key[it] !=
'\0'; it++) {
473 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it,
key);
476 if (node->
children[index] == NULL) {
527 for (
size_t it = 0;
key[it] !=
'\0'; it++) {
530 n_log(
LOG_ERR,
"Invalid value %zu for character at position %zu of %s, set to 0", index, it,
key);
533 if (node->
children[index] == NULL) {
586 if (
key[0] !=
'\0') {
588 for (
size_t it = 0;
key[it] !=
'\0'; it++) {
591 n_log(
LOG_DEBUG,
"Invalid value %d for charater at index %d of %s, set to 0", index, it,
key);
594 if (node->
children[index] == NULL) {
616 if (strlen(
key) == 0)
644 if (strlen(
key) == 0)
672 if (strlen(
key) == 0)
700 if (strlen(
key) == 0)
759 printf(
"key: %s, val: ", node->
key);
760 switch (node->
type) {
762 printf(
"int: %ld", (
long)node->
data.
ival);
765 printf(
"double: %f", node->
data.
fval);
768 printf(
"ptr: %p", node->
data.
ptr);
774 printf(
"unknwow type %d", node->
type);
810 if (node_is_matching(node) == TRUE) {
865#define ROTL64(x, r) (((x) << (r)) | ((x) >> (64 - (r))))
867#define ROTL32(x, r) (((x) << (r)) | ((x) >> (32 - (r))))
869#define BIG_CONSTANT(x) (x##LLU)
872#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__)
873#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
874#define BYTESWAP32(x) (x)
875#define BYTESWAP64(x) (x)
878#elif defined(__i386) || defined(__x86_64) || defined(__alpha) || defined(__vax)
880#define BYTESWAP32(x) (x)
881#define BYTESWAP64(x) (x)
883#elif defined(__GNUC__) || defined(__clang__)
885#if __has_builtin(__builtin_bswap32)
886#define BYTESWAP32(x) __builtin_bswap32(x)
888#if __has_builtin(__builtin_bswap64)
889#define BYTESWAP64(x) __builtin_bswap64(x)
896#define BYTESWAP32(x) ((((x) & 0xFF) << 24) | (((x) >> 24) & 0xFF) | (((x) & 0x0000FF00) << 8) | (((x) & 0x00FF0000) >> 8))
900#define BYTESWAP64(x) \
901 (((uint64_t)(x) << 56) | \
902 (((uint64_t)(x) << 40) & 0X00FF000000000000ULL) | \
903 (((uint64_t)(x) << 24) & 0X0000FF0000000000ULL) | \
904 (((uint64_t)(x) << 8) & 0X000000FF00000000ULL) | \
905 (((uint64_t)(x) >> 8) & 0X00000000FF000000ULL) | \
906 (((uint64_t)(x) >> 24) & 0X0000000000FF0000ULL) | \
907 (((uint64_t)(x) >> 40) & 0X000000000000FF00ULL) | \
908 ((uint64_t)(x) >> 56))
919 memcpy(&result, (
const uint8_t*)p + i * 4,
sizeof(result));
931 memcpy(&result, (
const uint8_t*)p + i * 8,
sizeof(result));
979 const uint8_t* data = (
const uint8_t*)
key;
980 const size_t nblocks = len / 4;
983 const uint32_t c1 = 0xcc9e2d51;
984 const uint32_t c2 = 0x1b873593;
986 const uint32_t* blocks = (
const uint32_t*)data;
988 for (
size_t i = 0; i < nblocks; i++) {
996 h1 = h1 * 5 + 0xe6546b64;
999 const uint8_t* tail = data + nblocks * 4;
1003 k1 ^= (uint32_t)tail[2] << 16;
1006 k1 ^= (uint32_t)tail[1] << 8;
1009 k1 ^= (uint32_t)tail[0];
1019 h1 ^= (uint32_t)len;
1021 *(uint32_t*)out = h1;
1037 const uint8_t* data = (
const uint8_t*)
key;
1038 const size_t nblocks = len / 16;
1045 const uint32_t c1 = 0x239b961b;
1046 const uint32_t c2 = 0xab0e9789;
1047 const uint32_t c3 = 0x38b34ae5;
1048 const uint32_t c4 = 0xa1e38b93;
1050 const uint32_t* blocks = (
const uint32_t*)data;
1052 for (
size_t i = 0; i < nblocks; i++) {
1064 h1 = h1 * 5 + 0x561ccd1b;
1072 h2 = h2 * 5 + 0x0bcaa747;
1080 h3 = h3 * 5 + 0x96cd1c35;
1088 h4 = h4 * 5 + 0x32ac3b17;
1092 const uint8_t* tail = data + nblocks * 16;
1094 uint32_t k1 = 0, k2 = 0, k3 = 0, k4 = 0;
1098 k4 ^= (uint32_t)tail[14] << 16;
1101 k4 ^= (uint32_t)tail[13] << 8;
1104 k4 ^= (uint32_t)tail[12];
1112 k3 ^= (uint32_t)tail[11] << 24;
1115 k3 ^= (uint32_t)tail[10] << 16;
1118 k3 ^= (uint32_t)tail[9] << 8;
1121 k3 ^= (uint32_t)tail[8];
1129 k2 ^= (uint32_t)tail[7] << 24;
1132 k2 ^= (uint32_t)tail[6] << 16;
1135 k2 ^= (uint32_t)tail[5] << 8;
1138 k2 ^= (uint32_t)tail[4];
1146 k1 ^= (uint32_t)tail[3] << 24;
1149 k1 ^= (uint32_t)tail[2] << 16;
1152 k1 ^= (uint32_t)tail[1] << 8;
1155 k1 ^= (uint32_t)tail[0];
1166 h1 ^= (uint32_t)len;
1167 h2 ^= (uint32_t)len;
1168 h3 ^= (uint32_t)len;
1169 h4 ^= (uint32_t)len;
1186 ((uint32_t*)out)[0] = h1;
1187 ((uint32_t*)out)[1] = h2;
1188 ((uint32_t*)out)[2] = h3;
1189 ((uint32_t*)out)[3] = h4;
1205 const uint8_t* data = (
const uint8_t*)
key;
1206 const size_t nblocks = len / 16;
1211 const uint64_t c1 = 0x87c37b91114253d5ULL;
1212 const uint64_t c2 = 0x4cf5ad432745937fULL;
1215 const uint64_t* blocks = (
const uint64_t*)data;
1216 for (
size_t i = 0; i < nblocks; i++) {
1227 h1 = h1 * 5 + 0x52dce729;
1236 h2 = h2 * 5 + 0x38495ab5;
1240 const uint8_t* tail = data + nblocks * 16;
1247 k2 ^= ((uint64_t)tail[14]) << 48;
1250 k2 ^= ((uint64_t)tail[13]) << 40;
1253 k2 ^= ((uint64_t)tail[12]) << 32;
1256 k2 ^= ((uint64_t)tail[11]) << 24;
1259 k2 ^= ((uint64_t)tail[10]) << 16;
1262 k2 ^= ((uint64_t)tail[9]) << 8;
1265 k2 ^= ((uint64_t)tail[8]);
1273 k1 ^= ((uint64_t)tail[7]) << 56;
1276 k1 ^= ((uint64_t)tail[6]) << 48;
1279 k1 ^= ((uint64_t)tail[5]) << 40;
1282 k1 ^= ((uint64_t)tail[4]) << 32;
1285 k1 ^= ((uint64_t)tail[3]) << 24;
1288 k1 ^= ((uint64_t)tail[2]) << 16;
1291 k1 ^= ((uint64_t)tail[1]) << 8;
1294 k1 ^= ((uint64_t)tail[0]);
1317 ((uint64_t*)out)[0] = h1;
1318 ((uint64_t*)out)[1] = h2;
1329 switch (node->
type) {
1333 return "HASH_DOUBLE";
1335 return "HASH_STRING";
1339 return "HASH_UNKNOWN";
1360 index = (hash_value[0]) % (table->
size);
1367 if (!strcmp(
key, node_ptr->
key)) {
1388 if (strlen(
key) == 0)
1395 new_hash_node->
key = strdup(
key);
1396 new_hash_node->
key_id =
'\0';
1399 new_hash_node->
data.
ptr = NULL;
1406 return new_hash_node;
1422 if (new_hash_node) {
1426 n_log(
LOG_ERR,
"Could not get a new node in table %p with key %s", table,
key);
1428 return new_hash_node;
1444 if (new_hash_node) {
1448 n_log(
LOG_ERR,
"Could not get a new node in table %p with key %s", table,
key);
1450 return new_hash_node;
1466 if (new_hash_node) {
1473 n_log(
LOG_ERR,
"Could not get a new node in table %p with key %s", table,
key);
1475 return new_hash_node;
1491 if (new_hash_node) {
1495 n_log(
LOG_ERR,
"Could not get a new node in table %p with key %s", table,
key);
1497 return new_hash_node;
1515 if (new_hash_node) {
1516 new_hash_node->
data.
ptr = value;
1521 n_log(
LOG_ERR,
"Could not get a new node in table %p with key %s", table,
key);
1523 return new_hash_node;
1544 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));
1548 int retcode = FALSE;
1553 if (retcode == TRUE) {
1578 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));
1582 int retcode = FALSE;
1587 if (retcode == TRUE) {
1622 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));
1626 int retcode = FALSE;
1631 if (retcode == TRUE) {
1654 char* new_str = NULL;
1656 new_str = strdup(
string);
1658 n_log(
LOG_ERR,
"could not strdup char *string at %p, didn't overwrite %s",
string,
key);
1666 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));
1670 int retcode = FALSE;
1675 if (retcode == TRUE) {
1702 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));
1706 int retcode = FALSE;
1711 if (retcode == TRUE) {
1728 if (strlen(
key) == 0)
1757 if (strlen(
key) == 0)
1785 if (strlen(
key) == 0)
1812 if (strlen(
key) == 0)
1844 if (strlen(
key) == 0)
1848 index = (hash_value[0]) % (table->
size);
1858 if (!strcmp(
key, node_ptr->
key)) {
1859 node_to_kill = list_node;
1884 for (index = 0; index < table->
size; index++) {
1902 if ((*table)->hash_table) {
1906 for (it = 0; it < (*table)->size; it++) {
1907 if ((*table)->hash_table[it])
1910 Free((*table)->hash_table);
1926 printf(
"key:%s node:%s\n", ht_node->
key, ht_node->
key);
1946 if (node_is_matching(hnode) == TRUE) {
1997 n_log(
LOG_ERR,
"Couldn't allocate new_ht_trie with alphabet_length of %zu and alphabet offset of %zu", alphabet_length, alphabet_offset);
2022 table->
seed = (uint32_t)rand() % 100000;
2030 for (it = 0; it < size; it++) {
2034 n_log(
LOG_ERR,
"Can't allocate table -> hash_table[ %d ] !", it);
2035 size_t it_delete = 0;
2036 for (it_delete = 0; it_delete < it; it_delete++) {
2167 return table->
ht_put_ptr(table,
key, ptr, destructor, duplicator);
2226 return table->
ht_search(table, node_is_matching);
2246 return (*table)->destroy_ht(table);
2259 size_t index = (hash_value) % (table->
size);
2315 index = (hash_value) % (table->
size);
2327 n_log(
LOG_ERR,
"Can't free previous key[\"%s\"] with type HASH_PTR , no hash node destroy func", node_ptr->
key);
2334 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));
2342 new_hash_node->
key = NULL;
2344 new_hash_node->
data.
ptr = val;
2368 index = (hash_value) % (table->
size);
2370 n_log(
LOG_ERR,
"Can't remove key[\"%zu\"], table is empty", hash_value);
2378 node_to_kill = list_node;
2390 n_log(
LOG_ERR,
"Can't delete key[\"%zu\"]: inexisting key", hash_value);
2409 if (
list_push(results, strdup(keybud), &free) == TRUE) {
2416 char new_keybud[3] =
"";
2418 list_push(results, strdup(new_keybud), &free);
2425 if (strncasecmp(keybud, hnode->
key, strlen(keybud)) == 0) {
2426 char*
key = strdup(hnode->
key);
2428 n_log(
LOG_ERR,
"not enough space in list or memory error, key %s not pushed !",
key);
2438 if (results && results->
nb_items < 1)
2450 if (nb <= 1)
return FALSE;
2451 if (nb <= 3)
return TRUE;
2454 if ((nb % 2 == 0) || (nb % 3 == 0))
2458 for (
size_t it = 5; it * it <= nb; it = it + 6) {
2459 if ((nb % it == 0) || (nb % (it + 2) == 0))
2493 if (table->
size == 0)
return FALSE;
2495 size_t nb_collisionned_lists = 0;
2497 for (
size_t hash_it = 0; hash_it < table->
size; hash_it++) {
2499 nb_collisionned_lists++;
2502 size_t collision_percentage = (100 * nb_collisionned_lists) / table->
size;
2503 return (
int)collision_percentage;
2518 size_t optimum_size = (size_t)((
double)table->
nb_keys * 1.3);
2519 if (
is_prime(optimum_size) != TRUE)
2521 return optimum_size;
2537 n_log(
LOG_ERR,
"invalid size %zu for hash table %p", size, (
void*)(*table));
2549 if (size > (*table)->size) {
2550 if (
Realloc((*table)->hash_table,
LIST*, size) == FALSE) {
2553 for (
size_t it = (*table)->size; it < size; it++) {
2555 if (!(*table)->hash_table[it]) {
2556 n_log(
LOG_ERR,
"Can't allocate table -> hash_table[ %zu ] !", it);
2558 for (
size_t it_delete = (*table)->size; it_delete < it; it_delete++) {
2563 Realloc((*table)->hash_table,
LIST*, (*table)->size);
2568 for (
size_t it = 0; it < size; it++) {
2569 if ((*table)->hash_table[it]) {
2570 while ((*table)->hash_table[it]->start) {
2577 size_t index = (hash_node->
hash_value) % (size);
2584 for (
size_t it = 0; it < (*table)->size; it++) {
2585 if ((*table)->hash_table[it]) {
2586 while ((*table)->hash_table[it]->start) {
2593 size_t index = (hash_node->
hash_value) % (size);
2599 for (
size_t it = size; it < (*table)->size; it++) {
2608 (*table)->size = size;
2626 if (optimal_size == FALSE) {
2631 if (collision_percentage == FALSE)
2634 int resize_result =
ht_resize(table, optimal_size);
2635 if (resize_result == FALSE) {
2640 if (collision_percentage == FALSE) {
2662 if (!duplicated_table) {
2663 n_log(
LOG_ERR,
"couldn't allocate duplicated table of %zu elements", table->
size);
2669 int has_succeeded = TRUE;
2670 switch (hash_node->
type) {
2681 if (!duplicated_ptr) {
2682 n_log(
LOG_ERR,
"duplicate_func returned NULL for key [%s]", hash_node->
key);
2683 has_succeeded = FALSE;
2697 n_log(
LOG_ERR,
"unknown node type %d for key [%s], skipping", hash_node->
type, hash_node->
key);
2701 if (has_succeeded == FALSE) {
2702 n_log(
LOG_ERR,
"problem when trying to duplicate value in %p, duplication cancelled", table);
2708 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
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.