libamxc  1.10.3
C Generic Data Containers
test_amxc_htable.c
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** SPDX-License-Identifier: BSD-2-Clause-Patent
4 **
5 ** SPDX-FileCopyrightText: Copyright (c) 2023 SoftAtHome
6 **
7 ** Redistribution and use in source and binary forms, with or without modification,
8 ** are permitted provided that the following conditions are met:
9 **
10 ** 1. Redistributions of source code must retain the above copyright notice,
11 ** this list of conditions and the following disclaimer.
12 **
13 ** 2. Redistributions in binary form must reproduce the above copyright notice,
14 ** this list of conditions and the following disclaimer in the documentation
15 ** and/or other materials provided with the distribution.
16 **
17 ** Subject to the terms and conditions of this license, each copyright holder
18 ** and contributor hereby grants to those receiving rights under this license
19 ** a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable
20 ** (except for failure to satisfy the conditions of this license) patent license
21 ** to make, have made, use, offer to sell, sell, import, and otherwise transfer
22 ** this software, where such license applies only to those patent claims, already
23 ** acquired or hereafter acquired, licensable by such copyright holder or contributor
24 ** that are necessarily infringed by:
25 **
26 ** (a) their Contribution(s) (the licensed copyrights of copyright holders and
27 ** non-copyrightable additions of contributors, in source or binary form) alone;
28 ** or
29 **
30 ** (b) combination of their Contribution(s) with the work of authorship to which
31 ** such Contribution(s) was added by such copyright holder or contributor, if,
32 ** at the time the Contribution is added, such addition causes such combination
33 ** to be necessarily infringed. The patent license shall not apply to any other
34 ** combinations which include the Contribution.
35 **
36 ** Except as expressly stated above, no rights or licenses from any copyright
37 ** holder or contributor is granted under this license, whether expressly, by
38 ** implication, estoppel or otherwise.
39 **
40 ** DISCLAIMER
41 **
42 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
43 ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45 ** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
46 ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
48 ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
49 ** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50 ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
51 ** USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 **
53 ****************************************************************************/
54 
55 #include <stdio.h>
56 
57 #include <stdlib.h>
58 #include <setjmp.h>
59 #include <stdarg.h>
60 #include <cmocka.h>
61 #include <amxc/amxc_hash.h>
62 #include <amxc/amxc_htable.h>
63 
64 #include "test_amxc_htable.h"
65 
66 #include <amxc/amxc_macros.h>
67 static unsigned int deletes = 0;
68 static amxc_htable_t* htable = NULL;
69 static amxc_htable_it_t it[2000];
70 
71 static void amxc_htable_setup(void) {
72  assert_int_equal(amxc_htable_new(&htable, 0), 0);
73 
74  for(int i = 0; i < 30; i++) {
75  assert_int_equal(amxc_htable_it_init(&it[i]), 0);
76  }
77 }
78 
79 static void amxc_htable_teardown(void) {
80  amxc_htable_delete(&htable, NULL);
81 }
82 
83 static void amxc_delete_it_func(const char* key, amxc_htable_it_t* it) {
84  assert_ptr_not_equal(it, NULL);
85  assert_ptr_not_equal((char*) key, NULL);
86  assert_ptr_equal(it->key, NULL);
87  assert_ptr_equal(it->ait, NULL);
88  assert_ptr_equal(it->next, NULL);
89  deletes++;
90 }
91 
94  // passing NULL pointers should not lead to segfault
95  assert_int_equal(amxc_htable_new(NULL, 0), -1);
96  amxc_htable_delete(NULL, NULL);
98 }
99 
102  amxc_htable_t* htable = NULL;
103  assert_int_equal(amxc_htable_new(&htable, 0), 0);
104  assert_ptr_not_equal(htable, NULL);
105  assert_ptr_not_equal(htable->hfunc, NULL);
106  assert_ptr_not_equal(htable->table.buffer, NULL);
107  assert_int_equal(htable->items, 0);
108  assert_int_equal(amxc_array_capacity(&htable->table), 64);
109 
110  amxc_htable_delete(&htable, NULL);
111  assert_ptr_equal(htable, NULL);
113 }
114 
117  char key[10] = "";
118 
119  for(int i = 0; i < 30; i++) {
120  sprintf(key, "key%d", i);
121  assert_int_equal(amxc_htable_insert(htable, key, &it[i]), 0);
122  }
123 
125  assert_int_equal(deletes, 30);
127 }
128 
131  // passing NULL pointers should not lead to segfault
132  assert_int_equal(amxc_htable_init(NULL, 0), -1);
133  amxc_htable_clean(NULL, NULL);
135 }
136 
140 
141  assert_int_equal(amxc_htable_init(&htable, 0), 0);
142  assert_ptr_not_equal(htable.table.buffer, NULL);
143  assert_ptr_not_equal(htable.hfunc, NULL);
144  assert_int_equal(htable.items, 0);
145  assert_int_equal(amxc_array_capacity(&htable.table), 64);
146 
147  amxc_htable_clean(&htable, NULL);
148  assert_ptr_equal(htable.table.buffer, NULL);
149  assert_ptr_not_equal(htable.hfunc, NULL);
150  assert_int_equal(htable.items, 0);
151  assert_int_equal(amxc_array_capacity(&htable.table), 0);
153 }
154 
158 
159  assert_int_equal(amxc_htable_init(&htable, 32), 0);
160  assert_ptr_not_equal(htable.table.buffer, NULL);
161  assert_ptr_not_equal(htable.hfunc, NULL);
162  assert_int_equal(htable.items, 0);
163  assert_int_equal(amxc_array_capacity(&htable.table), 32);
164  amxc_htable_clean(&htable, NULL);
165 
166  assert_int_equal(amxc_htable_init(&htable, 66), 0);
167  assert_ptr_not_equal(htable.table.buffer, NULL);
168  assert_ptr_not_equal(htable.hfunc, NULL);
169  assert_int_equal(htable.items, 0);
170  assert_int_equal(amxc_array_capacity(&htable.table), 66);
171  amxc_htable_clean(&htable, NULL);
173 }
174 
177  // should not segfault
178  amxc_htable_set_hash_func(NULL, NULL);
179 
180  // check for default hash function
181  assert_ptr_equal(htable->hfunc, amxc_BKDR_hash);
182 
183  // change hash function
185  assert_ptr_equal(htable->hfunc, amxc_DJB_hash);
186 
187  // reset to default hash function
189  assert_ptr_equal(htable->hfunc, amxc_BKDR_hash);
191 }
192 
195  // should not segfault
196  assert_int_equal(amxc_htable_key2index(NULL, NULL), AMXC_HTABLE_RANGE);
197  assert_int_equal(amxc_htable_key2index(NULL, "data"), AMXC_HTABLE_RANGE);
198 
199  // delete the hash table buffer
200  amxc_htable_clean(htable, NULL);
201  assert_int_equal(amxc_htable_key2index(htable, "data"), AMXC_HTABLE_RANGE);
203 }
204 
207  // should not segfault
208  assert_int_equal(amxc_htable_key2index(htable, "Key1"), 18);
209  assert_int_equal(amxc_htable_key2index(htable, "Key2"), 19);
211 }
212 
215  assert_int_equal(amxc_htable_insert(NULL, NULL, NULL), -1);
216 
217  assert_int_equal(amxc_htable_insert(htable, NULL, NULL), -1);
218  assert_int_equal(htable->items, 0);
219 
220  assert_int_equal(amxc_htable_insert(htable, "", NULL), -1);
221  assert_int_equal(htable->items, 0);
222 
223  assert_int_equal(amxc_htable_insert(htable, "TestKey", NULL), -1);
224  assert_int_equal(htable->items, 0);
225 
226  assert_int_equal(amxc_htable_insert(htable, NULL, &it[0]), -1);
227  assert_int_equal(htable->items, 0);
229 }
230 
231 void amxc_htable_insert_check(UNUSED void** state) {
233  assert_int_equal(amxc_htable_insert(htable, "TestKey", &it[0]), 0);
234  assert_ptr_not_equal(it[0].ait, NULL);
235  assert_ptr_equal(it[0].ait->array, &htable->table);
236  assert_string_equal(it[0].key, "TestKey");
237  // it is the first item, so the next pointer should be 0
238  assert_ptr_equal(it[0].next, NULL);
239  assert_int_equal(htable->items, 1);
241 }
242 
245  assert_int_equal(amxc_htable_insert(htable, "TestKey", &it[0]), 0);
246  assert_ptr_not_equal(it[0].ait, NULL);
247  assert_ptr_equal(it[0].ait->array, &htable->table);
248  assert_string_equal(it[0].key, "TestKey");
249  // it is the first item, so the next pointer should be 0
250  assert_ptr_equal(it[0].next, NULL);
251  assert_int_equal(htable->items, 1);
252 
253  assert_int_equal(amxc_htable_insert(htable, "TestKey", &it[1]), 0);
254  assert_ptr_not_equal(it[1].ait, NULL);
255  assert_ptr_equal(it[1].ait->array, &htable->table);
256  assert_string_equal(it[1].key, "TestKey");
257  // it is the second item with same key, so the next pointer should be set to it[0]
258  assert_ptr_equal(it[1].next, &it[0]);
259 
260  // same position
261  assert_ptr_equal(it[0].ait, it[1].ait);
262  assert_int_equal(htable->items, 2);
264 }
265 
268  assert_int_equal(amxc_htable_insert(htable, "TestKey", &it[0]), 0);
269 
270  assert_int_equal(amxc_htable_insert(htable, "AnotherKey", &it[0]), 0);
271  assert_ptr_not_equal(it[0].ait, NULL);
272  assert_string_equal(it[0].key, "AnotherKey");
273  assert_int_equal(htable->items, 1);
274 
275  assert_int_equal(amxc_htable_insert(htable, "AnotherKey", &it[0]), 0);
276  assert_ptr_not_equal(it[0].ait, NULL);
277  assert_string_equal(it[0].key, "AnotherKey");
278  assert_int_equal(htable->items, 1);
280 }
281 
284  amxc_htable_delete(&htable, NULL);
285 
286  char key[10];
287  assert_int_equal(amxc_htable_new(&htable, 8), 0);
288  for(int i = 0; i < 30; i++) {
289  sprintf(key, "key%d", i);
290  assert_int_equal(amxc_htable_insert(htable, key, &it[i]), 0);
291  assert_ptr_not_equal(it[i].ait, NULL);
292  assert_string_equal(it[i].key, key);
293  assert_int_equal(htable->items, i + 1);
294  if(i == 6) {
295  assert_int_equal(amxc_htable_capacity(htable), 16);
296  }
297  if(i == 12) {
298  assert_int_equal(amxc_htable_capacity(htable), 32);
299  }
300  }
301 
302  assert_int_equal(amxc_htable_capacity(htable), 64);
304 }
305 
308  amxc_htable_delete(&htable, NULL);
309 
310  char key[10];
311  assert_int_equal(amxc_htable_new(&htable, 1025), 0);
312  for(int i = 0; i < 2000; i++) {
313  sprintf(key, "key%d", i);
314  assert_int_equal(amxc_htable_insert(htable, key, &it[i]), 0);
315  assert_ptr_not_equal(it[i].ait, NULL);
316  assert_string_equal(it[i].key, key);
317  assert_int_equal(htable->items, i + 1);
318  }
319 
320  assert_int_equal(amxc_htable_capacity(htable), 1025 + 1024 + 1024);
322 }
323 
326  assert_int_equal(amxc_htable_is_empty(NULL), true);
328 }
329 
330 void amxc_htable_is_empty_check(UNUSED void** state) {
332  assert_int_equal(amxc_htable_is_empty(htable), true);
333 
334  amxc_htable_insert(htable, "Key1", &it[0]);
335  assert_int_equal(amxc_htable_is_empty(htable), false);
336 
338 }
339 
342  assert_int_equal(amxc_htable_size(NULL), 0);
344 }
345 
346 void amxc_htable_size_check(UNUSED void** state) {
348  assert_int_equal(amxc_htable_size(htable), 0);
349 
350  amxc_htable_insert(htable, "Key1", &it[0]);
351  assert_int_equal(amxc_htable_size(htable), 1);
352 
353  amxc_htable_insert(htable, "Key1", &it[0]);
354  assert_int_equal(amxc_htable_size(htable), 1);
355 
356  amxc_htable_insert(htable, "Key2", &it[1]);
357  assert_int_equal(amxc_htable_size(htable), 2);
359 }
360 
363  assert_int_equal(amxc_htable_capacity(NULL), 0);
365 }
366 
367 void amxc_htable_capacity_check(UNUSED void** state) {
369  amxc_htable_delete(&htable, NULL);
370 
371  assert_int_equal(amxc_htable_new(&htable, 8), 0);
372  assert_int_equal(amxc_htable_capacity(htable), 8);
373 
374  assert_int_equal(amxc_htable_insert(htable, "key0", &it[0]), 0);
375  assert_int_equal(amxc_htable_insert(htable, "key1", &it[1]), 0);
376  assert_int_equal(amxc_htable_insert(htable, "key2", &it[2]), 0);
377  assert_int_equal(amxc_htable_insert(htable, "key3", &it[3]), 0);
378  assert_int_equal(amxc_htable_insert(htable, "key4", &it[4]), 0);
379  assert_int_equal(amxc_htable_insert(htable, "key5", &it[5]), 0);
380  assert_int_equal(amxc_htable_capacity(htable), 16);
382 }
383 
384 void amxc_htable_get_null_check(UNUSED void** state) {
386  assert_ptr_equal(amxc_htable_get(NULL, NULL), NULL);
387 
388  assert_ptr_equal(amxc_htable_get(htable, NULL), NULL);
389  assert_ptr_equal(amxc_htable_get(htable, ""), NULL);
391 }
392 
393 void amxc_htable_get_check(UNUSED void** state) {
395  amxc_htable_insert(htable, "Key1", &it[0]);
396  amxc_htable_insert(htable, "Key2", &it[1]);
397  amxc_htable_insert(htable, "Key3", &it[2]);
398  amxc_htable_insert(htable, "Key4", &it[3]);
399  amxc_htable_insert(htable, "Key5", &it[4]);
400 
401  assert_ptr_equal(amxc_htable_get(htable, "Key3"), &it[2]);
402  assert_string_equal(it[2].key, "Key3");
403  assert_ptr_not_equal(it[2].ait, NULL);
404 
405  assert_ptr_equal(amxc_htable_get(htable, "Key1"), &it[0]);
406  assert_string_equal(it[0].key, "Key1");
407  assert_ptr_not_equal(it[0].ait, NULL);
408 
409  assert_ptr_equal(amxc_htable_get(htable, "Key4"), &it[3]);
410  assert_string_equal(it[3].key, "Key4");
411  assert_ptr_not_equal(it[3].ait, NULL);
412 
413  assert_ptr_equal(amxc_htable_get(htable, "Key2"), &it[1]);
414  assert_string_equal(it[1].key, "Key2");
415  assert_ptr_not_equal(it[1].ait, NULL);
416 
417  assert_ptr_equal(amxc_htable_get(htable, "Key5"), &it[4]);
418  assert_string_equal(it[4].key, "Key5");
419  assert_ptr_not_equal(it[4].ait, NULL);
420 
421  assert_ptr_equal(amxc_htable_get(htable, "Dummy"), NULL);
422 
423  // clean the table
424  amxc_htable_clean(htable, NULL);
425  assert_ptr_equal(amxc_htable_get(htable, "Dummy"), NULL);
427 }
428 
431  amxc_htable_insert(htable, "Key1", &it[0]);
432  amxc_htable_insert(htable, "Key610", &it[1]);
433 
434  assert_ptr_equal(amxc_htable_get(htable, "Key610"), &it[1]);
435  assert_string_equal(it[1].key, "Key610");
436  assert_ptr_not_equal(it[1].ait, NULL);
437  assert_ptr_equal(it[1].next, &it[0]);
438 
439  assert_ptr_equal(amxc_htable_get(htable, "Key1"), &it[0]);
440  assert_string_equal(it[0].key, "Key1");
441  assert_ptr_not_equal(it[0].ait, NULL);
443 }
444 
447  assert_ptr_equal(amxc_htable_get_first(NULL), NULL);
448 
449  assert_ptr_equal(amxc_htable_get_first(htable), NULL);
451 }
452 
455  amxc_htable_insert(htable, "Key1", &it[0]);
456 
457  assert_ptr_equal(amxc_htable_get_first(htable), &it[0]);
458  assert_string_equal(it[0].key, "Key1");
459  assert_ptr_not_equal(it[0].ait, NULL);
460 
461  // clean the table
462  amxc_htable_clean(htable, NULL);
463  assert_ptr_equal(amxc_htable_get_first(htable), NULL);
465 }
466 
469  assert_ptr_equal(amxc_htable_get_last(NULL), NULL);
470 
471  assert_ptr_equal(amxc_htable_get_last(htable), NULL);
473 }
474 
475 void amxc_htable_get_last_check(UNUSED void** state) {
477  amxc_htable_insert(htable, "Key1", &it[0]);
478 
479  assert_ptr_equal(amxc_htable_get_last(htable), &it[0]);
480  assert_string_equal(it[0].key, "Key1");
481  assert_ptr_not_equal(it[0].ait, NULL);
482 
483  // clean the table
484  amxc_htable_clean(htable, NULL);
485  assert_ptr_equal(amxc_htable_get_last(htable), NULL);
487 }
488 
491  assert_ptr_equal(amxc_htable_take(NULL, NULL), NULL);
492 
493  assert_ptr_equal(amxc_htable_take(htable, NULL), NULL);
494  assert_ptr_equal(amxc_htable_take(htable, ""), NULL);
496 }
497 
498 void amxc_htable_take_check(UNUSED void** state) {
500  amxc_htable_insert(htable, "Key1", &it[0]);
501  amxc_htable_insert(htable, "Key2", &it[1]);
502  amxc_htable_insert(htable, "Key3", &it[2]);
503  amxc_htable_insert(htable, "Key4", &it[3]);
504  amxc_htable_insert(htable, "Key5", &it[4]);
505 
506  assert_ptr_equal(amxc_htable_take(htable, "Key3"), &it[2]);
507  assert_string_equal(it[2].key, "Key3");
508  assert_ptr_equal(it[2].ait, NULL);
509  assert_int_equal(htable->items, 4);
510 
511  assert_ptr_equal(amxc_htable_take(htable, "Key1"), &it[0]);
512  assert_string_equal(it[0].key, "Key1");
513  assert_ptr_equal(it[0].ait, NULL);
514  assert_int_equal(htable->items, 3);
515 
516  assert_ptr_equal(amxc_htable_take(htable, "Key4"), &it[3]);
517  assert_string_equal(it[3].key, "Key4");
518  assert_ptr_equal(it[3].ait, NULL);
519  assert_int_equal(htable->items, 2);
520 
521  assert_ptr_equal(amxc_htable_take(htable, "Key2"), &it[1]);
522  assert_string_equal(it[1].key, "Key2");
523  assert_ptr_equal(it[1].ait, NULL);
524  assert_int_equal(htable->items, 1);
525 
526  assert_ptr_equal(amxc_htable_take(htable, "Key5"), &it[4]);
527  assert_string_equal(it[4].key, "Key5");
528  assert_ptr_equal(it[4].ait, NULL);
529  assert_int_equal(htable->items, 0);
530 
531  amxc_htable_it_clean(&it[0], NULL);
532  amxc_htable_it_clean(&it[1], NULL);
533  amxc_htable_it_clean(&it[2], NULL);
534  amxc_htable_it_clean(&it[3], NULL);
535  amxc_htable_it_clean(&it[4], NULL);
537 }
538 
541  amxc_htable_insert(htable, "Key1", &it[0]);
542  amxc_htable_insert(htable, "Key610", &it[1]);
543 
544  assert_ptr_equal(amxc_htable_take(htable, "Key610"), &it[1]);
545  assert_string_equal(it[1].key, "Key610");
546  assert_ptr_equal(it[1].ait, NULL);
547  assert_ptr_equal(it[1].next, NULL);
548  assert_int_equal(htable->items, 1);
549 
550  assert_ptr_equal(amxc_htable_take(htable, "Key1"), &it[0]);
551  assert_string_equal(it[0].key, "Key1");
552  assert_ptr_equal(it[0].ait, NULL);
553  assert_int_equal(htable->items, 0);
554 
555  assert_ptr_equal(amxc_htable_take(htable, "Dummy"), NULL);
556 
557  amxc_htable_it_clean(&it[0], NULL);
558  amxc_htable_it_clean(&it[1], NULL);
560 }
561 
564  assert_ptr_equal(amxc_htable_take_first(NULL), NULL);
565 
566  assert_ptr_equal(amxc_htable_take_first(htable), NULL);
568 }
569 
572  amxc_htable_insert(htable, "Key1", &it[0]);
573 
574  assert_ptr_equal(amxc_htable_take_first(htable), &it[0]);
575  assert_string_equal(it[0].key, "Key1");
576  assert_ptr_equal(it[0].ait, NULL);
577 
578  amxc_htable_it_clean(&it[0], NULL);
579 
580  // clean the table
581  amxc_htable_clean(htable, NULL);
582  assert_ptr_equal(amxc_htable_take_first(htable), NULL);
584 }
585 
588  assert_int_equal(amxc_htable_contains(NULL, NULL), false);
589 
590  assert_int_equal(amxc_htable_contains(htable, NULL), false);
591  assert_int_equal(amxc_htable_contains(htable, ""), false);
593 }
594 
595 void amxc_htable_contains_check(UNUSED void** state) {
597  amxc_htable_insert(htable, "Key1", &it[0]);
598  amxc_htable_insert(htable, "Key2", &it[1]);
599 
600  assert_int_equal(amxc_htable_contains(htable, "Key1"), true);
601  assert_int_equal(amxc_htable_contains(htable, "Key2"), true);
602  assert_int_equal(amxc_htable_contains(htable, "Key3"), false);
604 }
605 
608  assert_ptr_equal(amxc_htable_it_get_next(NULL), NULL);
609  assert_ptr_equal(amxc_htable_it_get_next(&it[0]), NULL);
611 }
612 
615  amxc_htable_insert(htable, "Key1", &it[0]);
616  amxc_htable_insert(htable, "Key2", &it[1]);
617  amxc_htable_insert(htable, "Key3", &it[2]);
618  amxc_htable_insert(htable, "Key4", &it[3]);
619  amxc_htable_insert(htable, "Key5", &it[4]);
620 
621  unsigned int count = 0;
623  while(it) {
625  count++;
626  }
627 
628  assert_int_equal(count, 5);
630 }
631 
634  amxc_htable_insert(htable, "Key", &it[0]);
635  amxc_htable_insert(htable, "Key", &it[1]);
636  amxc_htable_insert(htable, "Key", &it[2]);
637  amxc_htable_insert(htable, "Key", &it[3]);
638  amxc_htable_insert(htable, "Key", &it[4]);
639 
640  amxc_array_it_t* ait = it[0].ait;
641  unsigned int count = 0;
643  while(it) {
644  assert_ptr_equal(it->ait, ait);
646  count++;
647  }
648 
649  assert_int_equal(count, 5);
651 }
652 
655  assert_ptr_equal(amxc_htable_it_get_next_key(NULL), NULL);
656  assert_ptr_equal(amxc_htable_it_get_next_key(&it[0]), NULL);
658 }
659 
662  amxc_htable_insert(htable, "Key1", &it[0]);
663  amxc_htable_insert(htable, "Key2", &it[1]);
664  amxc_htable_insert(htable, "Key3", &it[2]);
665  amxc_htable_insert(htable, "Key4", &it[3]);
666  amxc_htable_insert(htable, "Key5", &it[4]);
667  amxc_htable_insert(htable, "Key610", &it[11]);
668  amxc_htable_insert(htable, "Key1", &it[5]);
669  amxc_htable_insert(htable, "Key2", &it[6]);
670  amxc_htable_insert(htable, "Key3", &it[7]);
671  amxc_htable_insert(htable, "Key1", &it[8]);
672  amxc_htable_insert(htable, "Key2", &it[9]);
673  amxc_htable_insert(htable, "Key3", &it[10]);
674 
675  unsigned int count = 0;
676  amxc_array_it_t* ait = it[0].ait;
677  amxc_htable_it_t* iter = amxc_htable_get(htable, "Key1");
678  while(iter) {
679  assert_ptr_equal(iter->ait, ait);
680  iter = amxc_htable_it_get_next_key(iter);
681  count++;
682  }
683 
684  assert_int_equal(count, 3);
685 
686  count = 0;
687  ait = it[2].ait;
688  iter = amxc_htable_get(htable, "Key3");
689  while(iter) {
690  assert_ptr_equal(iter->ait, ait);
691  iter = amxc_htable_it_get_next_key(iter);
692  count++;
693  }
694 
695  assert_int_equal(count, 3);
696 
697  count = 0;
698  iter = amxc_htable_get(htable, "Key4");
699  while(iter) {
700  iter = amxc_htable_it_get_next_key(iter);
701  count++;
702  }
703 
704  assert_int_equal(count, 1);
706 }
707 
710  assert_ptr_equal(amxc_htable_it_get_previous(NULL), NULL);
711  assert_ptr_equal(amxc_htable_it_get_previous(&it[0]), NULL);
713 }
714 
717  amxc_htable_insert(htable, "Key1", &it[0]);
718  amxc_htable_insert(htable, "Key2", &it[1]);
719  amxc_htable_insert(htable, "Key3", &it[2]);
720  amxc_htable_insert(htable, "Key4", &it[3]);
721  amxc_htable_insert(htable, "Key5", &it[4]);
722 
723  unsigned int count = 0;
725  while(it) {
727  count++;
728  }
729 
730  assert_int_equal(count, 5);
732 }
733 
736  amxc_htable_insert(htable, "Key", &it[0]);
737  amxc_htable_insert(htable, "Key", &it[1]);
738  amxc_htable_insert(htable, "Key", &it[2]);
739  amxc_htable_insert(htable, "Key", &it[3]);
740  amxc_htable_insert(htable, "Key", &it[4]);
741 
742  amxc_array_it_t* ait = it[0].ait;
743  unsigned int count = 0;
745  while(it) {
746  assert_ptr_equal(it->ait, ait);
748  count++;
749  }
750 
751  assert_int_equal(count, 5);
753 }
754 
757  assert_ptr_equal(amxc_htable_it_get_previous(NULL), NULL);
758  assert_ptr_equal(amxc_htable_it_get_previous(&it[0]), NULL);
760 }
761 
764  amxc_htable_insert(htable, "Key1", &it[0]);
765  amxc_htable_insert(htable, "Key2", &it[1]);
766  amxc_htable_insert(htable, "Key3", &it[2]);
767  amxc_htable_insert(htable, "Key4", &it[3]);
768  amxc_htable_insert(htable, "Key5", &it[4]);
769  amxc_htable_insert(htable, "Key610", &it[11]);
770  amxc_htable_insert(htable, "Key1", &it[5]);
771  amxc_htable_insert(htable, "Key2", &it[6]);
772  amxc_htable_insert(htable, "Key3", &it[7]);
773  amxc_htable_insert(htable, "Key1", &it[8]);
774  amxc_htable_insert(htable, "Key2", &it[9]);
775  amxc_htable_insert(htable, "Key3", &it[10]);
776 
777  unsigned int count = 0;
778  amxc_array_it_t* ait = it[0].ait;
779  amxc_htable_it_t* iter = amxc_htable_get(htable, "Key1");
780  while(iter) {
781  assert_ptr_equal(iter->ait, ait);
782  iter = amxc_htable_it_get_previous_key(iter);
783  count++;
784  }
785 
786  assert_int_equal(count, 3);
787 
788  count = 0;
789  ait = it[2].ait;
790  iter = amxc_htable_get(htable, "Key3");
791  while(iter) {
792  assert_ptr_equal(iter->ait, ait);
793  iter = amxc_htable_it_get_previous_key(iter);
794  count++;
795  }
796 
797  assert_int_equal(count, 3);
798 
799  count = 0;
800  iter = amxc_htable_get(htable, "Key4");
801  while(iter) {
802  iter = amxc_htable_it_get_previous_key(iter);
803  count++;
804  }
805 
806  assert_int_equal(count, 1);
808 }
809 
812  amxc_htable_it_take(NULL);
813  amxc_htable_it_take(&it[0]);
815 }
816 
817 void amxc_htable_it_take_check(UNUSED void** state) {
819  amxc_htable_insert(htable, "Key1", &it[0]);
820  amxc_htable_insert(htable, "Key2", &it[1]);
821  amxc_htable_insert(htable, "Key3", &it[2]);
822  amxc_htable_insert(htable, "Key4", &it[3]);
823  amxc_htable_insert(htable, "Key5", &it[4]);
824 
825  amxc_htable_it_take(&it[3]);
826  assert_int_equal(amxc_htable_size(htable), 4);
827  assert_string_equal(it[3].key, "Key4");
828  assert_ptr_equal(it[3].ait, NULL);
829  assert_ptr_equal(it[3].next, NULL);
830 
831  amxc_htable_it_take(&it[4]);
832  assert_int_equal(amxc_htable_size(htable), 3);
833  assert_string_equal(it[4].key, "Key5");
834  assert_ptr_equal(it[4].ait, NULL);
835  assert_ptr_equal(it[4].next, NULL);
836 
837  amxc_htable_it_clean(&it[3], NULL);
838  amxc_htable_it_clean(&it[4], NULL);
840 }
841 
844  amxc_htable_insert(htable, "Key", &it[0]);
845  amxc_htable_insert(htable, "Key", &it[1]);
846  amxc_htable_insert(htable, "Key", &it[2]);
847  amxc_htable_insert(htable, "Key", &it[3]);
848  amxc_htable_insert(htable, "Key", &it[4]);
849 
850  amxc_htable_it_take(&it[2]);
851  assert_int_equal(amxc_htable_size(htable), 4);
852  assert_string_equal(it[2].key, "Key");
853  assert_ptr_equal(it[2].ait, NULL);
854  assert_ptr_equal(it[2].next, NULL);
855 
856  amxc_htable_it_take(&it[0]);
857  assert_int_equal(amxc_htable_size(htable), 3);
858  assert_string_equal(it[0].key, "Key");
859  assert_ptr_equal(it[0].ait, NULL);
860  assert_ptr_equal(it[0].next, NULL);
861 
862  amxc_htable_it_take(&it[4]);
863  assert_int_equal(amxc_htable_size(htable), 2);
864  assert_string_equal(it[4].key, "Key");
865  assert_ptr_equal(it[4].ait, NULL);
866  assert_ptr_equal(it[4].next, NULL);
867 
868  amxc_htable_it_clean(&it[0], NULL);
869  amxc_htable_it_clean(&it[2], NULL);
870  amxc_htable_it_clean(&it[4], NULL);
872 }
873 
876  assert_ptr_equal((void*) amxc_htable_it_get_key(NULL), NULL);
877  assert_ptr_equal((void*) amxc_htable_it_get_key(&it[0]), NULL);
878 
879  amxc_htable_insert(htable, "SomeKey", &it[0]);
880  assert_string_equal(amxc_htable_it_get_key(&it[0]), "SomeKey");
881  amxc_htable_take(htable, "SomeKey");
882  assert_string_equal(amxc_htable_it_get_key(&it[0]), "SomeKey");
883 
884  amxc_htable_it_clean(&it[0], NULL);
886 }
887 
890  amxc_htable_it_init(NULL);
892 }
893 
896  amxc_htable_it_clean(NULL, NULL);
898 }
899 
902  deletes = 0;
903  amxc_htable_insert(htable, "SomeKey", &it[0]);
904  assert_string_equal(it[0].key, "SomeKey");
906  assert_int_equal(deletes, 1);
908 }
909 
912  amxc_htable_delete(&htable, NULL);
913  amxc_array_t* array = NULL;
914 
915  char key[10];
916  assert_int_equal(amxc_htable_new(&htable, 1025), 0);
917  for(int i = 0; i < 2000; i++) {
918  sprintf(key, "key%4d", i);
919  assert_int_equal(amxc_htable_insert(htable, key, &it[i]), 0);
920  assert_ptr_not_equal(it[i].ait, NULL);
921  assert_string_equal(it[i].key, key);
922  assert_int_equal(htable->items, i + 1);
923  }
924 
925  assert_int_equal(amxc_htable_capacity(htable), 1025 + 1024 + 1024);
927  assert_non_null(array);
928  assert_int_equal(amxc_array_size(array), 2000);
929 
930  for(int i = 0; i < 2000; i++) {
931  const char* ak = (const char*) amxc_array_get_data_at(array, i);
932  sprintf(key, "key%4d", i);
933  assert_string_equal(ak, key);
934  }
935 
936  amxc_array_delete(&array, NULL);
937  amxc_htable_clean(htable, NULL);
938 
940  assert_null(array);
942  assert_null(array);
943 
945 }
946 
947 void amxc_htable_move_check(UNUSED void** state) {
949  amxc_htable_delete(&htable, NULL);
950 
951  amxc_htable_t dest;
952  amxc_htable_init(&dest, 0);
953 
954  char key[10];
955  assert_int_equal(amxc_htable_new(&htable, 1025), 0);
956  for(int i = 0; i < 2000; i++) {
957  sprintf(key, "key%4d", i);
958  assert_int_equal(amxc_htable_insert(htable, key, &it[i]), 0);
959  assert_ptr_not_equal(it[i].ait, NULL);
960  assert_string_equal(it[i].key, key);
961  assert_int_equal(htable->items, i + 1);
962  }
963 
964  for(int i = 0; i < 2000; i++) {
965  sprintf(key, "key%4d", i);
966  assert_true(amxc_htable_contains(htable, key));
967  assert_ptr_equal(amxc_htable_get(htable, key), &it[i]);
968  }
969 
970  assert_int_equal(amxc_htable_move(&dest, htable), 0);
971  assert_int_equal(amxc_htable_size(&dest), 2000);
972  assert_true(amxc_htable_is_empty(htable));
973 
974  for(int i = 0; i < 2000; i++) {
975  sprintf(key, "key%4d", i);
976  assert_true(amxc_htable_contains(&dest, key));
977  assert_ptr_equal(amxc_htable_get(&dest, key), &it[i]);
978  }
979 
980  assert_int_equal(amxc_htable_move(htable, &dest), 0);
981 
982  assert_int_not_equal(amxc_htable_move(NULL, htable), 0);
983  assert_int_not_equal(amxc_htable_move(&dest, NULL), 0);
984 
985  amxc_htable_clean(&dest, NULL);
987 }
988 
989 void amxc_htable_check_null_ptr(UNUSED void** state) {
990  htable = (amxc_htable_t*) calloc(1, sizeof(amxc_htable_t));
991  assert_non_null(htable);
992  assert_int_not_equal(amxc_htable_insert(htable, "Key", &it[0]), 0);
993  assert_int_equal(amxc_htable_init(htable, 10), 0);
994  assert_int_equal(amxc_htable_insert(htable, "Key", &it[0]), 0);
995  amxc_htable_delete(&htable, NULL);
996 }
Ambiorix string hash functions header file.
Ambiorix hash table API header file.
#define UNUSED
Definition: amxc_macros.h:70
AMXC_INLINE size_t amxc_array_capacity(const amxc_array_t *const array)
Gets the capacity of the array.
Definition: amxc_array.h:694
size_t amxc_array_size(const amxc_array_t *const array)
Calculates the number of used items in the array.
Definition: amxc_array.c:415
AMXC_INLINE void * amxc_array_get_data_at(const amxc_array_t *const array, const unsigned int index)
Gets the data pointer of the item at the given index.
Definition: amxc_array.h:711
void amxc_array_delete(amxc_array_t **array, const amxc_array_it_delete_t func)
Frees the previously allocated array.
Definition: amxc_array.c:213
unsigned int amxc_BKDR_hash(const char *str, const unsigned int len)
Calculate a hash from a string.
unsigned int amxc_DJB_hash(const char *str, const unsigned int len)
Calculate a hash from a string.
amxc_htable_it_t * amxc_htable_it_get_next(const amxc_htable_it_t *const reference)
Gets the next iterator in the hash table.
int amxc_htable_it_init(amxc_htable_it_t *const it)
Initializes a hash table.iterator.
void amxc_htable_it_clean(amxc_htable_it_t *const it, amxc_htable_it_delete_t func)
Removes the iterator from the htable and frees allocated memory.
amxc_htable_it_t * amxc_htable_it_get_next_key(const amxc_htable_it_t *const reference)
Gets the next iterator in the hash table with the same key.
void amxc_htable_it_take(amxc_htable_it_t *const it)
Removes the iterator from the hash table.
amxc_htable_it_t * amxc_htable_it_get_previous(const amxc_htable_it_t *const reference)
Gets the previous iterator in the hash table.
AMXC_INLINE const char * amxc_htable_it_get_key(const amxc_htable_it_t *const it)
Gets the key from the iterator.
Definition: amxc_htable.h:672
amxc_htable_it_t * amxc_htable_it_get_previous_key(const amxc_htable_it_t *const reference)
Gets the previous iterator in the hash table with the same key.
int amxc_htable_init(amxc_htable_t *const htable, const size_t reserve)
Initializes a hash table.
Definition: amxc_htable.c:185
void amxc_htable_delete(amxc_htable_t **htable, amxc_htable_it_delete_t func)
Frees the previously allocated hash table.
Definition: amxc_htable.c:172
amxc_array_t * amxc_htable_get_sorted_keys(const amxc_htable_t *const htable)
Creates an array containing all keys of the hash table.
Definition: amxc_htable.c:339
amxc_htable_it_t * amxc_htable_get_first(const amxc_htable_t *const htable)
Gets the first item stored in the table.
Definition: amxc_htable.c:313
int amxc_htable_new(amxc_htable_t **htable, const size_t reserve)
Allocates a hash table.
Definition: amxc_htable.c:148
AMXC_INLINE size_t amxc_htable_size(const amxc_htable_t *const htable)
Calculates the size of the hash table.
Definition: amxc_htable.h:334
AMXC_INLINE bool amxc_htable_contains(const amxc_htable_t *const htable, const char *const key)
Verifies that a key is in the hash table.
Definition: amxc_htable.h:512
AMXC_INLINE bool amxc_htable_is_empty(const amxc_htable_t *const htable)
Checks that the hash table is empty.
Definition: amxc_htable.h:311
int amxc_htable_move(amxc_htable_t *const dest, amxc_htable_t *const src)
Moves all items from one hash table to another hash table.
Definition: amxc_htable.c:363
unsigned int amxc_htable_key2index(const amxc_htable_t *const htable, const char *const key)
Converts a key into an index.
Definition: amxc_htable.c:225
amxc_htable_it_t * amxc_htable_take(amxc_htable_t *const htable, const char *const key)
Removes a hash table iterator from the hash table.
Definition: amxc_htable.c:304
amxc_htable_it_t * amxc_htable_get_last(const amxc_htable_t *const htable)
Gets the last item stored in the table.
Definition: amxc_htable.c:326
amxc_htable_it_t * amxc_htable_get(const amxc_htable_t *const htable, const char *const key)
Gets a hash table iterator from the hash table.
Definition: amxc_htable.c:278
AMXC_INLINE size_t amxc_htable_capacity(const amxc_htable_t *const htable)
Calculates the capacity of the hash table.
Definition: amxc_htable.h:351
AMXC_INLINE amxc_htable_it_t * amxc_htable_take_first(const amxc_htable_t *const htable)
Removes the first item stored in the table.
Definition: amxc_htable.h:696
int amxc_htable_insert(amxc_htable_t *const htable, const char *const key, amxc_htable_it_t *const it)
Inserts an item in the hash table.
Definition: amxc_htable.c:237
void amxc_htable_clean(amxc_htable_t *const htable, amxc_htable_it_delete_t func)
Removes all items from the hash table.
Definition: amxc_htable.c:200
#define AMXC_HTABLE_RANGE
Out of range indicator.
Definition: amxc_htable.h:129
void amxc_htable_set_hash_func(amxc_htable_t *const htable, amxc_htable_hash_func_t func)
Sets the hash function for the hash table.
Definition: amxc_htable.c:211
The array iterator structure.
Definition: amxc_array.h:174
The array structure.
Definition: amxc_array.h:162
struct _amxc_array_it * buffer
Definition: amxc_array.h:166
The hash table iterator structure.
Definition: amxc_htable.h:138
amxc_array_it_t * ait
Definition: amxc_htable.h:139
amxc_htable_it_t * next
Definition: amxc_htable.h:141
The hash table structure.
Definition: amxc_htable.h:175
amxc_array_t table
Definition: amxc_htable.h:176
size_t items
Definition: amxc_htable.h:177
amxc_htable_hash_func_t hfunc
Definition: amxc_htable.h:178
static unsigned int array[2006]
void amxc_htable_init_reserve_check(UNUSED void **state)
void amxc_htable_it_get_previous_key_check(UNUSED void **state)
void amxc_htable_take_first_null_check(UNUSED void **state)
void amxc_htable_insert_null_check(UNUSED void **state)
static unsigned int deletes
void amxc_htable_get_last_check(UNUSED void **state)
void amxc_htable_init_clean_null_check(UNUSED void **state)
void amxc_htable_check_null_ptr(UNUSED void **state)
void amxc_htable_key2index_null_check(UNUSED void **state)
void amxc_htable_size_null_check(UNUSED void **state)
void amxc_htable_init_clean_check(UNUSED void **state)
void amxc_htable_it_get_previous_check(UNUSED void **state)
void amxc_htable_move_check(UNUSED void **state)
void amxc_htable_it_take_null_check(UNUSED void **state)
void amxc_htable_it_get_previous_null_check(UNUSED void **state)
void amxc_htable_get_null_check(UNUSED void **state)
static amxc_htable_it_t it[2000]
void amxc_htable_set_hash_func_check(UNUSED void **state)
void amxc_htable_it_clean_null_check(UNUSED void **state)
void amxc_htable_insert_grow_check(UNUSED void **state)
void amxc_htable_delete_func_check(UNUSED void **state)
void amxc_htable_it_get_next_key_check(UNUSED void **state)
void amxc_htable_capacity_null_check(UNUSED void **state)
void amxc_htable_get_check(UNUSED void **state)
void amxc_htable_new_delete_check(UNUSED void **state)
void amxc_htable_contains_check(UNUSED void **state)
void amxc_htable_it_get_next_key_null_check(UNUSED void **state)
void amxc_htable_new_delete_null_check(UNUSED void **state)
void amxc_htable_insert_same_key_check(UNUSED void **state)
void amxc_htable_size_check(UNUSED void **state)
void amxc_htable_get_first_check(UNUSED void **state)
void amxc_htable_insert_same_it_check(UNUSED void **state)
void amxc_htable_key2index_check(UNUSED void **state)
void amxc_htable_take_check(UNUSED void **state)
void amxc_htable_get_first_null_check(UNUSED void **state)
void amxc_htable_contains_null_check(UNUSED void **state)
void amxc_htable_it_get_next_chained_check(UNUSED void **state)
void amxc_htable_it_get_key_check(UNUSED void **state)
void amxc_htable_insert_check(UNUSED void **state)
void amxc_htable_it_take_check(UNUSED void **state)
void amxc_htable_it_get_previous_chained_check(UNUSED void **state)
void amxc_htable_it_get_previous_key_null_check(UNUSED void **state)
void amxc_htable_is_empty_null_check(UNUSED void **state)
void amxc_htable_get_sorted_keys_check(UNUSED void **state)
void amxc_htable_take_null_check(UNUSED void **state)
void amxc_htable_get_chained_check(UNUSED void **state)
void amxc_htable_insert_grow_big_check(UNUSED void **state)
void amxc_htable_it_clean_func_check(UNUSED void **state)
static amxc_htable_t * htable
void amxc_htable_get_last_null_check(UNUSED void **state)
static void amxc_delete_it_func(const char *key, amxc_htable_it_t *it)
static void amxc_htable_setup(void)
static void amxc_htable_teardown(void)
void amxc_htable_it_init_null_check(UNUSED void **state)
void amxc_htable_take_chained_check(UNUSED void **state)
void amxc_htable_take_first_check(UNUSED void **state)
void amxc_htable_it_get_next_null_check(UNUSED void **state)
void amxc_htable_it_take_chained_check(UNUSED void **state)
void amxc_htable_capacity_check(UNUSED void **state)
void amxc_htable_it_get_next_check(UNUSED void **state)
void amxc_htable_is_empty_check(UNUSED void **state)