Nilorea Library
C utilities for networking, threading, graphics
ex_hash.c
1
8#include "nilorea/n_str.h"
9#include "nilorea/n_log.h"
10#include "nilorea/n_list.h"
11#include "nilorea/n_hash.h"
12
13#define NB_ELEMENTS 24
14
16typedef struct DATA
17{
21 int value ;
22} DATA ;
23
28void destroy_data( void *ptr )
29{
30 DATA *data = (DATA *)ptr ;
31 free_nstr( &data -> rnd_str );
32 Free( data );
33}
34
35int main( void )
36{
37
39
40 HASH_TABLE *htable = new_ht( NB_ELEMENTS / 3 );
41 LIST *keys_list = new_generic_list( NB_ELEMENTS + 1 );
42 DATA *data = NULL ;
43 char *str = NULL ;
44
45 n_log( LOG_INFO, "Filling HashTable with %d random elements", NB_ELEMENTS );
46 for( int it = 0 ; it < NB_ELEMENTS ; it ++ )
47 {
48 N_STR *nkey = NULL ;
49 int randomizator = rand()%4;
50 nstrprintf( nkey, "key%d_%d", it, randomizator );
51 switch( randomizator )
52 {
53
54 default:
55 case 0:
56 ht_put_int( htable, _nstr( nkey ), 666 );
57 n_log( LOG_INFO, "Put int 666 with key %s", _nstr( nkey ) );
58 break;
59 case 1:
60 ht_put_double( htable, _nstr( nkey ), 3.14 );
61 n_log( LOG_INFO, "Put double 3.14 with key %s", _nstr( nkey ) );
62 break;
63 case 2:
64 Malloc( data, DATA, 1 );
65 data -> rnd_str = NULL ;
66 nstrprintf( data -> rnd_str, "%s%d", _nstr( nkey ), rand()%10 );
67 data -> value = 7 ;
68 ht_put_ptr( htable, _nstr( nkey ), data, &destroy_data );
69 n_log( LOG_INFO, "Put ptr rnd_str %s value %d with key %s", _nstr( data -> rnd_str ), data -> value, _nstr( nkey ) );
70 break;
71 case 3:
72 Malloc( str, char, 64 );
73 sprintf( str, "%s%d", _nstr( nkey ), rand()%10 );
74 ht_put_string( htable, _nstr( nkey ), str );
75 n_log( LOG_INFO, "Put string %s key %s", str, _nstr( nkey ) );
76 Free( str );
77 break;
78 }
79 /* asving key for ulterior use */
80 list_push( keys_list, nkey, free_nstr_ptr );
81 }
82
83 n_log( LOG_INFO, "Reading hash table with ht_foreach" );
84 HT_FOREACH( node, htable,
85 {
86 n_log( LOG_INFO, "HT_FOREACH hash: %u, key:%s", node -> hash_value , _str( node -> key ) );
87 } );
88 HT_FOREACH_R( node, htable, hash_iterator,
89 {
90 n_log( LOG_INFO, "HT_FOREACH_R hash: %u, key:%s", node -> hash_value , _str( node -> key ) );
91 } );
92
93 unsigned long int optimal_size = ht_get_optimal_size( htable );
94 n_log( LOG_INFO, "########" );
95 n_log( LOG_INFO, "collisions: %d %%", ht_get_table_collision_percentage( htable ) );
96 n_log( LOG_INFO, "table size: %ld , table optimal size: %ld", htable -> size, optimal_size );
97 n_log( LOG_INFO, "resizing to %ld returned %d", optimal_size, ht_resize( &htable, optimal_size ) );
98 n_log( LOG_INFO, "collisions after resize: %d %%", ht_get_table_collision_percentage( htable ) );
99 n_log( LOG_INFO, "########" );
100
101 if( ht_optimize( &htable ) == FALSE )
102 {
103 n_log( LOG_ERR, "Error when optimizing table %p", htable );
104 }
105 n_log( LOG_INFO, "collisions after ht_optimize: %d %%", ht_get_table_collision_percentage( htable ) );
106 n_log( LOG_INFO, "########" );
107
108 /*ht_print( htable );
109 char input_key[ 1024 ] = "" ;
110 printf( "Enter key starting piece, q! to quit:\n");
111 while( strcmp( input_key , "q!" ) != 0 )
112 {
113 printf( "key:" );
114 scanf( "%s" , input_key );
115 LIST *results = _ht_get_completion_list( htable , input_key , 10 );
116 if( results )
117 {
118 list_foreach( node , results )
119 {
120 printf( "result: %s\n" , (char *)node -> ptr );
121 }
122 list_destroy( &results );
123 }
124 }*/
125 LIST *results = ht_get_completion_list( htable, "key", 10 );
126 if( results )
127 {
128 list_foreach( node, results )
129 {
130 n_log( LOG_INFO, "completion result: %s", (char *)node -> ptr );
131 }
132 list_destroy( &results );
133 }
134
135 int matching_nodes( HASH_NODE *node)
136 {
137 if( strncasecmp( "key", node -> key, 3 ) == 0 )
138 return TRUE ;
139 return FALSE ;
140 }
141 results = ht_search( htable, &matching_nodes );
142 list_foreach( node, results )
143 {
144 n_log( LOG_INFO, "htsearch: key: %s", (char *)node -> ptr );
145 }
146 list_destroy( &results );
147
148 list_destroy( &keys_list );
149 destroy_ht( &htable );
150
151 /* testing empty destroy */
152 htable = new_ht( 1024 );
153 empty_ht( htable );
154 destroy_ht( &htable );
155
156 htable = new_ht_trie( 256, 32 );
157
158 ht_put_int( htable, "TestInt", 1 );
159 ht_put_double( htable, "TestDouble", 2.0 );
160 ht_put_string( htable, "TestString", "MyString" );
161 int ival = -1 ;
162 double fval = -1.0 ;
163 ht_get_int( htable, "TestInt", &ival );
164 ht_get_double( htable, "TestDouble", &fval );
165 char *string = NULL ;
166 ht_get_string( htable, "TestString", &string );
167 n_log( LOG_INFO, "Trie:%d %f %s", ival, fval, string );
168
169 results = ht_get_completion_list( htable, "Test", 10 );
170 if( results )
171 {
172 list_foreach( node, results )
173 {
174 n_log( LOG_INFO, "completion result: %s", (char *)node -> ptr );
175 }
176 list_destroy( &results );
177 }
178
179 destroy_ht( &htable );
180
181 exit( 0 );
182
183} /* END_OF_MAIN */
184
#define Malloc(__ptr, __struct, __size)
Malloc Handler to get errors and set to 0.
Definition: n_common.h:183
#define _str(__PTR)
define true
Definition: n_common.h:172
#define Free(__ptr)
Free Handler to get errors.
Definition: n_common.h:256
#define _nstr(__PTR)
N_STR or "NULL" string for logging purposes.
Definition: n_common.h:178
int ht_get_int(HASH_TABLE *table, const char *key, int *val)
get node at 'key' from 'table'
Definition: n_hash.c:2266
LIST * ht_search(HASH_TABLE *table, int(*node_is_matching)(HASH_NODE *node))
seach table for matching nodes
Definition: n_hash.c:2422
int destroy_ht(HASH_TABLE **table)
empty a table and destroy it
Definition: n_hash.c:2448
#define HT_FOREACH_R(__ITEM_, __HASH_, __ITERATOR,...)
ForEach macro helper.
Definition: n_hash.h:255
HASH_TABLE * new_ht(size_t size)
Create a hash table with the given size.
Definition: n_hash.c:2167
int ht_get_table_collision_percentage(HASH_TABLE *table)
get table collision percentage (HASH_CLASSIC mode only)
Definition: n_hash.c:2738
int ht_get_double(HASH_TABLE *table, const char *key, double *val)
get double at 'key' from 'table'
Definition: n_hash.c:2250
int empty_ht(HASH_TABLE *table)
empty a table
Definition: n_hash.c:2435
LIST * ht_get_completion_list(HASH_TABLE *table, const char *keybud, size_t max_results)
get next matching keys in table tree
Definition: n_hash.c:2630
int ht_put_double(HASH_TABLE *table, const char *key, double value)
put a double value with given key in the targeted hash table
Definition: n_hash.c:2314
int ht_get_string(HASH_TABLE *table, const char *key, char **val)
get string at 'key' from 'table'
Definition: n_hash.c:2298
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
Definition: n_hash.c:2363
int ht_resize(HASH_TABLE **table, size_t size)
rehash table according to size (HASH_CLASSIC mode only)
Definition: n_hash.c:2785
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
Definition: n_hash.c:2123
int ht_put_int(HASH_TABLE *table, const char *key, int value)
put an integral value with given key in the targeted hash table
Definition: n_hash.c:2330
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
Definition: n_hash.c:2347
int ht_optimize(HASH_TABLE **table)
try an automatic optimization of the table
Definition: n_hash.c:2881
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...
Definition: n_hash.c:2765
#define HT_FOREACH(__ITEM_, __HASH_,...)
ForEach macro helper.
Definition: n_hash.h:195
structure of a hash table node
Definition: n_hash.h:83
structure of a hash table
Definition: n_hash.h:109
int list_push(LIST *list, void *ptr, void(*destructor)(void *ptr))
Add a pointer to the end of the list.
Definition: n_list.c:244
#define list_foreach(__ITEM_, __LIST_)
ForEach macro helper.
Definition: n_list.h:70
int list_destroy(LIST **list)
Empty and Free a list container.
Definition: n_list.c:603
LIST * new_generic_list(int max_items)
Initialiaze a generic list container to max_items pointers.
Definition: n_list.c:20
Structure of a generic LIST container.
Definition: n_list.h:45
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition: n_log.h:74
#define LOG_DEBUG
debug-level messages
Definition: n_log.h:66
#define LOG_ERR
error conditions
Definition: n_log.h:58
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL )
Definition: n_log.c:97
#define LOG_INFO
informational
Definition: n_log.h:64
void free_nstr_ptr(void *ptr)
Free a N_STR pointer structure.
Definition: n_str.c:55
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
Definition: n_str.h:222
#define nstrprintf(__nstr_var,...)
Macro to quickly allocate and sprintf to N_STR *.
Definition: n_str.h:97
A box including a string and his lenght.
Definition: n_str.h:173
Hash functions and table.
List structures and definitions.
Generic log system.
N_STR and string function declaration.
string and int holder
Definition: ex_hash.c:17
int value
int value
Definition: ex_hash.c:21
N_STR * rnd_str
string holder
Definition: ex_hash.c:19