38 new_hash_node -> key = NULL ;
39 new_hash_node -> hash_value = 0 ;
40 new_hash_node -> data. ptr = NULL ;
41 new_hash_node -> destroy_func = NULL ;
42 new_hash_node -> children = NULL ;
43 new_hash_node -> is_leaf = 0 ;
44 new_hash_node -> need_rehash = 0 ;
45 new_hash_node -> alphabet_length = table -> alphabet_length ;
47 Malloc( new_hash_node -> children,
HASH_NODE *, table -> alphabet_length );
48 __n_assert( new_hash_node -> children,
n_log(
LOG_ERR,
"Could not allocate new_hash_node" );
Free( new_hash_node );
return NULL );
52 for(
size_t it = 0 ; it < table -> alphabet_length ; it++ )
54 new_hash_node -> children[ it ] = NULL;
56 new_hash_node -> is_leaf = 0 ;
57 new_hash_node -> key_id = key ;
78 for(
size_t it = 0 ; key[ it ] !=
'\0' ; it++ )
80 size_t index = (size_t)key[ it ] - table -> alphabet_offset ;
81 if( index >= table -> alphabet_length )
83 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it, key );
87 if( node -> children[ index ] == NULL )
91 __n_assert( node -> children[ index ],
return FALSE );
98 node = node -> children[ index ];
103 node -> key = strdup( key );
105 node -> data . ival = value ;
108 table -> nb_keys ++ ;
131 for(
size_t it = 0 ; key[ it ] !=
'\0' ; it++ )
133 size_t index = (size_t)key[ it ] - table -> alphabet_offset ;
134 if( index >= table -> alphabet_length )
136 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it, key );
139 if( node -> children[ index ] == NULL )
143 __n_assert( node -> children[ index ],
return FALSE );
150 node = node -> children[ index ];
155 node -> key = strdup( key );
157 node -> data . fval = value ;
160 table -> nb_keys ++ ;
183 for(
size_t it = 0 ; key[ it ] !=
'\0' ; it++ )
185 size_t index = (size_t)key[ it ] - table -> alphabet_offset ;
186 if( index >= table -> alphabet_length )
188 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it, key );
191 if( node -> children[ index ] == NULL )
195 __n_assert( node -> children[ index ],
return FALSE );
202 node = node -> children[ index ];
207 node -> key = strdup( key );
210 node -> data .
string = strdup(
string );
212 node -> data .
string = NULL ;
216 table -> nb_keys ++ ;
239 for(
size_t it = 0 ; key[ it ] !=
'\0' ; it++ )
241 size_t index = (size_t)key[ it ] - table -> alphabet_offset ;
242 if( index >= table -> alphabet_length )
244 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it, key );
247 if( node -> children[ index ] == NULL )
251 __n_assert( node -> children[ index ],
return FALSE );
258 node = node -> children[ index ];
263 node -> key = strdup( key );
265 node -> data .
string = string ;
268 table -> nb_keys ++ ;
292 for(
size_t it = 0 ; key[ it ] !=
'\0' ; it++ )
294 size_t index = ( (size_t)(key[ it ] - table -> alphabet_offset) ) % table -> alphabet_length;
295 if( index >= table -> alphabet_length )
297 n_log(
LOG_ERR,
"Invalid value %u for charater at position %d of %s, set to 0", index, it, key );
300 if( node -> children[ index ] == NULL )
304 __n_assert( node -> children[ index ],
return FALSE );
311 node = node -> children[ index ];
316 node -> key = strdup( key );
318 node -> data . ptr = ptr ;
320 node -> destroy_func = destructor ;
323 table -> nb_keys ++ ;
345 if( key[ 0 ] !=
'\0' )
347 node = table -> root;
348 for(
size_t it = 0 ; key[ it ] !=
'\0' ; it++ )
350 size_t index = (size_t)key[ it ] - table -> alphabet_offset ;
351 if( index >= table -> alphabet_length )
353 n_log(
LOG_DEBUG,
"Invalid value %d for charater at index %d of %s, set to 0", index, it, key );
356 if( node -> children[ index ] == NULL )
361 node = node -> children[ index ];
384 if( strlen( key ) == 0 )
389 if( !node || !node -> is_leaf )
398 (*val) = node -> data . ival ;
416 if( strlen( key ) == 0 )
421 if( !node || !node -> is_leaf )
430 (*val) = node -> data . fval ;
448 if( strlen( key ) == 0 )
453 if( !node || !node -> is_leaf )
462 (*val) = node -> data . string ;
479 if( strlen( key ) == 0 )
484 if( !node || !node -> is_leaf )
493 (*val) = node -> data . ptr ;
517 for(
size_t it = 0 ; key[ it ] !=
'\0' ; it ++ )
519 size_t index = (size_t)key[ it ] - table -> alphabet_offset ;
520 if( index >= table -> alphabet_length )
522 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it, key );
525 if( node -> children[ index ] )
528 for(
size_t it2 = 0 ; it2 < table -> alphabet_length ; it2++ )
530 if( it2 != (
unsigned)index && node -> children[ it2 ] )
559 int len = strlen( key );
562 char *longest_prefix = NULL ;
563 Malloc( longest_prefix,
char, len + 1 );
564 memcpy( longest_prefix, key, len );
568 if(branch_index >= 0 )
571 longest_prefix[ branch_index ] =
'\0';
572 Realloc( longest_prefix,
char, (branch_index + 1) );
573 if( !longest_prefix )
575 n_log(
LOG_ERR,
"reallocation error, stopping find longest prefix" );
580 return longest_prefix;
599 for(
size_t it = 0 ; key[ it ] ; it++ )
601 size_t index = (size_t)key[ it ] - table -> alphabet_offset ;
602 if( index >= table -> alphabet_length )
604 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it, key );
607 if( node -> children[ index ] )
609 node = node -> children[ index ];
612 return node -> is_leaf ;
629 Free( node_ptr -> data .
string );
633 if( node_ptr -> destroy_func && node_ptr -> data . ptr )
635 node_ptr -> destroy_func( node_ptr -> data . ptr );
645 if( node_ptr -> alphabet_length > 0 )
647 for(
size_t it = 0 ; it < node_ptr -> alphabet_length ; it ++ )
649 if( node_ptr -> children[ it ] )
654 Free( node_ptr -> children );
684 if( longest_prefix && longest_prefix[ 0 ] ==
'\0' )
686 Free( longest_prefix );
691 for( it = 0 ; longest_prefix[ it ] !=
'\0'; it++ )
693 size_t index = (size_t)longest_prefix[ it ] - table -> alphabet_offset ;
694 if( index >= table -> alphabet_length )
696 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it, key );
699 if( node -> children[ index ] != NULL )
702 node = node -> children[ index ];
707 Free( longest_prefix );
713 for( ; key[ it ] !=
'\0' ; it++ )
715 size_t index = (size_t)key[ it ] - table -> alphabet_offset ;
716 if( index >= table -> alphabet_length )
718 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it, key );
721 if( node -> children[ index] )
724 HASH_NODE* node_to_kill = node -> children[ index ];
725 node -> children[ index ] = NULL;
729 Free( longest_prefix );
731 table -> nb_keys -- ;
753 table -> nb_keys = 0 ;
791 if( node -> is_leaf )
793 printf(
"key: %s, val: ", node -> key );
794 switch( node -> type )
797 printf(
"int: %d", node -> data . ival );
800 printf(
"double: %f", node -> data . fval );
803 printf(
"ptr: %p", node -> data . ptr );
806 printf(
"%s", node -> data .
string );
809 printf(
"unknwow type %d", node -> type );
814 for(
size_t it = 0 ; it < table -> alphabet_length ; it++ )
852 if( node -> is_leaf )
854 if( node_is_matching( node ) == TRUE )
856 list_push( results, strdup( node -> key ), &free );
859 for(
size_t it = 0 ; it < node -> alphabet_length ; it++ )
883 if( results -> nb_items < 1 )
906 for(
size_t it = 0; it < node -> alphabet_length ; it++ )
910 if( node -> is_leaf )
912 if( results -> nb_items < results -> nb_max_items )
914 return list_push( results, strdup( node -> key ), &free );
925#define ROTL64(x, r) (((x) << (r)) | ((x) >> (64 - (r))))
927#define ROTL32(x, r) (((x) << (r)) | ((x) >> (32 - (r))))
929#define BIG_CONSTANT(x) (x##LLU)
932#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__)
933# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
934# define BYTESWAP32(x) (x)
935# define BYTESWAP64(x) (x)
938#elif defined(__i386) || defined(__x86_64) \
939 || defined(__alpha) || defined(__vax)
941# define BYTESWAP32(x) (x)
942# define BYTESWAP64(x) (x)
944#elif defined(__GNUC__) || defined(__clang__)
946# if __has_builtin(__builtin_bswap32)
947# define BYTESWAP32(x) __builtin_bswap32(x)
949# if __has_builtin(__builtin_bswap64)
950# define BYTESWAP64(x) __builtin_bswap64(x)
957# define BYTESWAP32(x) ((((x)&0xFF)<<24) \
959 |(((x)&0x0000FF00)<<8) \
960 |(((x)&0x00FF0000)>>8) )
964# define BYTESWAP64(x) \
965 (((uint64_t)(x) << 56) | \
966 (((uint64_t)(x) << 40) & 0X00FF000000000000ULL) | \
967 (((uint64_t)(x) << 24) & 0X0000FF0000000000ULL) | \
968 (((uint64_t)(x) << 8) & 0X000000FF00000000ULL) | \
969 (((uint64_t)(x) >> 8) & 0X00000000FF000000ULL) | \
970 (((uint64_t)(x) >> 24) & 0X0000000000FF0000ULL) | \
971 (((uint64_t)(x) >> 40) & 0X000000000000FF00ULL) | \
972 ((uint64_t)(x) >> 56))
1049 const uint8_t * data = (
const uint8_t*)key;
1050 const int nblocks = len / 4;
1054 uint32_t c1 = 0xcc9e2d51;
1055 uint32_t c2 = 0x1b873593;
1058 const uint32_t * blocks = (
const uint32_t *)(data + nblocks*4);
1061 for(i = -nblocks; i; i++)
1071 h1 = h1*5+0xe6546b64;
1075 const uint8_t * tail = (
const uint8_t*)(data + nblocks*4);
1082 k1 ^= tail[2] << 16;
1100 *(uint32_t*)out = h1;
1119 const uint8_t * data = (
const uint8_t*)key;
1120 const int nblocks = len / 16;
1127 uint32_t c1 = 0x239b961b;
1128 uint32_t c2 = 0xab0e9789;
1129 uint32_t c3 = 0x38b34ae5;
1130 uint32_t c4 = 0xa1e38b93;
1133 const uint32_t * blocks = (
const uint32_t *)(data + nblocks*16);
1136 for( i = -nblocks ; i; i++)
1149 h1 = h1*5+0x561ccd1b;
1157 h2 = h2*5+0x0bcaa747;
1165 h3 = h3*5+0x96cd1c35;
1173 h4 = h4*5+0x32ac3b17;
1177 const uint8_t * tail = (
const uint8_t*)(data + nblocks*16);
1187 k4 ^= tail[14] << 16;
1190 k4 ^= tail[13] << 8;
1193 k4 ^= tail[12] << 0;
1200 k3 ^= tail[11] << 24;
1203 k3 ^= tail[10] << 16;
1206 k3 ^= tail[ 9] << 8;
1209 k3 ^= tail[ 8] << 0;
1216 k2 ^= tail[ 7] << 24;
1219 k2 ^= tail[ 6] << 16;
1222 k2 ^= tail[ 5] << 8;
1225 k2 ^= tail[ 4] << 0;
1232 k1 ^= tail[ 3] << 24;
1235 k1 ^= tail[ 2] << 16;
1238 k1 ^= tail[ 1] << 8;
1241 k1 ^= tail[ 0] << 0;
1274 ((uint32_t*)out)[0] = h1;
1275 ((uint32_t*)out)[1] = h2;
1276 ((uint32_t*)out)[2] = h3;
1277 ((uint32_t*)out)[3] = h4;
1296 const uint8_t * data = (
const uint8_t*)key;
1297 const size_t nblocks = len / 16;
1305 const uint64_t * blocks = (
const uint64_t *)(data);
1306 const uint8_t * tail = (
const uint8_t*)(data + nblocks*16);
1311 for(
size_t i = 0; i < nblocks; i++)
1323 h1 = h1*5+0x52dce729;
1332 h2 = h2*5+0x38495ab5;
1339 k2 ^= ((uint64_t)tail[14]) << 48;
1342 k2 ^= ((uint64_t)tail[13]) << 40;
1345 k2 ^= ((uint64_t)tail[12]) << 32;
1348 k2 ^= ((uint64_t)tail[11]) << 24;
1351 k2 ^= ((uint64_t)tail[10]) << 16;
1354 k2 ^= ((uint64_t)tail[ 9]) << 8;
1357 k2 ^= ((uint64_t)tail[ 8]) << 0;
1365 k1 ^= ((uint64_t)tail[ 7]) << 56;
1368 k1 ^= ((uint64_t)tail[ 6]) << 48;
1371 k1 ^= ((uint64_t)tail[ 5]) << 40;
1374 k1 ^= ((uint64_t)tail[ 4]) << 32;
1377 k1 ^= ((uint64_t)tail[ 3]) << 24;
1380 k1 ^= ((uint64_t)tail[ 2]) << 16;
1383 k1 ^= ((uint64_t)tail[ 1]) << 8;
1386 k1 ^= ((uint64_t)tail[ 0]) << 0;
1410 ((uint64_t*)out)[0] = h2;
1411 ((uint64_t*)out)[1] = h1;
1424 static char *HASH_TYPE_STR[ 5 ] = {
"HASH_INT",
"HASH_DOUBLE",
"HASH_STRING",
"HASH_PTR",
"HASH_UNKNOWN" };
1429 return HASH_TYPE_STR[ node -> type ];
1451 if( key[ 0 ] ==
'\0' )
1454 MurmurHash( key, strlen( key ), table -> seed, &hash_value );
1455 index= (hash_value[ 0 ])%(table->
size);
1457 if( ! table -> hash_table[ index ] -> start )
1460 list_foreach( list_node, table -> hash_table[ index ] )
1462 node_ptr = (
HASH_NODE *)list_node -> ptr ;
1463 if( !strcmp( key, node_ptr -> key ) )
1488 if( strlen( key ) == 0 )
1491 MurmurHash( key, strlen( key ), table -> seed, &hash_value );
1495 new_hash_node -> key = strdup( key );
1496 new_hash_node -> key_id =
'\0' ;
1497 __n_assert( new_hash_node -> key,
n_log(
LOG_ERR,
"Could not allocate new_hash_node->key" );
Free( new_hash_node );
return NULL );
1498 new_hash_node -> hash_value = hash_value[ 0 ] ;
1499 new_hash_node -> data. ptr = NULL ;
1500 new_hash_node -> destroy_func = NULL ;
1501 new_hash_node -> children = NULL ;
1502 new_hash_node -> is_leaf = 0 ;
1503 new_hash_node -> need_rehash = 0 ;
1504 new_hash_node -> alphabet_length = 0 ;
1506 return new_hash_node ;
1525 new_hash_node -> data . ival = value ;
1527 return new_hash_node ;
1546 new_hash_node -> data . fval = value ;
1548 return new_hash_node ;
1568 new_hash_node -> data .
string = strdup( value );
1570 new_hash_node -> data .
string = NULL ;
1572 return new_hash_node ;
1591 new_hash_node -> data .
string = value ;
1593 return new_hash_node ;
1613 new_hash_node -> data . ptr = value ;
1614 new_hash_node -> destroy_func = destructor ;
1616 return new_hash_node ;
1641 node_ptr -> data . ival = value ;
1644 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 ) );
1650 size_t index = ( node_ptr -> hash_value )%( table -> size );
1652 if( retcode == TRUE )
1654 table -> nb_keys ++ ;
1679 node_ptr -> data . fval = value ;
1682 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 ) );
1688 HASH_VALUE index = ( node_ptr -> hash_value )%( table -> size );
1690 if( retcode == TRUE )
1692 table -> nb_keys ++ ;
1719 if( node_ptr -> destroy_func )
1721 node_ptr -> destroy_func( node_ptr -> data . ptr );
1722 node_ptr -> data . ptr = ptr ;
1723 node_ptr -> destroy_func = destructor ;
1727 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 ) );
1733 HASH_VALUE index = ( node_ptr -> hash_value )%( table -> size );
1735 if( retcode == TRUE )
1737 table -> nb_keys ++ ;
1763 Free( node_ptr -> data .
string );
1764 node_ptr -> data .
string = strdup(
string );
1767 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 ) );
1773 HASH_VALUE index = ( node_ptr -> hash_value )%( table -> size );
1775 if( retcode == TRUE )
1777 table -> nb_keys ++ ;
1803 Free( node_ptr -> data .
string );
1804 node_ptr -> data .
string = string ;
1807 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 ) );
1813 HASH_VALUE index = ( node_ptr -> hash_value )%( table -> size );
1815 if( retcode == TRUE )
1817 table -> nb_keys ++ ;
1837 if( strlen( key ) == 0 )
1851 (*val) = node -> data . ival ;
1870 if( strlen( key ) == 0 )
1884 (*val) = node -> data . fval ;
1902 if( strlen( key ) == 0 )
1915 (*val) = node -> data . ptr ;
1933 if( strlen( key ) == 0 )
1946 (*val) = node -> data . string ;
1969 if( strlen( key ) == 0 )
1972 MurmurHash( key, strlen( key ), table -> seed, &hash_value );
1973 index= (hash_value[ 0 ])%(table->
size) ;
1975 if( !table -> hash_table[ index ] -> start )
1977 n_log(
LOG_ERR,
"Can't remove key[\"%s\"], table is empty", key );
1981 list_foreach( list_node, table -> hash_table[ index ] )
1983 node_ptr = (
HASH_NODE *)list_node -> ptr ;
1985 if( !strcmp( key, node_ptr -> key ) )
1987 node_to_kill = list_node ;
1996 table -> nb_keys -- ;
2000 n_log(
LOG_ERR,
"Can't delete key[\"%s\"]: inexisting key", key );
2020 for( index = 0 ; index < table -> size ; index ++ )
2022 while( table -> hash_table[ index ] && table -> hash_table[ index ] -> start )
2028 table -> nb_keys = 0 ;
2045 if( (*table )-> hash_table )
2050 for( it = 0 ; it < (*table) -> size ; it ++ )
2052 if( (*table) -> hash_table[ it ] )
2055 Free( (*table )->hash_table );
2074 printf(
"key:%s node:%s\n", ((
HASH_NODE *)node ->ptr)->key, ((
HASH_NODE *)node ->ptr)->key );
2099 if( node_is_matching( hnode ) == TRUE )
2101 list_push( results, strdup( hnode -> key ), &free );
2105 if( results -> nb_items < 1 )
2132 table -> nb_keys = 0 ;
2134 table -> hash_table = NULL ;
2151 table -> alphabet_length = alphabet_length ;
2152 table -> alphabet_offset = alphabet_offset ;
2173 n_log(
LOG_ERR,
"Invalide size %d for new_ht()", size );
2179 table -> size = size ;
2180 table -> seed = (uint32_t)rand()%100000 ;
2181 table -> nb_keys = 0 ;
2185 __n_assert( table -> hash_table,
n_log(
LOG_ERR,
"Can't allocate table -> hash_table with size %d !", size );
Free( table );
return NULL );
2188 for( it = 0 ; it < size ; it ++ )
2192 if( !table -> hash_table[ it ] )
2194 n_log(
LOG_ERR,
"Can't allocate table -> hash_table[ %d ] !", it );
2195 size_t it_delete = 0 ;
2196 for( it_delete = 0 ; it_delete < it ; it_delete ++ )
2200 Free( table -> hash_table );
2286 return table ->
ht_get_ptr( table, key, &(*val) );
2334 return table->
ht_put_int( table, key, value );
2351 return table->
ht_put_ptr( table, key, ptr, destructor );
2425 return table ->
ht_search( table, node_is_matching );
2451 return (*table)->destroy_ht( table );
2470 index= (hash_value)%(table->
size) ;
2471 if( !table -> hash_table[ index ] -> start )
2476 list_foreach( list_node, table -> hash_table[ index ] )
2478 node_ptr = (
HASH_NODE *)list_node -> ptr ;
2479 if( hash_value == node_ptr -> hash_value )
2511 (*val) = node -> data . ptr ;
2535 index = (hash_value)%(table->
size) ;
2538 list_foreach( list_node, table -> hash_table[ index ] )
2540 node_ptr = (
HASH_NODE *)list_node -> ptr ;
2542 if( hash_value == node_ptr -> hash_value )
2547 if( list_node -> destroy_func )
2549 list_node -> destroy_func( node_ptr -> data . ptr );
2550 node_ptr -> data . ptr = val ;
2551 list_node -> destroy_func = destructor ;
2555 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 ) );
2563 new_hash_node -> key = NULL ;
2564 new_hash_node -> hash_value = hash_value ;
2565 new_hash_node -> data . ptr = val ;
2567 new_hash_node -> destroy_func = destructor ;
2569 table -> nb_keys ++ ;
2591 index= (hash_value)%(table->
size) ;
2592 if( !table -> hash_table[ index ] -> start )
2594 n_log(
LOG_ERR,
"Can't remove key[\"%d\"], table is empty", hash_value );
2598 list_foreach( list_node, table -> hash_table[ index ] )
2600 node_ptr = (
HASH_NODE *)list_node -> ptr ;
2602 if( hash_value == node_ptr -> hash_value )
2604 node_to_kill = list_node ;
2613 table -> nb_keys -- ;
2617 n_log(
LOG_ERR,
"Can't delete key[\"%d\"]: inexisting key", hash_value );
2635 LIST *results = NULL ;
2643 if(
list_push( results, strdup( keybud ), &free ) == TRUE )
2651 node = table -> root ;
2652 for(
size_t it = 0 ; it < table -> alphabet_length ; it++ )
2654 if( node -> children[ it ] )
2656 char keybud[ 3 ] =
"" ;
2657 keybud[ 0 ] = it + table -> alphabet_offset ;
2658 list_push( results , strdup( keybud ), &free );
2663 if( found == FALSE )
2670 if( strncasecmp( keybud, node -> key, strlen( keybud ) ) == 0 )
2674 results =
ht_search( table, &matching_nodes );
2678 n_log(
LOG_ERR,
"unsupported mode %d", table -> mode );
2693 if( nb <= 1 )
return FALSE ;
2694 if( nb <= 3 )
return TRUE ;
2697 if( (nb%2 == 0) || (nb%3 == 0) )
2701 for(
int it = 5 ; it*it <= nb ; it = it + 6 )
2703 if( (nb%it == 0) || (nb%( it + 2 ) == 0) )
2743 if( table -> size == 0 )
return FALSE ;
2745 int nb_collisionned_lists = 0 ;
2747 for(
size_t hash_it = 0 ; hash_it < table -> size ; hash_it ++ )
2749 if( table -> hash_table[ hash_it ] && table -> hash_table[ hash_it ] -> nb_items > 1 )
2751 nb_collisionned_lists ++ ;
2754 int collision_percentage = ( 100 * nb_collisionned_lists ) / table -> size ;
2755 return collision_percentage ;
2769 int optimum_size = (double)table -> nb_keys * 1.3 ;
2770 if(
is_prime( optimum_size ) != TRUE )
2773 return optimum_size ;
2791 n_log(
LOG_ERR,
"invalid size %d for hash table %p", size, (*table) );
2794 HT_FOREACH( node, (*table), { node -> need_rehash = 1 ; } );
2796 if( size > (*table) -> size )
2799 if( !(*table) -> hash_table )
2801 n_log(
LOG_ERR,
"Realloc did not augment the size the table !" );
2805 for(
size_t it = (*table) -> size ; it < size ; it ++ )
2809 if( !(*table) -> hash_table[ it ] )
2811 n_log(
LOG_ERR,
"Can't allocate table -> hash_table[ %d ] !", it );
2812 for(
size_t it_delete = 0 ; it_delete < it ; it_delete ++ )
2816 Free( (*table) -> hash_table );
2821 for(
size_t it = 0 ; it < size ; it ++ )
2823 if( ( (*table) -> hash_table[ it ] ) )
2825 while( (*table) -> hash_table[ it ] -> start )
2828 if( hash_node -> need_rehash == 0 )
2830 hash_node -> need_rehash = 0 ;
2832 node -> next = node -> prev = NULL ;
2833 size_t index= (hash_node -> hash_value)%(size);
2842 for(
size_t it = 0 ; it < (*table) -> size ; it ++ )
2844 if( ( (*table) -> hash_table[ it ] ) )
2846 while( (*table) -> hash_table[ it ] -> start )
2849 if( hash_node -> need_rehash == 0 )
2851 hash_node -> need_rehash = 0 ;
2853 node -> next = node -> prev = NULL ;
2854 size_t index= (hash_node -> hash_value)%(size);
2859 for(
size_t it = size ; it < (*table) -> size ; it ++ )
2864 if( !(*table) -> hash_table )
2866 n_log(
LOG_ERR,
"Realloc did not reduce the resize the table !" );
2869 (*table) -> size = size ;
2886 if( optimal_size == FALSE )
2892 if( collision_percentage == FALSE )
2895 int resize_result =
ht_resize( &(*table), optimal_size );
2896 if( resize_result == FALSE )
2902 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.
HASH_NODE *(* ht_get_node)(struct HASH_TABLE *table, const char *key)
get HASH_NODE at 'key' from table
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
int(* ht_put_int)(struct HASH_TABLE *table, const char *key, int val)
put an integer
int(* ht_get_double)(struct HASH_TABLE *table, const char *key, double *val)
get a double from a key's node
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.
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, int *val)
get an int from a key's node
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)
int ht_get_int(HASH_TABLE *table, const char *key, int *val)
get node at 'key' from 'table'
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)
void MurmurHash3_x86_32(const void *key, int len, uint32_t seed, void *out)
MurmurHash3 was written by Austin Appleby, and is placed in the public domain.
#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'
int next_prime(int nb)
compute next prime number after nb
#define HASH_DOUBLE
value of double type inside the hash node
int empty_ht(HASH_TABLE *table)
empty a table
int is_prime(int nb)
test if number is a prime number or not
#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
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
void MurmurHash3_x86_128(const void *key, const int len, uint32_t seed, void *out)
MurmurHash3 was written by Austin Appleby, and is placed in the public domain.
int ht_resize(HASH_TABLE **table, size_t size)
rehash table according to size (HASH_CLASSIC mode only)
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
int ht_put_int(HASH_TABLE *table, const char *key, int value)
put an integral value with given key in the targeted hash table
#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
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_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...
#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
#define remove_list_node(__LIST_,__NODE_, __TYPE_)
Remove macro helper for void pointer casting.
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.
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(int max_items)
Initialiaze a generic list container to max_items pointers.
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 hugly functions & define.
void _ht_node_destroy(void *node)
destroy a HASH_NODE by first calling the HASH_NODE destructor
static FORCE_INLINE uint64_t fmix64(uint64_t k)
Finalization mix - force all bits of a hash block to avalanche (from murmur's author)
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
int _ht_put_int_trie(HASH_TABLE *table, const char *key, int value)
put an integral value with given key in the targeted hash table [TRIE 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_put_int(HASH_TABLE *table, const char *key, int value)
put an integral value with given key in the targeted hash table [CLASSIC 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.
int _ht_check_trie_divergence(HASH_TABLE *table, const char *key)
check and return branching index in key if any
HASH_NODE * _ht_new_int_node(HASH_TABLE *table, const char *key, int value)
node creation, HASH_CLASSIC mode
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
static FORCE_INLINE uint64_t getblock64(const uint64_t *p, const size_t i)
Block read - modified from murmur's author, ajusted byte endianess.
static FORCE_INLINE uint32_t getblock32(const uint32_t *p, const size_t i)
Block read - modified from murmur's author, ajusted byte endianess
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)
static FORCE_INLINE uint32_t fmix32(uint32_t h)
Finalization mix - force all bits of a hash block to avalanche (from murmur's author)
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_get_int(HASH_TABLE *table, const char *key, int *val)
Retrieve an integral value in the hash table, at the given key.
int _ht_remove_trie(HASH_TABLE *table, const char *key)
Remove a key from a trie table and destroy the node.
int _ht_get_int_trie(HASH_TABLE *table, const char *key, int *val)
Retrieve an integral value in the hash table, at the given key.
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.