├── LICENSE
├── Makefile
├── debug.h
├── hashtable.c
├── hashtable.h
└── main.c
/LICENSE:
--------------------------------------------------------------------------------
1 | A Simple hash table implementation
2 | Copyright (C) 2011 Ankur Shrivastava
3 |
4 | This program is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see .
16 |
17 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | CC = gcc -fPIC
2 | LDFLAGS = -lm
3 |
4 | # set DEBUG options
5 | ifdef DEBUG
6 | CFLAGS = -Wall -Wextra -ggdb -pg -DDEBUG
7 | else
8 | CFLAGS = -Wall -O2
9 | endif
10 |
11 | #name all the object files
12 | OBJS = main.o hashtable.o
13 |
14 | all : hashtable
15 |
16 | hashtable : $(OBJS)
17 | $(CC) $(LDFLAGS) -o main $^
18 |
19 | debug :
20 | make all DEBUG=1
21 |
22 | %.o : %.c
23 | $(CC) $(CFLAGS) -o $@ -c $^
24 |
25 | doxy :
26 | doxygen Doxyfile
27 |
28 | clean :
29 | rm -rf $(OBJS) main
30 |
31 |
--------------------------------------------------------------------------------
/debug.h:
--------------------------------------------------------------------------------
1 | #ifndef _DEBUG_H
2 | #define _DEBUG_H
3 |
4 | #ifdef DEBUG
5 |
6 | #include
7 |
8 | #define INFO(format) fprintf(stderr,"%s:%d:%s -> " format "\n", __FILE__, __LINE__, __func__)
9 | #define LOG(format, ...) fprintf(stderr,"%s:%d:%s -> " format "\n", __FILE__, __LINE__, __func__, __VA_ARGS__)
10 |
11 | #else
12 |
13 | #define LOG(...)
14 | #define INFO(...)
15 |
16 | #endif // debug
17 |
18 | #endif // debug.h
19 |
--------------------------------------------------------------------------------
/hashtable.c:
--------------------------------------------------------------------------------
1 | /**
2 | * License GPLv3+
3 | * @file hashtable.c
4 | * @brief a simple hash table implementation
5 | * @author Ankur Shrivastava
6 | */
7 | #include "hashtable.h"
8 | #include "debug.h"
9 |
10 | #include
11 | #include
12 |
13 | // element operations
14 | /**
15 | * Function to create a now hash_table element
16 | * @returns hash_table_element_t object when success
17 | * @returns NULL when no memory
18 | */
19 | hash_table_element_t * hash_table_element_new()
20 | {
21 | INFO("creating a new hash table element");
22 | return calloc(1, hash_table_element_s);
23 | }
24 |
25 | /**
26 | * Function to delete an hash table element
27 | * @param table table from which element has to be deleted
28 | * @param element hash table element to be deleted
29 | */
30 | void hash_table_element_delete(hash_table_t * table, hash_table_element_t * element)
31 | {
32 | INFO("Deleting an hash table element");
33 | if (table->mode == MODE_COPY)
34 | {
35 | free(element->value);
36 | free(element->key);
37 | }
38 | else if (table->mode == MODE_VALUEREF)
39 | {
40 | free(element->key);
41 | }
42 | free(element);
43 | }
44 |
45 | // hash table operations
46 | /**
47 | * Fuction to create a new hash table
48 | * @param mode hash_table_mode which the hash table should follow
49 | * @returns hash_table_t object which references the hash table
50 | * @returns NULL when no memory
51 | */
52 | hash_table_t * hash_table_new(hash_table_mode_t mode)
53 | {
54 | INFO("Creating a new hash table");
55 | hash_table_t *table = calloc(1, hash_table_s);
56 | if (!table)
57 | {
58 | INFO("No Memory while allocating hash_table");
59 | return NULL;
60 | }
61 | table->mode = mode;
62 | table->key_num = 128;
63 | table->key_ratio = 4;
64 | table->store_house = (hash_table_element_t **) calloc(table->key_num, sizeof(hash_table_element_t *));
65 | if (!table->store_house)
66 | {
67 | INFO("No Memory while allocating hash_table store house");
68 | free(table);
69 | return NULL;
70 | }
71 | return table;
72 | }
73 |
74 | /**
75 | * Function to delete the hash table
76 | * @param table hash table to be deleted
77 | */
78 | void hash_table_delete(hash_table_t * table)
79 | {
80 | INFO("Deleating a hash table");
81 | size_t i=0;
82 | for (;istore_house[i])
85 | {
86 | hash_table_element_t * temp = table->store_house[i];
87 | table->store_house[i] = table->store_house[i]->next;
88 | hash_table_element_delete(table, temp);
89 | }
90 | }
91 | free(table->store_house);
92 | free(table);
93 | }
94 |
95 | /**
96 | * Function to add a key - value pair to the hash table, use HT_ADD macro
97 | * @param table hash table to add element to
98 | * @param key pointer to the key for the hash table
99 | * @param key_len length of the key in bytes
100 | * @param value pointer to the value to be added against the key
101 | * @param value_len length of the value in bytes
102 | * @returns 0 on sucess
103 | * @returns -1 when no memory
104 | */
105 | int hash_table_add(hash_table_t * table, void * key, size_t key_len, void * value, size_t value_len)
106 | {
107 | if ((table->key_count / table->key_num) >= table->key_ratio)
108 | {
109 | LOG("Ratio(%d) reached the set limit %d\nExpanding hash_table", (table->key_count / table->key_num), table->key_ratio);
110 | hash_table_resize(table, table->key_num*2);
111 | //exit(0);
112 | }
113 | size_t hash = HASH(key, key_len);
114 | hash_table_element_t * element = hash_table_element_new();
115 | if (!element)
116 | {
117 | INFO("Cannot allocate memory for element");
118 | return -1; // No Memory
119 | }
120 | if (table->mode == MODE_COPY)
121 | {
122 | LOG("Adding a key-value pair to the hash table with hash -> %d, in COPY MODE", (int)hash);
123 | element->key = malloc(key_len);
124 | element->value = malloc(value_len);
125 | if (element->key && element->value)
126 | {
127 | memcpy(element->key, key, key_len);
128 | memcpy(element->value, value, value_len);
129 | }
130 | else
131 | {
132 | if (element->key)
133 | {
134 | free(element->key);
135 | INFO("Cannot allocate memory for value");
136 | }
137 | if (element->value)
138 | {
139 | free(element->value);
140 | INFO("Cannot allocate memory for key");
141 | }
142 | free(element);
143 | return -1; //No Memory
144 | }
145 | }
146 | else if (table->mode == MODE_VALUEREF)
147 | {
148 | LOG("Adding a key-value pair to the hash table with hash -> %d, in VALUEREF MODE", (int)hash);
149 | element->key = malloc(key_len);
150 | if (element->key)
151 | {
152 | memcpy(element->key, key, key_len);
153 | }
154 | else
155 | {
156 | INFO("Cannot allocate memory for key");
157 | free(element);
158 | return -1; //No Memory
159 | }
160 | element->value = value;
161 | }
162 | else if (table->mode == MODE_ALLREF)
163 | {
164 | LOG("Adding a key-value pair to the hash table with hash -> %d, in ALLREF MODE", (int)hash);
165 | element->key = key;
166 | element->value = value;
167 | }
168 | element->key_len = key_len;
169 | element->value_len = value_len;
170 | element->next = NULL;
171 | // find the key position for chaining
172 | if (!table->store_house[hash])
173 | {
174 | LOG("No Conflicts adding the first element at %d", (int)hash);
175 | table->store_house[hash] = element;
176 | table->key_count++;
177 | }
178 | else
179 | {
180 | LOG("Conflicts adding element at %d", (int)hash);
181 | hash_table_element_t * temp = table->store_house[hash];
182 | while(temp->next)
183 | {
184 | while(temp->next && temp->next->key_len!=key_len)
185 | {
186 | temp = temp->next;
187 | }
188 | if(temp->next)
189 | {
190 | if (!memcmp(temp->next->key, key, key_len))
191 | {
192 | LOG("Found Key at hash -> %d", (int)hash);
193 | hash_table_element_t *to_delete = temp->next;
194 | temp->next = element;
195 | element->next = to_delete->next;
196 | hash_table_element_delete(table, to_delete);
197 | // since we are replacing values no need to change key_count
198 | return 0;
199 | }
200 | else
201 | {
202 | temp = temp->next;
203 | }
204 | }
205 | }
206 | temp->next = element;
207 | table->key_count++;
208 | }
209 | return 0;
210 | }
211 |
212 | /**
213 | * Function to remove an hash table element (for a given key) from a given hash table
214 | * @param table hash table from which element has to be removed
215 | * @param key pointer to the key which has to be removed
216 | * @param key_len size of the key in bytes
217 | * @returns 0 on sucess
218 | * @returns -1 when key is not found
219 | */
220 | int hash_table_remove(hash_table_t * table, void * key, size_t key_len)
221 | {
222 | INFO("Deleting a key-value pair from the hash table");
223 | if ((table->key_num/ table->key_count) >= table->key_ratio)
224 | {
225 | LOG("Ratio(%d) reached the set limit %d\nContracting hash_table", (table->key_num / table->key_count), table->key_ratio);
226 | hash_table_resize(table, table->key_num/2);
227 | //exit(0);
228 | }
229 | size_t hash = HASH(key, key_len);
230 | if (!table->store_house[hash])
231 | {
232 | LOG("Key Not Found -> No element at %d", (int)hash);
233 | return -1; // key not found
234 | }
235 | hash_table_element_t *temp = table->store_house[hash];
236 | hash_table_element_t *prev = temp;
237 | while(temp)
238 | {
239 | while(temp && temp->key_len!=key_len)
240 | {
241 | prev = temp;
242 | temp = temp->next;
243 | }
244 | if(temp)
245 | {
246 | if (!memcmp(temp->key, key, key_len))
247 | {
248 | if (prev == table->store_house[hash])
249 | {
250 | table->store_house[hash] = temp->next;
251 | }
252 | else
253 | {
254 | prev->next = temp->next;
255 | }
256 | hash_table_element_delete(table, temp);
257 | INFO("Deleted a key-value pair from the hash table");
258 | table->key_count--;
259 | return 0;
260 | }
261 | prev=temp;
262 | temp=temp->next;
263 | }
264 | }
265 | INFO("Key Not Found");
266 | return -1; // key not found
267 | }
268 |
269 | /**
270 | * Function to lookup a key in a particular table
271 | * @param table table to look key in
272 | * @param key pointer to key to be looked for
273 | * @param key_len size of the key to be searched
274 | * @returns NULL when key is not found in the hash table
275 | * @returns void* pointer to the value in the table
276 | */
277 | void * hash_table_lookup(hash_table_t * table, void * key, size_t key_len)
278 | {
279 | size_t hash = HASH(key, key_len);
280 | LOG("Looking up a key-value pair for hash -> %d", (int)hash);
281 | if (!table->store_house[hash])
282 | {
283 | LOG("Key not found at hash %d, no entries", (int)hash);
284 | return NULL; // key not found
285 | }
286 | hash_table_element_t *temp = table->store_house[hash];
287 | while(temp)
288 | {
289 | while(temp && temp->key_len!=key_len)
290 | {
291 | temp = temp->next;
292 | }
293 | if(temp)
294 | {
295 | if (!memcmp(temp->key, key, key_len))
296 | {
297 | LOG("Found Key at hash -> %d", (int)hash);
298 | return temp->value;
299 | }
300 | else
301 | {
302 | temp = temp->next;
303 | }
304 | }
305 | }
306 | LOG("Key not found at hash %d", (int)hash);
307 | return NULL; // key not found
308 | }
309 |
310 | /**
311 | * Function to look if the exists in the hash table
312 | * @param key pointer to key to be looked for
313 | * @param key_len size of the key to be searched
314 | * @returns 0 when key is not found
315 | * @returns 1 when key is found
316 | */
317 | int hash_table_has_key(hash_table_t * table, void * key, size_t key_len)
318 | {
319 | size_t hash = HASH(key, key_len);
320 | LOG("Searching for key with hash -> %d", (int)hash);
321 | if (!table->store_house[hash])
322 | {
323 | LOG("Key not found with hash -> %d, no entries", (int)hash);
324 | return 0; // key not found
325 | }
326 | hash_table_element_t *temp = table->store_house[hash];
327 | while(temp)
328 | {
329 | while(temp && temp->key_len!=key_len)
330 | {
331 | temp = temp->next;
332 | }
333 | if(temp)
334 | {
335 | if (!memcmp(temp->key, key, key_len))
336 | {
337 | LOG("Key Found with hash -> %d", (int)hash);
338 | return 1; // key found
339 | }
340 | temp=temp->next;
341 | }
342 | }
343 | LOG("Key not found with hash -> %d", (int)hash);
344 | return 0; // key not found
345 | }
346 |
347 | /**
348 | * Function to return all the keys in a given hash table
349 | * @param table hash table from which key are to be reterived
350 | * @param keys a void** pointer where keys are filled in (memory allocated internally and must be freed)
351 | * @return total number of keys filled in keys
352 | */
353 | size_t hash_table_get_keys(hash_table_t * table, void ** keys)
354 | {
355 | size_t i = 0;
356 | size_t count = 0;
357 | keys = calloc(table->key_count, sizeof(void *));
358 | for(i=0;istore_house[i])
361 | {
362 | keys[count++] = table->store_house[i];
363 | hash_table_element_t *temp = table->store_house[i];
364 | #ifdef DEBUG
365 | size_t num = 1;
366 | #endif
367 | while(temp->next)
368 | {
369 | keys[count++] = temp->next;
370 | temp = temp->next;
371 | #ifdef DEBUG
372 | num++;
373 | #endif
374 | }
375 | #ifdef DEBUG
376 | LOG("found %d key(s) at hash -> %d", (int)num, (int)i);
377 | #endif
378 | }
379 | }
380 | return count;
381 | }
382 |
383 | /**
384 | * Function to get all elements (key - value pairs) from the given hash table
385 | * @param table hash table from which elements have to be retrieved
386 | * @param elements a pointer to an array of hash_table_element_t pointer (malloced by function)
387 | * @returns 1 when no memory
388 | * @returns count of elements
389 | */
390 | size_t hash_table_get_elements(hash_table_t * table, hash_table_element_t *** elements)
391 | {
392 | size_t i = 0;
393 | size_t count = 0;
394 | (*elements) = (hash_table_element_t **) calloc(table->key_count, sizeof(hash_table_element_t *));
395 | if (!*elements)
396 | {
397 | INFO("No Memory to allocate elements array");
398 | return 1;
399 | }
400 | for(i=0;istore_house[i])
403 | {
404 | (*elements)[count++] = table->store_house[i];
405 | hash_table_element_t *temp = table->store_house[i];
406 | #ifdef DEBUG
407 | size_t num = 1;
408 | #endif
409 | while(temp->next)
410 | {
411 | (*elements)[count++] = temp->next;
412 | temp = temp->next;
413 | #ifdef DEBUG
414 | num++;
415 | #endif
416 | }
417 | #ifdef DEBUG
418 | LOG("found %d key(s) at hash -> %d", (int)num, (int)i);
419 | #endif
420 | }
421 | }
422 | return count;
423 | }
424 |
425 | /**
426 | * Function that returns a hash value for a given key and key_len
427 | * @param key pointer to the key
428 | * @param key_len length of the key
429 | * @param max_key max value of the hash to be returned by the function
430 | * @returns hash value belonging to [0, max_key)
431 | */
432 | uint16_t hash_table_do_hash(void * key, size_t key_len, uint16_t max_key)
433 | {
434 | uint16_t *ptr = (uint16_t *) key;
435 | uint16_t hash = 0xbabe; // WHY NOT
436 | size_t i = 0;
437 | for(;i<(key_len/2);i++)
438 | {
439 | hash^=(i<<4 ^ *ptr<<8 ^ *ptr);
440 | ptr++;
441 | }
442 | hash = hash % max_key;
443 | return hash;
444 | }
445 |
446 | /**
447 | * Function to resize the hash table store house
448 | * @param table hash table to be resized
449 | * @param len new length of the hash table
450 | * @returns -1 when no elements in hash table
451 | * @returns -2 when no emmory for new store house
452 | * @returns 0 when sucess
453 | */
454 | int hash_table_resize(hash_table_t *table, size_t len)
455 | {
456 | LOG("resizing hash table from %d to %d", table->key_num, len);
457 | hash_table_element_t ** elements;
458 | size_t count;
459 | // FIXME traversing the elements twice, change it some time soon
460 | count = hash_table_get_elements(table, &elements);
461 | if (!count)
462 | {
463 | INFO("Got No Elements from the hash table");
464 | return -1;
465 | }
466 | // keep the current store house in case we dont get more memory
467 | hash_table_element_t ** temp = table->store_house;
468 | table->store_house = calloc(len, sizeof(hash_table_element_t *));
469 | if (!table->store_house)
470 | {
471 | table->store_house = temp;
472 | INFO("No Memory for new store house");
473 | return -2;
474 | }
475 | table->key_num = len;
476 | // fool the new hash table so if refers even previously copied values
477 | int mode = table->mode;
478 | table->mode = MODE_ALLREF;
479 | // the new table starts from scratch
480 | table->key_count = 0;
481 | while(count>0)
482 | {
483 | hash_table_element_t *elem = elements[--count];
484 | hash_table_add(table, elem->key, elem->key_len, elem->value, elem->value_len);
485 | }
486 | table->mode = mode;
487 | // free old store house
488 | free(temp);
489 | return 0;
490 | }
491 |
492 | /**
493 | * Function to iterate through all elements of the hashtable
494 | * @param table hash table to be iterated
495 | * @param fct pointer to a function returning 1 if the element has to be removed
496 | * @param user arbitrary user pointer passed to the fct callback
497 | * @returns 0 when success
498 | */
499 | int hash_table_iterate(hash_table_t *table, int (*fct)(void *user,
500 | void *value, void *key, size_t key_len), void *user)
501 | {
502 | LOG("iterating hash table");
503 | int i;
504 |
505 | for(i=0;istore_house[i])
508 | {
509 | hash_table_element_t *temp = table->store_house[i];
510 | hash_table_element_t *prev = NULL;
511 | while(temp)
512 | {
513 | int r = fct(user, temp->value, temp->key, temp->key_len);
514 | if (r){
515 | hash_table_element_t *next = temp->next;
516 | hash_table_element_delete(table,temp);
517 | if(prev == NULL)
518 | table->store_house[i] = next;
519 | else
520 | prev->next = next;
521 | temp = next;
522 | table->key_count--;
523 | } else {
524 | prev = temp;
525 | temp = temp->next;
526 | }
527 | }
528 | }
529 | }
530 | return 0;
531 | }
532 |
--------------------------------------------------------------------------------
/hashtable.h:
--------------------------------------------------------------------------------
1 | /**
2 | * License GPLv3+
3 | * @file hashtable.h
4 | * @brief a simple hash table implementation
5 | * @author Ankur Shrivastava
6 | */
7 | #ifndef _HASHTABLE_H
8 | #define _HASHTABLE_H
9 |
10 | #include
11 | #include
12 |
13 | #define HASH_LEN table->key_num
14 | #define HASH(x,y) hash_table_do_hash(x,y,HASH_LEN)
15 |
16 | // forward declaration
17 | typedef struct hash_table_element hash_table_element_t;
18 |
19 | /**
20 | * @struct hash_table_element "hashtable.h"
21 | * @brief stores an hash table element for use in the hash table
22 | */
23 | struct hash_table_element
24 | {
25 | /**
26 | * store the length in bytes of the key
27 | */
28 | size_t key_len;
29 | /**
30 | * stores the length in bytes of the key (only for copy mode)
31 | */
32 | size_t value_len;
33 | /**
34 | * pointer to the key
35 | */
36 | void * key;
37 | /**
38 | * pointer to the value
39 | */
40 | void * value;
41 | /**
42 | * next chained key for this hash
43 | */
44 | hash_table_element_t * next;
45 | };
46 | #define hash_table_element_s sizeof(hash_table_element_t)
47 |
48 | /**
49 | * @enum hash_table_mode defines the mode of operation of hash table
50 | */
51 | typedef enum hash_table_mode{
52 | /** copy mode here values as well as key is copied */
53 | MODE_COPY,
54 | /** value reference mode, here ONLY key is copies and value is always referred */
55 | MODE_VALUEREF,
56 | /** in this mode all keys and values are referred */
57 | MODE_ALLREF
58 | } hash_table_mode_t;
59 |
60 | /**
61 | * @struct hash_table "hashtable.h"
62 | * @brief identifies the hashtable for which operations are to be performed
63 | */
64 | typedef struct hash_table
65 | {
66 | /**
67 | * the hash table array where all values are stored
68 | */
69 | hash_table_element_t ** store_house;
70 |
71 | /**
72 | * mode of the hash table
73 | */
74 | hash_table_mode_t mode;
75 |
76 | /**
77 | * number of keys in the hash table
78 | */
79 | size_t key_count;
80 |
81 | /**
82 | * number of keys allocated in the hash table
83 | */
84 | uint16_t key_num;
85 |
86 | /**
87 | * the ratio of key_count / key_num at which the hash table should be expanded
88 | */
89 | size_t key_ratio;
90 |
91 | } hash_table_t;
92 | #define hash_table_s sizeof(hash_table_t)
93 |
94 |
95 | // element operations
96 | /**
97 | * Function to create a now hash_table element
98 | * @returns hash_table_element_t object when success
99 | * @returns NULL when no memory
100 | */
101 | hash_table_element_t * hash_table_element_new();
102 |
103 | /**
104 | * Function to delete an hash table element
105 | * @param table table from which element has to be deleted
106 | * @param element hash table element to be deleted
107 | */
108 | void hash_table_element_delete(hash_table_t *, hash_table_element_t *);
109 |
110 | /**
111 | * Function that returns a hash value for a given key and key_len
112 | * @param key pointer to the key
113 | * @param key_len length of the key
114 | * @param max_key max value of the hash to be returned by the function
115 | * @returns hash value belonging to [0, max_key)
116 | */
117 | uint16_t hash_table_do_hash(void * key, size_t key_len, uint16_t max_key);
118 |
119 | // hash table operations
120 | /**
121 | * Fuction to create a new hash table
122 | * @param mode hash_table_mode which the hash table should follow
123 | * @returns hash_table_t object which references the hash table
124 | * @returns NULL when no memory
125 | */
126 | hash_table_t * hash_table_new(hash_table_mode_t);
127 |
128 | /**
129 | * Function to delete the hash table
130 | * @param table hash table to be deleted
131 | */
132 | void hash_table_delete(hash_table_t *);
133 |
134 | /**
135 | * macro to add a key - value pair to the hash table
136 | * @note use this macro when size of key and/or value can be given by sizeof
137 | * @param table hash table to add element to
138 | * @param key pointer to the key for the hash table
139 | * @param value pointer to the value to be added against the key
140 | * @returns 0 on sucess
141 | * @returns -1 when no memory
142 | */
143 | #define HT_ADD(table, key, value) hash_table_add(table, (void *) key, sizeof(*key), (void *) value, sizeof(*value))
144 |
145 | /**
146 | * Function to add a key - value pair to the hash table, use HT_ADD macro
147 | * @param table hash table to add element to
148 | * @param key pointer to the key for the hash table
149 | * @param key_len length of the key in bytes
150 | * @param value pointer to the value to be added against the key
151 | * @param value_len length of the value in bytes
152 | * @returns 0 on sucess
153 | * @returns -1 when no memory
154 | */
155 | int hash_table_add(hash_table_t *, void *, size_t, void *, size_t);
156 |
157 | /**
158 | * macro to remove an hash table element (for a given key) from a given hash table
159 | * @note use this macro when size of key and/or value can be given by sizeof
160 | * @param table hash table from which element has to be removed
161 | * @param key pointer to the key which has to be removed
162 | * @returns 0 on sucess
163 | * @returns -1 when key is not found
164 | */
165 | #define HT_REMOVE(table, key) hash_table_remove(table, key, sizeof(*key))
166 |
167 | /**
168 | * Function to remove an hash table element (for a given key) from a given hash table
169 | * @param table hash table from which element has to be removed
170 | * @param key pointer to the key which has to be removed
171 | * @param key_len size of the key in bytes
172 | * @returns 0 on sucess
173 | * @returns -1 when key is not found
174 | */
175 | int hash_table_remove(hash_table_t *, void *, size_t);
176 |
177 | /**
178 | * macro to lookup a key in a particular table
179 | * @param table table to look key in
180 | * @param key pointer to key to be looked for
181 | * @returns NULL when key is not found in the hash table
182 | * @returns void* pointer to the value in the table
183 | */
184 | #define HT_LOOKUP(table, key) hash_table_lookup(table, key, sizeof(*key))
185 |
186 | /**
187 | * Function to lookup a key in a particular table
188 | * @note use this macro when size of key and/or value can be given by sizeof
189 | * @param table table to look key in
190 | * @param key pointer to key to be looked for
191 | * @param key_len size of the key to be searched
192 | * @returns NULL when key is not found in the hash table
193 | * @returns void* pointer to the value in the table
194 | */
195 | void * hash_table_lookup(hash_table_t *, void *, size_t);
196 |
197 | /**
198 | * macro to look if the exists in the hash table
199 | * @note use this macro when size of key and/or value can be given by sizeof
200 | * @param key pointer to key to be looked for
201 | * @returns 0 when key is not found
202 | * @returns 1 when key is found
203 | */
204 | #define HT_HAS_KEY(table, key) hash_table_has_key(table, key, sizeof(*key))
205 |
206 | /**
207 | * Function to look if the exists in the hash table
208 | * @param key pointer to key to be looked for
209 | * @param key_len size of the key to be searched
210 | * @returns 0 when key is not found
211 | * @returns 1 when key is found
212 | */
213 | int hash_table_has_key(hash_table_t *, void *, size_t);
214 |
215 | /**
216 | * Function to return all the keys in a given hash table
217 | * @param table hash table from which key are to be reterived
218 | * @param keys a void** pointer where keys are filled in (memory allocated internally and must be freed)
219 | * @return total number of keys filled in keys
220 | */
221 | size_t hash_table_get_keys(hash_table_t *, void **);
222 |
223 | /**
224 | * Function to get all elements (key - value pairs) from the given hash table
225 | * @param table hash table from which elements have to be retrieved
226 | * @param elements a pointer to an array of hash_table_element_t pointer (malloced by function)
227 | * @returns 1 when no memory
228 | * @returns count of elements
229 | */
230 | size_t hash_table_get_elements(hash_table_t *, hash_table_element_t *** );
231 |
232 | /**
233 | * Function to resize the hash table store house
234 | * @param table hash table to be resized
235 | * @param len new length of the hash table
236 | * @returns -1 when no elements in hash table
237 | * @returns -2 when no emmory for new store house
238 | * @returns 0 when sucess
239 | */
240 | int hash_table_resize(hash_table_t *, size_t);
241 |
242 | /**
243 | * Function to iterate through all elements of the hashtable
244 | * @param table hash table to be iterated
245 | * @param fct pointer to a function returning 1 if the element has to be removed
246 | * @param user arbitrary user pointer passed to the fct callback
247 | * @returns 0 when success
248 | */
249 | int hash_table_iterate(hash_table_t *table, int (*fct)(void *user,
250 | void *value, void *key, size_t key_len), void *user);
251 | #endif
252 |
--------------------------------------------------------------------------------
/main.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "hashtable.h"
3 |
4 | int main()
5 | {
6 | hash_table_t *table = hash_table_new(MODE_COPY);
7 | int i = 1;
8 | int val = 100;
9 | int val2 = 200;
10 | int j = 2;
11 | int x =0;
12 | for (x=0;x<3000;x++)
13 | {
14 | // use the macro
15 | HT_ADD(table, &j, &val);
16 | // or use the function
17 | //hash_table_add(table, &j, i, (void *) &val, sizeof(int));
18 | val++;
19 | j++;
20 | }
21 | hash_table_add(table, &j, i, (void *) &val2, 1);
22 | j--; j--;
23 | hash_table_remove(table, &j, i);
24 | HT_REMOVE(table, &j);
25 | if (hash_table_has_key(table, &j, i))
26 | {
27 | printf("Key found %d\n", j);
28 | }
29 | else
30 | {
31 | printf("Key NOT found %d\n", j);
32 | }
33 | val = -100;
34 | val2 = -200;
35 | j--;
36 | int *value = NULL;
37 | value = (int* ) HT_LOOKUP(table, &j);
38 | void** keys = NULL;
39 | size_t num = hash_table_get_keys(table, keys);
40 | printf("found %d keys\n", (int)num);
41 | printf("j -> %d \n", j);
42 | if (value)
43 | printf("value is %d\n", *value);
44 | else
45 | printf("*value is %p\n", value);
46 |
47 | return 0;
48 | }
49 |
--------------------------------------------------------------------------------