39 new_hash_node -> key = NULL ;
40 new_hash_node -> hash_value = 0 ;
41 new_hash_node -> data. ptr = NULL ;
42 new_hash_node -> destroy_func = NULL ;
43 new_hash_node -> children = NULL ;
44 new_hash_node -> is_leaf = 0 ;
45 new_hash_node -> need_rehash = 0 ;
46 new_hash_node -> alphabet_length = table -> alphabet_length ;
48 Malloc( new_hash_node -> children,
HASH_NODE *, table -> alphabet_length );
49 __n_assert( new_hash_node -> children,
n_log(
LOG_ERR,
"Could not allocate new_hash_node" );
Free( new_hash_node );
return NULL );
53 for(
size_t it = 0 ; it < table -> alphabet_length ; it++ )
55 new_hash_node -> children[ it ] = NULL;
57 new_hash_node -> is_leaf = 0 ;
58 new_hash_node -> key_id = key ;
79 for(
size_t it = 0 ; key[ it ] !=
'\0' ; it++ )
81 size_t index = (size_t)key[ it ] - table -> alphabet_offset ;
82 if( index >= table -> alphabet_length )
84 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it, key );
88 if( node -> children[ index ] == NULL )
92 __n_assert( node -> children[ index ],
return FALSE );
99 node = node -> children[ index ];
104 node -> key = strdup( key );
106 node -> data . ival = value ;
109 table -> nb_keys ++ ;
132 for(
size_t it = 0 ; key[ it ] !=
'\0' ; it++ )
134 size_t index = (size_t)key[ it ] - table -> alphabet_offset ;
135 if( index >= table -> alphabet_length )
137 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it, key );
140 if( node -> children[ index ] == NULL )
144 __n_assert( node -> children[ index ],
return FALSE );
151 node = node -> children[ index ];
156 node -> key = strdup( key );
158 node -> data . fval = value ;
161 table -> nb_keys ++ ;
184 for(
size_t it = 0 ; key[ it ] !=
'\0' ; it++ )
186 size_t index = (size_t)key[ it ] - table -> alphabet_offset ;
187 if( index >= table -> alphabet_length )
189 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it, key );
192 if( node -> children[ index ] == NULL )
196 __n_assert( node -> children[ index ],
return FALSE );
203 node = node -> children[ index ];
208 node -> key = strdup( key );
211 node -> data .
string = strdup(
string );
213 node -> data .
string = NULL ;
217 table -> nb_keys ++ ;
240 for(
size_t it = 0 ; key[ it ] !=
'\0' ; it++ )
242 size_t index = (size_t)key[ it ] - table -> alphabet_offset ;
243 if( index >= table -> alphabet_length )
245 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it, key );
248 if( node -> children[ index ] == NULL )
252 __n_assert( node -> children[ index ],
return FALSE );
259 node = node -> children[ index ];
264 node -> key = strdup( key );
266 node -> data .
string = string ;
269 table -> nb_keys ++ ;
293 for(
size_t it = 0 ; key[ it ] !=
'\0' ; it++ )
295 size_t index = ( (size_t)(key[ it ] - table -> alphabet_offset) ) % table -> alphabet_length;
296 if( index >= table -> alphabet_length )
298 n_log(
LOG_ERR,
"Invalid value %u for charater at position %d of %s, set to 0", index, it, key );
301 if( node -> children[ index ] == NULL )
305 __n_assert( node -> children[ index ],
return FALSE );
312 node = node -> children[ index ];
317 node -> key = strdup( key );
319 node -> data . ptr = ptr ;
321 node -> destroy_func = destructor ;
324 table -> nb_keys ++ ;
346 if( key[ 0 ] !=
'\0' )
348 node = table -> root;
349 for(
size_t it = 0 ; key[ it ] !=
'\0' ; it++ )
351 size_t index = (size_t)key[ it ] - table -> alphabet_offset ;
352 if( index >= table -> alphabet_length )
354 n_log(
LOG_DEBUG,
"Invalid value %d for charater at index %d of %s, set to 0", index, it, key );
357 if( node -> children[ index ] == NULL )
362 node = node -> children[ index ];
385 if( strlen( key ) == 0 )
390 if( !node || !node -> is_leaf )
399 (*val) = node -> data . ival ;
417 if( strlen( key ) == 0 )
422 if( !node || !node -> is_leaf )
431 (*val) = node -> data . fval ;
449 if( strlen( key ) == 0 )
454 if( !node || !node -> is_leaf )
463 (*val) = node -> data . string ;
480 if( strlen( key ) == 0 )
485 if( !node || !node -> is_leaf )
494 (*val) = node -> data . ptr ;
518 for(
size_t it = 0 ; key[ it ] !=
'\0' ; it ++ )
520 size_t index = (size_t)key[ it ] - table -> alphabet_offset ;
521 if( index >= table -> alphabet_length )
523 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it, key );
526 if( node -> children[ index ] )
529 for(
size_t it2 = 0 ; it2 < table -> alphabet_length ; it2++ )
531 if( it2 != (
unsigned)index && node -> children[ it2 ] )
560 int len = strlen( key );
563 char *longest_prefix = NULL ;
564 Malloc( longest_prefix,
char, len + 1 );
565 memcpy( longest_prefix, key, len );
569 if(branch_index >= 0 )
572 longest_prefix[ branch_index ] =
'\0';
573 Realloc( longest_prefix,
char, (branch_index + 1) );
574 if( !longest_prefix )
576 n_log(
LOG_ERR,
"reallocation error, stopping find longest prefix" );
581 return longest_prefix;
600 for(
size_t it = 0 ; key[ it ] ; it++ )
602 size_t index = (size_t)key[ it ] - table -> alphabet_offset ;
603 if( index >= table -> alphabet_length )
605 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it, key );
608 if( node -> children[ index ] )
610 node = node -> children[ index ];
613 return node -> is_leaf ;
630 Free( node_ptr -> data .
string );
634 if( node_ptr -> destroy_func && node_ptr -> data . ptr )
636 node_ptr -> destroy_func( node_ptr -> data . ptr );
646 if( node_ptr -> alphabet_length > 0 )
648 for(
size_t it = 0 ; it < node_ptr -> alphabet_length ; it ++ )
650 if( node_ptr -> children[ it ] )
655 Free( node_ptr -> children );
685 if( longest_prefix && longest_prefix[ 0 ] ==
'\0' )
687 Free( longest_prefix );
692 for( it = 0 ; longest_prefix[ it ] !=
'\0'; it++ )
694 size_t index = (size_t)longest_prefix[ it ] - table -> alphabet_offset ;
695 if( index >= table -> alphabet_length )
697 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it, key );
700 if( node -> children[ index ] != NULL )
703 node = node -> children[ index ];
708 Free( longest_prefix );
714 for( ; key[ it ] !=
'\0' ; it++ )
716 size_t index = (size_t)key[ it ] - table -> alphabet_offset ;
717 if( index >= table -> alphabet_length )
719 n_log(
LOG_ERR,
"Invalid value %d for charater at position %d of %s, set to 0", index, it, key );
722 if( node -> children[ index] )
725 HASH_NODE* node_to_kill = node -> children[ index ];
726 node -> children[ index ] = NULL;
730 Free( longest_prefix );
732 table -> nb_keys -- ;
754 table -> nb_keys = 0 ;
792 if( node -> is_leaf )
794 printf(
"key: %s, val: ", node -> key );
795 switch( node -> type )
798 printf(
"int: %d", node -> data . ival );
801 printf(
"double: %f", node -> data . fval );
804 printf(
"ptr: %p", node -> data . ptr );
807 printf(
"%s", node -> data .
string );
810 printf(
"unknwow type %d", node -> type );
815 for(
size_t it = 0 ; it < table -> alphabet_length ; it++ )
853 if( node -> is_leaf )
855 if( node_is_matching( node ) == TRUE )
857 list_push( results, strdup( node -> key ), &free );
860 for(
size_t it = 0 ; it < node -> alphabet_length ; it++ )
884 if( results -> nb_items < 1 )
907 for(
size_t it = 0; it < node -> alphabet_length ; it++ )
911 if( node -> is_leaf )
913 if( results -> nb_items < results -> nb_max_items )
915 return list_push( results, strdup( node -> key ), &free );
926#define ROTL64(x, r) (((x) << (r)) | ((x) >> (64 - (r))))
928#define ROTL32(x, r) (((x) << (r)) | ((x) >> (32 - (r))))
930#define BIG_CONSTANT(x) (x##LLU)
933#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__)
934# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
935# define BYTESWAP32(x) (x)
936# define BYTESWAP64(x) (x)
939#elif defined(__i386) || defined(__x86_64) \
940 || defined(__alpha) || defined(__vax)
942# define BYTESWAP32(x) (x)
943# define BYTESWAP64(x) (x)
945#elif defined(__GNUC__) || defined(__clang__)
947# if __has_builtin(__builtin_bswap32)
948# define BYTESWAP32(x) __builtin_bswap32(x)
950# if __has_builtin(__builtin_bswap64)
951# define BYTESWAP64(x) __builtin_bswap64(x)
958# define BYTESWAP32(x) ((((x)&0xFF)<<24) \
960 |(((x)&0x0000FF00)<<8) \
961 |(((x)&0x00FF0000)>>8) )
965# define BYTESWAP64(x) \
966 (((uint64_t)(x) << 56) | \
967 (((uint64_t)(x) << 40) & 0X00FF000000000000ULL) | \
968 (((uint64_t)(x) << 24) & 0X0000FF0000000000ULL) | \
969 (((uint64_t)(x) << 8) & 0X000000FF00000000ULL) | \
970 (((uint64_t)(x) >> 8) & 0X00000000FF000000ULL) | \
971 (((uint64_t)(x) >> 24) & 0X0000000000FF0000ULL) | \
972 (((uint64_t)(x) >> 40) & 0X000000000000FF00ULL) | \
973 ((uint64_t)(x) >> 56))
1050 const uint8_t * data = (
const uint8_t*)key;
1051 const int nblocks = len / 4;
1055 uint32_t c1 = 0xcc9e2d51;
1056 uint32_t c2 = 0x1b873593;
1059 const uint32_t * blocks = (
const uint32_t *)(data + nblocks*4);
1062 for(i = -nblocks; i; i++)
1072 h1 = h1*5+0xe6546b64;
1076 const uint8_t * tail = (
const uint8_t*)(data + nblocks*4);
1083 k1 ^= tail[2] << 16;
1101 *(uint32_t*)out = h1;
1120 const uint8_t * data = (
const uint8_t*)key;
1121 const int nblocks = len / 16;
1128 uint32_t c1 = 0x239b961b;
1129 uint32_t c2 = 0xab0e9789;
1130 uint32_t c3 = 0x38b34ae5;
1131 uint32_t c4 = 0xa1e38b93;
1134 const uint32_t * blocks = (
const uint32_t *)(data + nblocks*16);
1137 for( i = -nblocks ; i; i++)
1150 h1 = h1*5+0x561ccd1b;
1158 h2 = h2*5+0x0bcaa747;
1166 h3 = h3*5+0x96cd1c35;
1174 h4 = h4*5+0x32ac3b17;
1178 const uint8_t * tail = (
const uint8_t*)(data + nblocks*16);
1188 k4 ^= tail[14] << 16;
1191 k4 ^= tail[13] << 8;
1194 k4 ^= tail[12] << 0;
1201 k3 ^= tail[11] << 24;
1204 k3 ^= tail[10] << 16;
1207 k3 ^= tail[ 9] << 8;
1210 k3 ^= tail[ 8] << 0;
1217 k2 ^= tail[ 7] << 24;
1220 k2 ^= tail[ 6] << 16;
1223 k2 ^= tail[ 5] << 8;
1226 k2 ^= tail[ 4] << 0;
1233 k1 ^= tail[ 3] << 24;
1236 k1 ^= tail[ 2] << 16;
1239 k1 ^= tail[ 1] << 8;
1242 k1 ^= tail[ 0] << 0;
1275 ((uint32_t*)out)[0] = h1;
1276 ((uint32_t*)out)[1] = h2;
1277 ((uint32_t*)out)[2] = h3;
1278 ((uint32_t*)out)[3] = h4;
1297 const uint8_t * data = (
const uint8_t*)key;
1298 const size_t nblocks = len / 16;
1306 const uint64_t * blocks = (
const uint64_t *)(data);
1307 const uint8_t * tail = (
const uint8_t*)(data + nblocks*16);
1312 for(
size_t i = 0; i < nblocks; i++)
1324 h1 = h1*5+0x52dce729;
1333 h2 = h2*5+0x38495ab5;
1340 k2 ^= ((uint64_t)tail[14]) << 48;
1343 k2 ^= ((uint64_t)tail[13]) << 40;
1346 k2 ^= ((uint64_t)tail[12]) << 32;
1349 k2 ^= ((uint64_t)tail[11]) << 24;
1352 k2 ^= ((uint64_t)tail[10]) << 16;
1355 k2 ^= ((uint64_t)tail[ 9]) << 8;
1358 k2 ^= ((uint64_t)tail[ 8]) << 0;
1366 k1 ^= ((uint64_t)tail[ 7]) << 56;
1369 k1 ^= ((uint64_t)tail[ 6]) << 48;
1372 k1 ^= ((uint64_t)tail[ 5]) << 40;
1375 k1 ^= ((uint64_t)tail[ 4]) << 32;
1378 k1 ^= ((uint64_t)tail[ 3]) << 24;
1381 k1 ^= ((uint64_t)tail[ 2]) << 16;
1384 k1 ^= ((uint64_t)tail[ 1]) << 8;
1387 k1 ^= ((uint64_t)tail[ 0]) << 0;
1411 ((uint64_t*)out)[0] = h2;
1412 ((uint64_t*)out)[1] = h1;
1425 static char *HASH_TYPE_STR[ 5 ] = {
"HASH_INT",
"HASH_DOUBLE",
"HASH_STRING",
"HASH_PTR",
"HASH_UNKNOWN" };
1430 return HASH_TYPE_STR[ node -> type ];
1452 if( key[ 0 ] ==
'\0' )
1455 MurmurHash( key, strlen( key ), table -> seed, &hash_value );
1456 index= (hash_value[ 0 ])%(table->
size);
1458 if( ! table -> hash_table[ index ] -> start )
1461 list_foreach( list_node, table -> hash_table[ index ] )
1463 node_ptr = (
HASH_NODE *)list_node -> ptr ;
1464 if( !strcmp( key, node_ptr -> key ) )
1489 if( strlen( key ) == 0 )
1492 MurmurHash( key, strlen( key ), table -> seed, &hash_value );
1496 new_hash_node -> key = strdup( key );
1497 new_hash_node -> key_id =
'\0' ;
1498 __n_assert( new_hash_node -> key,
n_log(
LOG_ERR,
"Could not allocate new_hash_node->key" );
Free( new_hash_node );
return NULL );
1499 new_hash_node -> hash_value = hash_value[ 0 ] ;
1500 new_hash_node -> data. ptr = NULL ;
1501 new_hash_node -> destroy_func = NULL ;
1502 new_hash_node -> children = NULL ;
1503 new_hash_node -> is_leaf = 0 ;
1504 new_hash_node -> need_rehash = 0 ;
1505 new_hash_node -> alphabet_length = 0 ;
1507 return new_hash_node ;
1526 new_hash_node -> data . ival = value ;
1528 return new_hash_node ;
1547 new_hash_node -> data . fval = value ;
1549 return new_hash_node ;
1569 new_hash_node -> data .
string = strdup( value );
1571 new_hash_node -> data .
string = NULL ;
1573 return new_hash_node ;
1592 new_hash_node -> data .
string = value ;
1594 return new_hash_node ;
1614 new_hash_node -> data . ptr = value ;
1615 new_hash_node -> destroy_func = destructor ;
1617 return new_hash_node ;
1642 node_ptr -> data . ival = value ;
1645 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 ) );
1651 size_t index = ( node_ptr -> hash_value )%( table -> size );
1653 if( retcode == TRUE )
1655 table -> nb_keys ++ ;
1680 node_ptr -> data . fval = value ;
1683 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 ) );
1689 HASH_VALUE index = ( node_ptr -> hash_value )%( table -> size );
1691 if( retcode == TRUE )
1693 table -> nb_keys ++ ;
1720 if( node_ptr -> destroy_func )
1722 node_ptr -> destroy_func( node_ptr -> data . ptr );
1723 node_ptr -> data . ptr = ptr ;
1724 node_ptr -> destroy_func = destructor ;
1728 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 ) );
1734 HASH_VALUE index = ( node_ptr -> hash_value )%( table -> size );
1736 if( retcode == TRUE )
1738 table -> nb_keys ++ ;
1764 Free( node_ptr -> data .
string );
1765 node_ptr -> data .
string = strdup(
string );
1768 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 ) );
1774 HASH_VALUE index = ( node_ptr -> hash_value )%( table -> size );
1776 if( retcode == TRUE )
1778 table -> nb_keys ++ ;
1804 Free( node_ptr -> data .
string );
1805 node_ptr -> data .
string = string ;
1808 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 ) );
1814 HASH_VALUE index = ( node_ptr -> hash_value )%( table -> size );
1816 if( retcode == TRUE )
1818 table -> nb_keys ++ ;
1838 if( strlen( key ) == 0 )
1852 (*val) = node -> data . ival ;
1871 if( strlen( key ) == 0 )
1885 (*val) = node -> data . fval ;
1903 if( strlen( key ) == 0 )
1916 (*val) = node -> data . ptr ;
1934 if( strlen( key ) == 0 )
1947 (*val) = node -> data . string ;
1970 if( strlen( key ) == 0 )
1973 MurmurHash( key, strlen( key ), table -> seed, &hash_value );
1974 index= (hash_value[ 0 ])%(table->
size) ;
1976 if( !table -> hash_table[ index ] -> start )
1978 n_log(
LOG_ERR,
"Can't remove key[\"%s\"], table is empty", key );
1982 list_foreach( list_node, table -> hash_table[ index ] )
1984 node_ptr = (
HASH_NODE *)list_node -> ptr ;
1986 if( !strcmp( key, node_ptr -> key ) )
1988 node_to_kill = list_node ;
1997 table -> nb_keys -- ;
2001 n_log(
LOG_ERR,
"Can't delete key[\"%s\"]: inexisting key", key );
2021 for( index = 0 ; index < table -> size ; index ++ )
2023 while( table -> hash_table[ index ] && table -> hash_table[ index ] -> start )
2029 table -> nb_keys = 0 ;
2046 if( (*table )-> hash_table )
2051 for( it = 0 ; it < (*table) -> size ; it ++ )
2053 if( (*table) -> hash_table[ it ] )
2056 Free( (*table )->hash_table );
2075 printf(
"key:%s node:%s\n", ((
HASH_NODE *)node ->ptr)->key, ((
HASH_NODE *)node ->ptr)->key );
2100 if( node_is_matching( hnode ) == TRUE )
2102 list_push( results, strdup( hnode -> key ), &free );
2106 if( results -> nb_items < 1 )
2133 table -> nb_keys = 0 ;
2135 table -> hash_table = NULL ;
2152 table -> alphabet_length = alphabet_length ;
2153 table -> alphabet_offset = alphabet_offset ;
2174 n_log(
LOG_ERR,
"Invalide size %d for new_ht()", size );
2180 table -> size = size ;
2181 table -> seed = (uint32_t)rand()%100000 ;
2182 table -> nb_keys = 0 ;
2186 __n_assert( table -> hash_table,
n_log(
LOG_ERR,
"Can't allocate table -> hash_table with size %d !", size );
Free( table );
return NULL );
2189 for( it = 0 ; it < size ; it ++ )
2193 if( !table -> hash_table[ it ] )
2195 n_log(
LOG_ERR,
"Can't allocate table -> hash_table[ %d ] !", it );
2196 size_t it_delete = 0 ;
2197 for( it_delete = 0 ; it_delete < it ; it_delete ++ )
2201 Free( table -> hash_table );
2287 return table ->
ht_get_ptr( table, key, &(*val) );
2335 return table->
ht_put_int( table, key, value );
2352 return table->
ht_put_ptr( table, key, ptr, destructor );
2426 return table ->
ht_search( table, node_is_matching );
2452 return (*table)->destroy_ht( table );
2471 index= (hash_value)%(table->
size) ;
2472 if( !table -> hash_table[ index ] -> start )
2477 list_foreach( list_node, table -> hash_table[ index ] )
2479 node_ptr = (
HASH_NODE *)list_node -> ptr ;
2480 if( hash_value == node_ptr -> hash_value )
2512 (*val) = node -> data . ptr ;
2536 index = (hash_value)%(table->
size) ;
2539 list_foreach( list_node, table -> hash_table[ index ] )
2541 node_ptr = (
HASH_NODE *)list_node -> ptr ;
2543 if( hash_value == node_ptr -> hash_value )
2548 if( list_node -> destroy_func )
2550 list_node -> destroy_func( node_ptr -> data . ptr );
2551 node_ptr -> data . ptr = val ;
2552 list_node -> destroy_func = destructor ;
2556 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 ) );
2564 new_hash_node -> key = NULL ;
2565 new_hash_node -> hash_value = hash_value ;
2566 new_hash_node -> data . ptr = val ;
2568 new_hash_node -> destroy_func = destructor ;
2570 table -> nb_keys ++ ;
2592 index= (hash_value)%(table->
size) ;
2593 if( !table -> hash_table[ index ] -> start )
2595 n_log(
LOG_ERR,
"Can't remove key[\"%d\"], table is empty", hash_value );
2599 list_foreach( list_node, table -> hash_table[ index ] )
2601 node_ptr = (
HASH_NODE *)list_node -> ptr ;
2603 if( hash_value == node_ptr -> hash_value )
2605 node_to_kill = list_node ;
2614 table -> nb_keys -- ;
2618 n_log(
LOG_ERR,
"Can't delete key[\"%d\"]: inexisting key", hash_value );
2636 LIST *results = NULL ;
2644 if(
list_push( results, strdup( keybud ), &free ) == TRUE )
2652 node = table -> root ;
2653 for(
size_t it = 0 ; it < table -> alphabet_length ; it++ )
2655 if( node -> children[ it ] )
2657 char keybud[ 3 ] =
"" ;
2658 keybud[ 0 ] = it + table -> alphabet_offset ;
2659 list_push( results , strdup( keybud ), &free );
2664 if( found == FALSE )
2671 if( strncasecmp( keybud, node -> key, strlen( keybud ) ) == 0 )
2675 results =
ht_search( table, &matching_nodes );
2679 n_log(
LOG_ERR,
"unsupported mode %d", table -> mode );
2694 if( nb <= 1 )
return FALSE ;
2695 if( nb <= 3 )
return TRUE ;
2698 if( (nb%2 == 0) || (nb%3 == 0) )
2702 for(
int it = 5 ; it*it <= nb ; it = it + 6 )
2704 if( (nb%it == 0) || (nb%( it + 2 ) == 0) )
2744 if( table -> size == 0 )
return FALSE ;
2746 int nb_collisionned_lists = 0 ;
2748 for(
size_t hash_it = 0 ; hash_it < table -> size ; hash_it ++ )
2750 if( table -> hash_table[ hash_it ] && table -> hash_table[ hash_it ] -> nb_items > 1 )
2752 nb_collisionned_lists ++ ;
2755 int collision_percentage = ( 100 * nb_collisionned_lists ) / table -> size ;
2756 return collision_percentage ;
2770 int optimum_size = (double)table -> nb_keys * 1.3 ;
2771 if(
is_prime( optimum_size ) != TRUE )
2774 return optimum_size ;
2792 n_log(
LOG_ERR,
"invalid size %d for hash table %p", size, (*table) );
2795 HT_FOREACH( node, (*table), { node -> need_rehash = 1 ; } );
2797 if( size > (*table) -> size )
2800 if( !(*table) -> hash_table )
2802 n_log(
LOG_ERR,
"Realloc did not augment the size the table !" );
2806 for(
size_t it = (*table) -> size ; it < size ; it ++ )
2810 if( !(*table) -> hash_table[ it ] )
2812 n_log(
LOG_ERR,
"Can't allocate table -> hash_table[ %d ] !", it );
2813 for(
size_t it_delete = 0 ; it_delete < it ; it_delete ++ )
2817 Free( (*table) -> hash_table );
2822 for(
size_t it = 0 ; it < size ; it ++ )
2824 if( ( (*table) -> hash_table[ it ] ) )
2826 while( (*table) -> hash_table[ it ] -> start )
2829 if( hash_node -> need_rehash == 0 )
2831 hash_node -> need_rehash = 0 ;
2833 node -> next = node -> prev = NULL ;
2834 size_t index= (hash_node -> hash_value)%(size);
2843 for(
size_t it = 0 ; it < (*table) -> size ; it ++ )
2845 if( ( (*table) -> hash_table[ it ] ) )
2847 while( (*table) -> hash_table[ it ] -> start )
2850 if( hash_node -> need_rehash == 0 )
2852 hash_node -> need_rehash = 0 ;
2854 node -> next = node -> prev = NULL ;
2855 size_t index= (hash_node -> hash_value)%(size);
2860 for(
size_t it = size ; it < (*table) -> size ; it ++ )
2865 if( !(*table) -> hash_table )
2867 n_log(
LOG_ERR,
"Realloc did not reduce the resize the table !" );
2870 (*table) -> size = size ;
2887 if( optimal_size == FALSE )
2893 if( collision_percentage == FALSE )
2896 int resize_result =
ht_resize( &(*table), optimal_size );
2897 if( resize_result == FALSE )
2903 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.
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
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
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_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.
FORCE_INLINE uint64_t getblock64(const uint64_t *p, const size_t i)
Block read - modified from murmur's author, ajusted byte endianess.
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
FORCE_INLINE uint32_t fmix32(uint32_t h)
Finalization mix - force all bits of a hash block to avalanche (from murmur's author)
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_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.
N_STR and string function declaration.