1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 #include "alloc-util.h"
6 #include "string-util.h"
11 void test_hashmap_funcs(void);
13 static void test_hashmap_replace(void) {
15 char *val1
, *val2
, *val3
, *val4
, *val5
, *r
;
17 log_info("%s", __func__
);
19 m
= hashmap_new(&string_hash_ops
);
21 val1
= strdup("val1");
23 val2
= strdup("val2");
25 val3
= strdup("val3");
27 val4
= strdup("val4");
29 val5
= strdup("val5");
32 hashmap_put(m
, "key 1", val1
);
33 hashmap_put(m
, "key 2", val2
);
34 hashmap_put(m
, "key 3", val3
);
35 hashmap_put(m
, "key 4", val4
);
37 hashmap_replace(m
, "key 3", val1
);
38 r
= hashmap_get(m
, "key 3");
39 assert_se(streq(r
, "val1"));
41 hashmap_replace(m
, "key 5", val5
);
42 r
= hashmap_get(m
, "key 5");
43 assert_se(streq(r
, "val5"));
53 static void test_hashmap_copy(void) {
55 char *val1
, *val2
, *val3
, *val4
, *r
;
57 log_info("%s", __func__
);
59 val1
= strdup("val1");
61 val2
= strdup("val2");
63 val3
= strdup("val3");
65 val4
= strdup("val4");
68 m
= hashmap_new(&string_hash_ops
);
70 hashmap_put(m
, "key 1", val1
);
71 hashmap_put(m
, "key 2", val2
);
72 hashmap_put(m
, "key 3", val3
);
73 hashmap_put(m
, "key 4", val4
);
75 copy
= hashmap_copy(m
);
77 r
= hashmap_get(copy
, "key 1");
78 assert_se(streq(r
, "val1"));
79 r
= hashmap_get(copy
, "key 2");
80 assert_se(streq(r
, "val2"));
81 r
= hashmap_get(copy
, "key 3");
82 assert_se(streq(r
, "val3"));
83 r
= hashmap_get(copy
, "key 4");
84 assert_se(streq(r
, "val4"));
86 hashmap_free_free(copy
);
90 static void test_hashmap_get_strv(void) {
93 char *val1
, *val2
, *val3
, *val4
;
95 log_info("%s", __func__
);
97 val1
= strdup("val1");
99 val2
= strdup("val2");
101 val3
= strdup("val3");
103 val4
= strdup("val4");
106 m
= hashmap_new(&string_hash_ops
);
108 hashmap_put(m
, "key 1", val1
);
109 hashmap_put(m
, "key 2", val2
);
110 hashmap_put(m
, "key 3", val3
);
111 hashmap_put(m
, "key 4", val4
);
113 strv
= hashmap_get_strv(m
);
116 strv
= strv_sort(strv
);
119 assert_se(streq(strv
[0], "val1"));
120 assert_se(streq(strv
[1], "val2"));
121 assert_se(streq(strv
[2], "val3"));
122 assert_se(streq(strv
[3], "val4"));
129 static void test_hashmap_move_one(void) {
131 char *val1
, *val2
, *val3
, *val4
, *r
;
133 log_info("%s", __func__
);
135 val1
= strdup("val1");
137 val2
= strdup("val2");
139 val3
= strdup("val3");
141 val4
= strdup("val4");
144 m
= hashmap_new(&string_hash_ops
);
145 n
= hashmap_new(&string_hash_ops
);
147 hashmap_put(m
, "key 1", val1
);
148 hashmap_put(m
, "key 2", val2
);
149 hashmap_put(m
, "key 3", val3
);
150 hashmap_put(m
, "key 4", val4
);
152 assert_se(hashmap_move_one(n
, NULL
, "key 3") == -ENOENT
);
153 assert_se(hashmap_move_one(n
, m
, "key 5") == -ENOENT
);
154 assert_se(hashmap_move_one(n
, m
, "key 3") == 0);
155 assert_se(hashmap_move_one(n
, m
, "key 4") == 0);
157 r
= hashmap_get(n
, "key 3");
158 assert_se(r
&& streq(r
, "val3"));
159 r
= hashmap_get(n
, "key 4");
160 assert_se(r
&& streq(r
, "val4"));
161 r
= hashmap_get(m
, "key 3");
164 assert_se(hashmap_move_one(n
, m
, "key 3") == -EEXIST
);
166 hashmap_free_free(m
);
167 hashmap_free_free(n
);
170 static void test_hashmap_move(void) {
172 char *val1
, *val2
, *val3
, *val4
, *r
;
174 log_info("%s", __func__
);
176 val1
= strdup("val1");
178 val2
= strdup("val2");
180 val3
= strdup("val3");
182 val4
= strdup("val4");
185 m
= hashmap_new(&string_hash_ops
);
186 n
= hashmap_new(&string_hash_ops
);
188 hashmap_put(n
, "key 1", strdup(val1
));
189 hashmap_put(m
, "key 1", val1
);
190 hashmap_put(m
, "key 2", val2
);
191 hashmap_put(m
, "key 3", val3
);
192 hashmap_put(m
, "key 4", val4
);
194 assert_se(hashmap_move(n
, NULL
) == 0);
195 assert_se(hashmap_move(n
, m
) == 0);
197 assert_se(hashmap_size(m
) == 1);
198 r
= hashmap_get(m
, "key 1");
199 assert_se(r
&& streq(r
, "val1"));
201 r
= hashmap_get(n
, "key 1");
202 assert_se(r
&& streq(r
, "val1"));
203 r
= hashmap_get(n
, "key 2");
204 assert_se(r
&& streq(r
, "val2"));
205 r
= hashmap_get(n
, "key 3");
206 assert_se(r
&& streq(r
, "val3"));
207 r
= hashmap_get(n
, "key 4");
208 assert_se(r
&& streq(r
, "val4"));
210 hashmap_free_free(m
);
211 hashmap_free_free(n
);
214 static void test_hashmap_update(void) {
216 char *val1
, *val2
, *r
;
218 log_info("%s", __func__
);
220 m
= hashmap_new(&string_hash_ops
);
221 val1
= strdup("old_value");
223 val2
= strdup("new_value");
226 hashmap_put(m
, "key 1", val1
);
227 r
= hashmap_get(m
, "key 1");
228 assert_se(streq(r
, "old_value"));
230 assert_se(hashmap_update(m
, "key 2", val2
) == -ENOENT
);
231 r
= hashmap_get(m
, "key 1");
232 assert_se(streq(r
, "old_value"));
234 assert_se(hashmap_update(m
, "key 1", val2
) == 0);
235 r
= hashmap_get(m
, "key 1");
236 assert_se(streq(r
, "new_value"));
243 static void test_hashmap_put(void) {
245 int valid_hashmap_put
;
246 void *val1
= (void*) "val 1";
247 void *val2
= (void*) "val 2";
248 _cleanup_free_
char* key1
= NULL
;
250 log_info("%s", __func__
);
252 assert_se(hashmap_ensure_allocated(&m
, &string_hash_ops
) >= 0);
255 valid_hashmap_put
= hashmap_put(m
, "key 1", val1
);
256 assert_se(valid_hashmap_put
== 1);
257 assert_se(hashmap_put(m
, "key 1", val1
) == 0);
258 assert_se(hashmap_put(m
, "key 1", val2
) == -EEXIST
);
259 key1
= strdup("key 1");
260 assert_se(hashmap_put(m
, key1
, val1
) == 0);
261 assert_se(hashmap_put(m
, key1
, val2
) == -EEXIST
);
266 static void test_hashmap_remove(void) {
267 _cleanup_hashmap_free_ Hashmap
*m
= NULL
;
270 log_info("%s", __func__
);
272 r
= hashmap_remove(NULL
, "key 1");
273 assert_se(r
== NULL
);
275 m
= hashmap_new(&string_hash_ops
);
278 r
= hashmap_remove(m
, "no such key");
279 assert_se(r
== NULL
);
281 hashmap_put(m
, "key 1", (void*) "val 1");
282 hashmap_put(m
, "key 2", (void*) "val 2");
284 r
= hashmap_remove(m
, "key 1");
285 assert_se(streq(r
, "val 1"));
287 r
= hashmap_get(m
, "key 2");
288 assert_se(streq(r
, "val 2"));
289 assert_se(!hashmap_get(m
, "key 1"));
292 static void test_hashmap_remove2(void) {
293 _cleanup_hashmap_free_free_free_ Hashmap
*m
= NULL
;
294 char key1
[] = "key 1";
295 char key2
[] = "key 2";
296 char val1
[] = "val 1";
297 char val2
[] = "val 2";
300 log_info("%s", __func__
);
302 r
= hashmap_remove2(NULL
, "key 1", &r2
);
303 assert_se(r
== NULL
);
305 m
= hashmap_new(&string_hash_ops
);
308 r
= hashmap_remove2(m
, "no such key", &r2
);
309 assert_se(r
== NULL
);
311 hashmap_put(m
, strdup(key1
), strdup(val1
));
312 hashmap_put(m
, strdup(key2
), strdup(val2
));
314 r
= hashmap_remove2(m
, key1
, &r2
);
315 assert_se(streq(r
, val1
));
316 assert_se(streq(r2
, key1
));
320 r
= hashmap_get(m
, key2
);
321 assert_se(streq(r
, val2
));
322 assert_se(!hashmap_get(m
, key1
));
325 static void test_hashmap_remove_value(void) {
326 _cleanup_hashmap_free_ Hashmap
*m
= NULL
;
329 char val1
[] = "val 1";
330 char val2
[] = "val 2";
332 log_info("%s", __func__
);
334 r
= hashmap_remove_value(NULL
, "key 1", val1
);
335 assert_se(r
== NULL
);
337 m
= hashmap_new(&string_hash_ops
);
340 r
= hashmap_remove_value(m
, "key 1", val1
);
341 assert_se(r
== NULL
);
343 hashmap_put(m
, "key 1", val1
);
344 hashmap_put(m
, "key 2", val2
);
346 r
= hashmap_remove_value(m
, "key 1", val1
);
347 assert_se(streq(r
, "val 1"));
349 r
= hashmap_get(m
, "key 2");
350 assert_se(streq(r
, "val 2"));
351 assert_se(!hashmap_get(m
, "key 1"));
353 r
= hashmap_remove_value(m
, "key 2", val1
);
354 assert_se(r
== NULL
);
356 r
= hashmap_get(m
, "key 2");
357 assert_se(streq(r
, "val 2"));
358 assert_se(!hashmap_get(m
, "key 1"));
361 static void test_hashmap_remove_and_put(void) {
362 _cleanup_hashmap_free_ Hashmap
*m
= NULL
;
366 log_info("%s", __func__
);
368 m
= hashmap_new(&string_hash_ops
);
371 valid
= hashmap_remove_and_put(m
, "invalid key", "new key", NULL
);
372 assert_se(valid
== -ENOENT
);
374 valid
= hashmap_put(m
, "key 1", (void*) (const char *) "val 1");
375 assert_se(valid
== 1);
377 valid
= hashmap_remove_and_put(NULL
, "key 1", "key 2", (void*) (const char *) "val 2");
378 assert_se(valid
== -ENOENT
);
380 valid
= hashmap_remove_and_put(m
, "key 1", "key 2", (void*) (const char *) "val 2");
381 assert_se(valid
== 0);
383 r
= hashmap_get(m
, "key 2");
384 assert_se(streq(r
, "val 2"));
385 assert_se(!hashmap_get(m
, "key 1"));
387 valid
= hashmap_put(m
, "key 3", (void*) (const char *) "val 3");
388 assert_se(valid
== 1);
389 valid
= hashmap_remove_and_put(m
, "key 3", "key 2", (void*) (const char *) "val 2");
390 assert_se(valid
== -EEXIST
);
393 static void test_hashmap_remove_and_replace(void) {
394 _cleanup_hashmap_free_ Hashmap
*m
= NULL
;
396 void *key1
= UINT_TO_PTR(1);
397 void *key2
= UINT_TO_PTR(2);
398 void *key3
= UINT_TO_PTR(3);
402 log_info("%s", __func__
);
404 m
= hashmap_new(&trivial_hash_ops
);
407 valid
= hashmap_remove_and_replace(m
, key1
, key2
, NULL
);
408 assert_se(valid
== -ENOENT
);
410 valid
= hashmap_put(m
, key1
, key1
);
411 assert_se(valid
== 1);
413 valid
= hashmap_remove_and_replace(NULL
, key1
, key2
, key2
);
414 assert_se(valid
== -ENOENT
);
416 valid
= hashmap_remove_and_replace(m
, key1
, key2
, key2
);
417 assert_se(valid
== 0);
419 r
= hashmap_get(m
, key2
);
420 assert_se(r
== key2
);
421 assert_se(!hashmap_get(m
, key1
));
423 valid
= hashmap_put(m
, key3
, key3
);
424 assert_se(valid
== 1);
425 valid
= hashmap_remove_and_replace(m
, key3
, key2
, key2
);
426 assert_se(valid
== 0);
427 r
= hashmap_get(m
, key2
);
428 assert_se(r
== key2
);
429 assert_se(!hashmap_get(m
, key3
));
431 /* Repeat this test several times to increase the chance of hitting
432 * the less likely case in hashmap_remove_and_replace where it
433 * compensates for the backward shift. */
434 for (i
= 0; i
< 20; i
++) {
437 for (j
= 1; j
< 7; j
++)
438 hashmap_put(m
, UINT_TO_PTR(10*i
+ j
), UINT_TO_PTR(10*i
+ j
));
439 valid
= hashmap_remove_and_replace(m
, UINT_TO_PTR(10*i
+ 1),
440 UINT_TO_PTR(10*i
+ 2),
441 UINT_TO_PTR(10*i
+ 2));
442 assert_se(valid
== 0);
443 assert_se(!hashmap_get(m
, UINT_TO_PTR(10*i
+ 1)));
444 for (j
= 2; j
< 7; j
++) {
445 r
= hashmap_get(m
, UINT_TO_PTR(10*i
+ j
));
446 assert_se(r
== UINT_TO_PTR(10*i
+ j
));
451 static void test_hashmap_ensure_allocated(void) {
455 log_info("%s", __func__
);
457 m
= hashmap_new(&string_hash_ops
);
459 valid_hashmap
= hashmap_ensure_allocated(&m
, &string_hash_ops
);
460 assert_se(valid_hashmap
== 0);
466 static void test_hashmap_foreach_key(void) {
469 bool key_found
[] = { false, false, false, false };
472 static const char key_table
[] =
478 log_info("%s", __func__
);
480 m
= hashmap_new(&string_hash_ops
);
482 NULSTR_FOREACH(key
, key_table
)
483 hashmap_put(m
, key
, (void*) (const char*) "my dummy val");
485 HASHMAP_FOREACH_KEY(s
, key
, m
, i
) {
487 if (!key_found
[0] && streq(key
, "key 1"))
489 else if (!key_found
[1] && streq(key
, "key 2"))
491 else if (!key_found
[2] && streq(key
, "key 3"))
493 else if (!key_found
[3] && streq(key
, "fail"))
498 assert_se(key_found
[0] && key_found
[1] && key_found
[2] && !key_found
[3]);
503 static void test_hashmap_foreach(void) {
506 bool value_found
[] = { false, false, false, false };
507 char *val1
, *val2
, *val3
, *val4
, *s
;
510 log_info("%s", __func__
);
512 val1
= strdup("my val1");
514 val2
= strdup("my val2");
516 val3
= strdup("my val3");
518 val4
= strdup("my val4");
524 HASHMAP_FOREACH(s
, m
, i
)
526 assert_se(count
== 0);
528 m
= hashmap_new(&string_hash_ops
);
531 HASHMAP_FOREACH(s
, m
, i
)
533 assert_se(count
== 0);
535 hashmap_put(m
, "Key 1", val1
);
536 hashmap_put(m
, "Key 2", val2
);
537 hashmap_put(m
, "Key 3", val3
);
538 hashmap_put(m
, "Key 4", val4
);
540 HASHMAP_FOREACH(s
, m
, i
) {
541 if (!value_found
[0] && streq(s
, val1
))
542 value_found
[0] = true;
543 else if (!value_found
[1] && streq(s
, val2
))
544 value_found
[1] = true;
545 else if (!value_found
[2] && streq(s
, val3
))
546 value_found
[2] = true;
547 else if (!value_found
[3] && streq(s
, val4
))
548 value_found
[3] = true;
552 assert_se(value_found
[0] && value_found
[1] && value_found
[2] && value_found
[3]);
554 hashmap_free_free(m
);
557 static void test_hashmap_merge(void) {
560 char *val1
, *val2
, *val3
, *val4
, *r
;
562 log_info("%s", __func__
);
564 val1
= strdup("my val1");
566 val2
= strdup("my val2");
568 val3
= strdup("my val3");
570 val4
= strdup("my val4");
573 n
= hashmap_new(&string_hash_ops
);
574 m
= hashmap_new(&string_hash_ops
);
576 hashmap_put(m
, "Key 1", val1
);
577 hashmap_put(m
, "Key 2", val2
);
578 hashmap_put(n
, "Key 3", val3
);
579 hashmap_put(n
, "Key 4", val4
);
581 assert_se(hashmap_merge(m
, n
) == 0);
582 r
= hashmap_get(m
, "Key 3");
583 assert_se(r
&& streq(r
, "my val3"));
584 r
= hashmap_get(m
, "Key 4");
585 assert_se(r
&& streq(r
, "my val4"));
590 hashmap_free_free(m
);
593 static void test_hashmap_contains(void) {
597 log_info("%s", __func__
);
599 val1
= strdup("my val");
602 m
= hashmap_new(&string_hash_ops
);
604 assert_se(!hashmap_contains(m
, "Key 1"));
605 hashmap_put(m
, "Key 1", val1
);
606 assert_se(hashmap_contains(m
, "Key 1"));
607 assert_se(!hashmap_contains(m
, "Key 2"));
609 assert_se(!hashmap_contains(NULL
, "Key 1"));
612 hashmap_free_free(m
);
615 static void test_hashmap_isempty(void) {
619 log_info("%s", __func__
);
621 val1
= strdup("my val");
624 m
= hashmap_new(&string_hash_ops
);
626 assert_se(hashmap_isempty(m
));
627 hashmap_put(m
, "Key 1", val1
);
628 assert_se(!hashmap_isempty(m
));
631 hashmap_free_free(m
);
634 static void test_hashmap_size(void) {
636 char *val1
, *val2
, *val3
, *val4
;
638 log_info("%s", __func__
);
640 val1
= strdup("my val");
642 val2
= strdup("my val");
644 val3
= strdup("my val");
646 val4
= strdup("my val");
649 assert_se(hashmap_size(NULL
) == 0);
650 assert_se(hashmap_buckets(NULL
) == 0);
652 m
= hashmap_new(&string_hash_ops
);
654 hashmap_put(m
, "Key 1", val1
);
655 hashmap_put(m
, "Key 2", val2
);
656 hashmap_put(m
, "Key 3", val3
);
657 hashmap_put(m
, "Key 4", val4
);
660 assert_se(hashmap_size(m
) == 4);
661 assert_se(hashmap_buckets(m
) >= 4);
662 hashmap_free_free(m
);
665 static void test_hashmap_get(void) {
670 log_info("%s", __func__
);
672 val
= strdup("my val");
675 r
= hashmap_get(NULL
, "Key 1");
676 assert_se(r
== NULL
);
678 m
= hashmap_new(&string_hash_ops
);
680 hashmap_put(m
, "Key 1", val
);
682 r
= hashmap_get(m
, "Key 1");
683 assert_se(streq(r
, val
));
685 r
= hashmap_get(m
, "no such key");
686 assert_se(r
== NULL
);
689 hashmap_free_free(m
);
692 static void test_hashmap_get2(void) {
696 char key_orig
[] = "Key 1";
699 log_info("%s", __func__
);
701 val
= strdup("my val");
704 key_copy
= strdup(key_orig
);
707 r
= hashmap_get2(NULL
, key_orig
, &key_copy
);
708 assert_se(r
== NULL
);
710 m
= hashmap_new(&string_hash_ops
);
712 hashmap_put(m
, key_copy
, val
);
715 r
= hashmap_get2(m
, key_orig
, &key_copy
);
716 assert_se(streq(r
, val
));
717 assert_se(key_orig
!= key_copy
);
718 assert_se(streq(key_orig
, key_copy
));
720 r
= hashmap_get2(m
, "no such key", NULL
);
721 assert_se(r
== NULL
);
724 hashmap_free_free_free(m
);
727 static void crippled_hashmap_func(const void *p
, struct siphash
*state
) {
728 return trivial_hash_func(INT_TO_PTR(PTR_TO_INT(p
) & 0xff), state
);
731 static const struct hash_ops crippled_hashmap_ops
= {
732 .hash
= crippled_hashmap_func
,
733 .compare
= trivial_compare_func
,
736 static void test_hashmap_many(void) {
740 bool slow
= slow_tests_enabled();
742 const struct hash_ops
*ops
;
745 { .ops
= NULL
, .n_entries
= slow
? 1 << 20 : 240 },
746 { .ops
= &crippled_hashmap_ops
, .n_entries
= slow
? 1 << 14 : 140 },
749 log_info("%s (%s)", __func__
, slow
? "slow" : "fast");
751 for (j
= 0; j
< ELEMENTSOF(tests
); j
++) {
752 assert_se(h
= hashmap_new(tests
[j
].ops
));
754 for (i
= 1; i
< tests
[j
].n_entries
*3; i
+=3) {
755 assert_se(hashmap_put(h
, UINT_TO_PTR(i
), UINT_TO_PTR(i
)) >= 0);
756 assert_se(PTR_TO_UINT(hashmap_get(h
, UINT_TO_PTR(i
))) == i
);
759 for (i
= 1; i
< tests
[j
].n_entries
*3; i
++)
760 assert_se(hashmap_contains(h
, UINT_TO_PTR(i
)) == (i
% 3 == 1));
762 log_info("%u <= %u * 0.8 = %g", hashmap_size(h
), hashmap_buckets(h
), hashmap_buckets(h
) * 0.8);
764 assert_se(hashmap_size(h
) <= hashmap_buckets(h
) * 0.8);
765 assert_se(hashmap_size(h
) == tests
[j
].n_entries
);
767 while (!hashmap_isempty(h
)) {
768 k
= hashmap_first_key(h
);
769 v
= hashmap_remove(h
, k
);
777 static void test_hashmap_first(void) {
778 _cleanup_hashmap_free_ Hashmap
*m
= NULL
;
780 log_info("%s", __func__
);
782 m
= hashmap_new(&string_hash_ops
);
785 assert_se(!hashmap_first(m
));
786 assert_se(hashmap_put(m
, "key 1", (void*) "val 1") == 1);
787 assert_se(streq(hashmap_first(m
), "val 1"));
788 assert_se(hashmap_put(m
, "key 2", (void*) "val 2") == 1);
790 assert_se(streq(hashmap_first(m
), "val 1"));
791 assert_se(hashmap_remove(m
, "key 1"));
792 assert_se(streq(hashmap_first(m
), "val 2"));
796 static void test_hashmap_first_key(void) {
797 _cleanup_hashmap_free_ Hashmap
*m
= NULL
;
799 log_info("%s", __func__
);
801 m
= hashmap_new(&string_hash_ops
);
804 assert_se(!hashmap_first_key(m
));
805 assert_se(hashmap_put(m
, "key 1", NULL
) == 1);
806 assert_se(streq(hashmap_first_key(m
), "key 1"));
807 assert_se(hashmap_put(m
, "key 2", NULL
) == 1);
809 assert_se(streq(hashmap_first_key(m
), "key 1"));
810 assert_se(hashmap_remove(m
, "key 1") == NULL
);
811 assert_se(streq(hashmap_first_key(m
), "key 2"));
815 static void test_hashmap_steal_first_key(void) {
816 _cleanup_hashmap_free_ Hashmap
*m
= NULL
;
818 log_info("%s", __func__
);
820 m
= hashmap_new(&string_hash_ops
);
823 assert_se(!hashmap_steal_first_key(m
));
824 assert_se(hashmap_put(m
, "key 1", NULL
) == 1);
825 assert_se(streq(hashmap_steal_first_key(m
), "key 1"));
827 assert_se(hashmap_isempty(m
));
830 static void test_hashmap_steal_first(void) {
831 _cleanup_hashmap_free_ Hashmap
*m
= NULL
;
835 log_info("%s", __func__
);
837 m
= hashmap_new(&string_hash_ops
);
840 assert_se(hashmap_put(m
, "key 1", (void*) "1") == 1);
841 assert_se(hashmap_put(m
, "key 2", (void*) "22") == 1);
842 assert_se(hashmap_put(m
, "key 3", (void*) "333") == 1);
844 while ((val
= hashmap_steal_first(m
)))
845 seen
[strlen(val
) - 1]++;
847 assert_se(seen
[0] == 1 && seen
[1] == 1 && seen
[2] == 1);
849 assert_se(hashmap_isempty(m
));
852 static void test_hashmap_clear_free_free(void) {
853 _cleanup_hashmap_free_ Hashmap
*m
= NULL
;
855 log_info("%s", __func__
);
857 m
= hashmap_new(&string_hash_ops
);
860 assert_se(hashmap_put(m
, strdup("key 1"), NULL
) == 1);
861 assert_se(hashmap_put(m
, strdup("key 2"), NULL
) == 1);
862 assert_se(hashmap_put(m
, strdup("key 3"), NULL
) == 1);
864 hashmap_clear_free_free(m
);
865 assert_se(hashmap_isempty(m
));
868 static void test_hashmap_reserve(void) {
869 _cleanup_hashmap_free_ Hashmap
*m
= NULL
;
871 log_info("%s", __func__
);
873 m
= hashmap_new(&string_hash_ops
);
875 assert_se(hashmap_reserve(m
, 1) == 0);
876 assert_se(hashmap_buckets(m
) < 1000);
877 assert_se(hashmap_reserve(m
, 1000) == 0);
878 assert_se(hashmap_buckets(m
) >= 1000);
879 assert_se(hashmap_isempty(m
));
881 assert_se(hashmap_put(m
, "key 1", (void*) "val 1") == 1);
883 assert_se(hashmap_reserve(m
, UINT_MAX
) == -ENOMEM
);
884 assert_se(hashmap_reserve(m
, UINT_MAX
- 1) == -ENOMEM
);
887 void test_hashmap_funcs(void) {
888 log_parse_environment();
892 test_hashmap_get_strv();
893 test_hashmap_move_one();
895 test_hashmap_replace();
896 test_hashmap_update();
898 test_hashmap_remove();
899 test_hashmap_remove2();
900 test_hashmap_remove_value();
901 test_hashmap_remove_and_put();
902 test_hashmap_remove_and_replace();
903 test_hashmap_ensure_allocated();
904 test_hashmap_foreach();
905 test_hashmap_foreach_key();
906 test_hashmap_contains();
907 test_hashmap_merge();
908 test_hashmap_isempty();
913 test_hashmap_first();
914 test_hashmap_first_key();
915 test_hashmap_steal_first_key();
916 test_hashmap_steal_first();
917 test_hashmap_clear_free_free();
918 test_hashmap_reserve();