38 new_hash_node->
key = NULL;
56 new_hash_node->
key_id = key;
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);
256int _ht_put_int_trie(
HASH_TABLE* table,
const char* key, HASH_INT_TYPE value) {
262 for (
size_t it = 0; key[it] !=
'\0'; it++) {
265 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it, key);
269 if (node->
children[index] == NULL) {
282 node->
key = strdup(key);
313 for (
size_t it = 0; key[it] !=
'\0'; it++) {
316 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it, key);
319 if (node->
children[index] == NULL) {
332 node->
key = strdup(key);
363 for (
size_t it = 0; key[it] !=
'\0'; it++) {
366 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it, key);
369 if (node->
children[index] == NULL) {
382 node->
key = strdup(key);
393 n_log(
LOG_ERR,
"strdup failure for value at key [%s]", key);
425 for (
size_t it = 0; key[it] !=
'\0'; it++) {
428 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it, key);
431 if (node->
children[index] == NULL) {
444 node->
key = strdup(key);
476 for (
size_t it = 0; key[it] !=
'\0'; it++) {
479 n_log(
LOG_ERR,
"Invalid value %u for charater at position %d of %s, set to 0", index, it, key);
482 if (node->
children[index] == NULL) {
495 node->
key = strdup(key);
521 if (key[0] !=
'\0') {
523 for (
size_t it = 0; key[it] !=
'\0'; it++) {
526 n_log(
LOG_DEBUG,
"Invalid value %d for charater at index %d of %s, set to 0", index, it, key);
529 if (node->
children[index] == NULL) {
548int _ht_get_int_trie(
HASH_TABLE* table,
const char* key, HASH_INT_TYPE* val) {
551 if (strlen(key) == 0)
579 if (strlen(key) == 0)
607 if (strlen(key) == 0)
635 if (strlen(key) == 0)
698 printf(
"key: %s, val: ", node->
key);
699 switch (node->
type) {
701 printf(
"int: %ld", (
long)node->
data.
ival);
704 printf(
"double: %f", node->
data.
fval);
707 printf(
"ptr: %p", node->
data.
ptr);
713 printf(
"unknwow type %d", node->
type);
751 if (node_is_matching(node) == TRUE) {
810#define ROTL64(x, r) (((x) << (r)) | ((x) >> (64 - (r))))
812#define ROTL32(x, r) (((x) << (r)) | ((x) >> (32 - (r))))
814#define BIG_CONSTANT(x) (x##LLU)
817#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__)
818#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
819#define BYTESWAP32(x) (x)
820#define BYTESWAP64(x) (x)
823#elif defined(__i386) || defined(__x86_64) || defined(__alpha) || defined(__vax)
825#define BYTESWAP32(x) (x)
826#define BYTESWAP64(x) (x)
828#elif defined(__GNUC__) || defined(__clang__)
830#if __has_builtin(__builtin_bswap32)
831#define BYTESWAP32(x) __builtin_bswap32(x)
833#if __has_builtin(__builtin_bswap64)
834#define BYTESWAP64(x) __builtin_bswap64(x)
841#define BYTESWAP32(x) ((((x) & 0xFF) << 24) | (((x) >> 24) & 0xFF) | (((x) & 0x0000FF00) << 8) | (((x) & 0x00FF0000) >> 8))
845#define BYTESWAP64(x) \
846 (((uint64_t)(x) << 56) | \
847 (((uint64_t)(x) << 40) & 0X00FF000000000000ULL) | \
848 (((uint64_t)(x) << 24) & 0X0000FF0000000000ULL) | \
849 (((uint64_t)(x) << 8) & 0X000000FF00000000ULL) | \
850 (((uint64_t)(x) >> 8) & 0X00000000FF000000ULL) | \
851 (((uint64_t)(x) >> 24) & 0X0000000000FF0000ULL) | \
852 (((uint64_t)(x) >> 40) & 0X000000000000FF00ULL) | \
853 ((uint64_t)(x) >> 56))
862FORCE_INLINE uint32_t getblock32(
const uint32_t* p,
const size_t i) {
864 memcpy(&result, (
const uint8_t*)p + i * 4,
sizeof(result));
874FORCE_INLINE uint64_t getblock64(
const uint64_t* p,
const size_t i) {
876 memcpy(&result, (
const uint8_t*)p + i * 8,
sizeof(result));
924 const uint8_t* data = (
const uint8_t*)key;
925 const size_t nblocks = len / 4;
928 const uint32_t c1 = 0xcc9e2d51;
929 const uint32_t c2 = 0x1b873593;
931 const uint32_t* blocks = (
const uint32_t*)data;
933 for (
size_t i = 0; i < nblocks; i++) {
934 uint32_t k1 = getblock32(blocks, i);
941 h1 = h1 * 5 + 0xe6546b64;
944 const uint8_t* tail = data + nblocks * 4;
948 k1 ^= (uint32_t)tail[2] << 16;
951 k1 ^= (uint32_t)tail[1] << 8;
954 k1 ^= (uint32_t)tail[0];
966 *(uint32_t*)out = h1;
982 const uint8_t* data = (
const uint8_t*)key;
983 const size_t nblocks = len / 16;
990 const uint32_t c1 = 0x239b961b;
991 const uint32_t c2 = 0xab0e9789;
992 const uint32_t c3 = 0x38b34ae5;
993 const uint32_t c4 = 0xa1e38b93;
995 const uint32_t* blocks = (
const uint32_t*)data;
997 for (
size_t i = 0; i < nblocks; i++) {
998 uint32_t k1 = getblock32(blocks, i * 4 + 0);
999 uint32_t k2 = getblock32(blocks, i * 4 + 1);
1000 uint32_t k3 = getblock32(blocks, i * 4 + 2);
1001 uint32_t k4 = getblock32(blocks, i * 4 + 3);
1009 h1 = h1 * 5 + 0x561ccd1b;
1017 h2 = h2 * 5 + 0x0bcaa747;
1025 h3 = h3 * 5 + 0x96cd1c35;
1033 h4 = h4 * 5 + 0x32ac3b17;
1037 const uint8_t* tail = data + nblocks * 16;
1039 uint32_t k1 = 0, k2 = 0, k3 = 0, k4 = 0;
1043 k4 ^= (uint32_t)tail[14] << 16;
1046 k4 ^= (uint32_t)tail[13] << 8;
1049 k4 ^= (uint32_t)tail[12];
1057 k3 ^= (uint32_t)tail[11] << 24;
1060 k3 ^= (uint32_t)tail[10] << 16;
1063 k3 ^= (uint32_t)tail[9] << 8;
1066 k3 ^= (uint32_t)tail[8];
1074 k2 ^= (uint32_t)tail[7] << 24;
1077 k2 ^= (uint32_t)tail[6] << 16;
1080 k2 ^= (uint32_t)tail[5] << 8;
1083 k2 ^= (uint32_t)tail[4];
1091 k1 ^= (uint32_t)tail[3] << 24;
1094 k1 ^= (uint32_t)tail[2] << 16;
1097 k1 ^= (uint32_t)tail[1] << 8;
1100 k1 ^= (uint32_t)tail[0];
1111 h1 ^= (uint32_t)len;
1112 h2 ^= (uint32_t)len;
1113 h3 ^= (uint32_t)len;
1114 h4 ^= (uint32_t)len;
1131 ((uint32_t*)out)[0] = h1;
1132 ((uint32_t*)out)[1] = h2;
1133 ((uint32_t*)out)[2] = h3;
1134 ((uint32_t*)out)[3] = h4;
1150 const uint8_t* data = (
const uint8_t*)key;
1151 const size_t nblocks = len / 16;
1156 const uint64_t c1 = 0x87c37b91114253d5ULL;
1157 const uint64_t c2 = 0x4cf5ad432745937fULL;
1160 const uint64_t* blocks = (
const uint64_t*)data;
1161 for (
size_t i = 0; i < nblocks; i++) {
1162 uint64_t k1 = getblock64(blocks, i * 2 + 0);
1163 uint64_t k2 = getblock64(blocks, i * 2 + 1);
1172 h1 = h1 * 5 + 0x52dce729;
1181 h2 = h2 * 5 + 0x38495ab5;
1185 const uint8_t* tail = data + nblocks * 16;
1192 k2 ^= ((uint64_t)tail[14]) << 48;
1195 k2 ^= ((uint64_t)tail[13]) << 40;
1198 k2 ^= ((uint64_t)tail[12]) << 32;
1201 k2 ^= ((uint64_t)tail[11]) << 24;
1204 k2 ^= ((uint64_t)tail[10]) << 16;
1207 k2 ^= ((uint64_t)tail[9]) << 8;
1210 k2 ^= ((uint64_t)tail[8]);
1218 k1 ^= ((uint64_t)tail[7]) << 56;
1221 k1 ^= ((uint64_t)tail[6]) << 48;
1224 k1 ^= ((uint64_t)tail[5]) << 40;
1227 k1 ^= ((uint64_t)tail[4]) << 32;
1230 k1 ^= ((uint64_t)tail[3]) << 24;
1233 k1 ^= ((uint64_t)tail[2]) << 16;
1236 k1 ^= ((uint64_t)tail[1]) << 8;
1239 k1 ^= ((uint64_t)tail[0]);
1262 ((uint64_t*)out)[0] = h1;
1263 ((uint64_t*)out)[1] = h2;
1272 static char* HASH_TYPE_STR[5] = {
"HASH_INT",
"HASH_DOUBLE",
"HASH_STRING",
"HASH_PTR",
"HASH_UNKNOWN"};
1277 return HASH_TYPE_STR[node->
type];
1301 index = (hash_value[0]) % (table->
size);
1308 if (!strcmp(key, node_ptr->
key)) {
1329 if (strlen(key) == 0)
1336 new_hash_node->
key = strdup(key);
1337 new_hash_node->
key_id =
'\0';
1340 new_hash_node->
data.
ptr = NULL;
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) {
1389 n_log(
LOG_ERR,
"Could not get a new node in table %p with key %s", table, key);
1391 return new_hash_node;
1407 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;
1432 if (new_hash_node) {
1436 n_log(
LOG_ERR,
"Could not get a new node in table %p with key %s", table, key);
1438 return new_hash_node;
1455 if (new_hash_node) {
1456 new_hash_node->
data.
ptr = value;
1460 n_log(
LOG_ERR,
"Could not get a new node in table %p with key %s", table, key);
1462 return new_hash_node;
1474int _ht_put_int(
HASH_TABLE* table,
const char* key, HASH_INT_TYPE value) {
1485 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));
1489 int retcode = FALSE;
1490 node_ptr = _ht_new_int_node(table, key, value);
1494 if (retcode == TRUE) {
1519 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));
1523 int retcode = FALSE;
1528 if (retcode == TRUE) {
1559 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));
1563 int retcode = FALSE;
1568 if (retcode == TRUE) {
1595 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));
1599 int retcode = FALSE;
1604 if (retcode == TRUE) {
1631 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));
1635 int retcode = FALSE;
1640 if (retcode == TRUE) {
1654int _ht_get_int(
HASH_TABLE* table,
const char* key, HASH_INT_TYPE* val) {
1657 if (strlen(key) == 0)
1686 if (strlen(key) == 0)
1714 if (strlen(key) == 0)
1741 if (strlen(key) == 0)
1773 if (strlen(key) == 0)
1777 index = (hash_value[0]) % (table->
size);
1780 n_log(
LOG_ERR,
"Can't remove key[\"%s\"], table is empty", key);
1787 if (!strcmp(key, node_ptr->
key)) {
1788 node_to_kill = list_node;
1800 n_log(
LOG_ERR,
"Can't delete key[\"%s\"]: inexisting key", key);
1817 for (index = 0; index < table->
size; index++) {
1837 if ((*table)->hash_table) {
1841 for (it = 0; it < (*table)->size; it++) {
1842 if ((*table)->hash_table[it])
1845 Free((*table)->hash_table);
1861 printf(
"key:%s node:%s\n", ((
HASH_NODE*)node->ptr)->key, ((
HASH_NODE*)node->ptr)->key);
1883 if (node_is_matching(hnode) == TRUE) {
1934 n_log(
LOG_ERR,
"Couldn't allocate new_ht_trie with alphabet_length of %zu and alphabet offset of %d", alphabet_length, alphabet_offset);
1959 table->
seed = (uint32_t)rand() % 100000;
1967 for (it = 0; it < size; it++) {
1971 n_log(
LOG_ERR,
"Can't allocate table -> hash_table[ %d ] !", it);
1972 size_t it_delete = 0;
1973 for (it_delete = 0; it_delete < it; it_delete++) {
2034int ht_get_int(
HASH_TABLE* table,
const char* key, HASH_INT_TYPE* val) {
2050 return table->
ht_get_ptr(table, key, &(*val));
2086int ht_put_int(
HASH_TABLE* table,
const char* key, HASH_INT_TYPE value) {
2103 return table->
ht_put_ptr(table, key, ptr, destructor);
2162 return table->
ht_search(table, node_is_matching);
2182 return (*table)->destroy_ht(table);
2198 index = (hash_value) % (table->
size);
2253 index = (hash_value) % (table->
size);
2262 if (list_node->destroy_func) {
2263 list_node->destroy_func(node_ptr->
data.
ptr);
2265 list_node->destroy_func = destructor;
2269 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));
2277 new_hash_node->
key = NULL;
2279 new_hash_node->
data.
ptr = val;
2302 index = (hash_value) % (table->
size);
2304 n_log(
LOG_ERR,
"Can't remove key[\"%d\"], table is empty", hash_value);
2312 node_to_kill = list_node;
2324 n_log(
LOG_ERR,
"Can't delete key[\"%d\"]: inexisting key", hash_value);
2339 LIST* results = new_generic_list(max_results);
2343 if (
list_push(results, strdup(keybud), &free) == TRUE) {
2350 char new_keybud[3] =
"";
2352 list_push(results, strdup(new_keybud), &free);
2359 if (strncasecmp(keybud, hnode->
key, strlen(keybud)) == 0) {
2360 char* key = strdup(hnode->
key);
2361 if (
list_push(results, key, &free) == FALSE) {
2371 if (results && results->
nb_items < 1)
2381int is_prime(
size_t nb) {
2383 if (nb <= 1)
return FALSE;
2384 if (nb <= 3)
return TRUE;
2387 if ((nb % 2 == 0) || (nb % 3 == 0))
2391 for (
size_t it = 5; it * it <= nb; it = it + 6) {
2392 if ((nb % it == 0) || (nb % (it + 2) == 0))
2403size_t next_prime(
size_t nb) {
2407 size_t next_prime = nb;
2410 }
while (is_prime(next_prime) == FALSE);
2424 if (table->
size == 0)
return FALSE;
2426 size_t nb_collisionned_lists = 0;
2428 for (
size_t hash_it = 0; hash_it < table->
size; hash_it++) {
2430 nb_collisionned_lists++;
2433 size_t collision_percentage = (100 * nb_collisionned_lists) / table->
size;
2434 return (
int)collision_percentage;
2445 size_t optimum_size = (size_t)((
double)table->
nb_keys * 1.3);
2446 if (is_prime(optimum_size) != TRUE)
2447 optimum_size = next_prime(optimum_size);
2448 return optimum_size;
2461 n_log(
LOG_ERR,
"invalid size %d for hash table %p", size, (*table));
2466 if (size > (*table)->size) {
2468 if (!(*table)->hash_table) {
2469 n_log(
LOG_ERR,
"Realloc did not augment the size the table !");
2471 for (
size_t it = (*table)->size; it < size; it++) {
2474 if (!(*table)->hash_table[it]) {
2475 n_log(
LOG_ERR,
"Can't allocate table -> hash_table[ %d ] !", it);
2476 for (
size_t it_delete = 0; it_delete < it; it_delete++) {
2479 Free((*table)->hash_table);
2484 for (
size_t it = 0; it < size; it++) {
2485 if (((*table)->hash_table[it])) {
2486 while ((*table)->hash_table[it]->start) {
2493 size_t index = (hash_node->
hash_value) % (size);
2500 for (
size_t it = 0; it < (*table)->size; it++) {
2501 if (((*table)->hash_table[it])) {
2502 while ((*table)->hash_table[it]->start) {
2509 size_t index = (hash_node->
hash_value) % (size);
2514 for (
size_t it = size; it < (*table)->size; it++) {
2518 if (!(*table)->hash_table) {
2519 n_log(
LOG_ERR,
"Realloc did not reduce the resize the table !");
2522 (*table)->size = size;
2536 if (optimal_size == FALSE) {
2541 if (collision_percentage == FALSE)
2544 int resize_result =
ht_resize(&(*table), optimal_size);
2545 if (resize_result == FALSE) {
2550 if (collision_percentage == FALSE) {
#define FreeNoLog(__ptr)
Free Handler without log.
#define FALL_THROUGH
fall through macro for switch cases, avoid warning at compilation
#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 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.
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_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.
#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 _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.
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)
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
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.
void _ht_print_trie_helper(HASH_TABLE *table, HASH_NODE *node)
Recursive function to print trie tree's keys and values.
size_t _ht_check_trie_divergence(HASH_TABLE *table, const char *key)
check and return branching index in key if any
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.
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.
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
#define ROTL32(x, r)
32 bit rotate left
Hash functions and table.
N_STR and string function declaration.