2 This file is part of systemd
4 Copyright 2013 Daniel Buch
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
24 void test_hashmap_funcs(void);
26 static void test_hashmap_replace(void) {
28 char *val1, *val2, *val3, *val4, *val5, *r;
30 m = hashmap_new(&string_hash_ops);
32 val1 = strdup("val1");
34 val2 = strdup("val2");
36 val3 = strdup("val3");
38 val4 = strdup("val4");
40 val5 = strdup("val5");
43 hashmap_put(m, "key 1", val1);
44 hashmap_put(m, "key 2", val2);
45 hashmap_put(m, "key 3", val3);
46 hashmap_put(m, "key 4", val4);
48 hashmap_replace(m, "key 3", val1);
49 r = hashmap_get(m, "key 3");
50 assert_se(streq(r, "val1"));
52 hashmap_replace(m, "key 5", val5);
53 r = hashmap_get(m, "key 5");
54 assert_se(streq(r, "val5"));
64 static void test_hashmap_copy(void) {
66 char *val1, *val2, *val3, *val4, *r;
68 val1 = strdup("val1");
70 val2 = strdup("val2");
72 val3 = strdup("val3");
74 val4 = strdup("val4");
77 m = hashmap_new(&string_hash_ops);
79 hashmap_put(m, "key 1", val1);
80 hashmap_put(m, "key 2", val2);
81 hashmap_put(m, "key 3", val3);
82 hashmap_put(m, "key 4", val4);
84 copy = hashmap_copy(m);
86 r = hashmap_get(copy, "key 1");
87 assert_se(streq(r, "val1"));
88 r = hashmap_get(copy, "key 2");
89 assert_se(streq(r, "val2"));
90 r = hashmap_get(copy, "key 3");
91 assert_se(streq(r, "val3"));
92 r = hashmap_get(copy, "key 4");
93 assert_se(streq(r, "val4"));
95 hashmap_free_free(copy);
99 static void test_hashmap_get_strv(void) {
102 char *val1, *val2, *val3, *val4;
104 val1 = strdup("val1");
106 val2 = strdup("val2");
108 val3 = strdup("val3");
110 val4 = strdup("val4");
113 m = hashmap_new(&string_hash_ops);
115 hashmap_put(m, "key 1", val1);
116 hashmap_put(m, "key 2", val2);
117 hashmap_put(m, "key 3", val3);
118 hashmap_put(m, "key 4", val4);
120 strv = hashmap_get_strv(m);
123 strv = strv_sort(strv);
126 assert_se(streq(strv[0], "val1"));
127 assert_se(streq(strv[1], "val2"));
128 assert_se(streq(strv[2], "val3"));
129 assert_se(streq(strv[3], "val4"));
136 static void test_hashmap_move_one(void) {
138 char *val1, *val2, *val3, *val4, *r;
140 val1 = strdup("val1");
142 val2 = strdup("val2");
144 val3 = strdup("val3");
146 val4 = strdup("val4");
149 m = hashmap_new(&string_hash_ops);
150 n = hashmap_new(&string_hash_ops);
152 hashmap_put(m, "key 1", val1);
153 hashmap_put(m, "key 2", val2);
154 hashmap_put(m, "key 3", val3);
155 hashmap_put(m, "key 4", val4);
157 hashmap_move_one(n, m, "key 3");
158 hashmap_move_one(n, m, "key 4");
160 r = hashmap_get(n, "key 3");
161 assert_se(r && streq(r, "val3"));
162 r = hashmap_get(n, "key 4");
163 assert_se(r && streq(r, "val4"));
164 r = hashmap_get(m, "key 3");
168 hashmap_free_free(m);
169 hashmap_free_free(n);
172 static void test_hashmap_update(void) {
174 char *val1, *val2, *r;
176 m = hashmap_new(&string_hash_ops);
177 val1 = strdup("old_value");
179 val2 = strdup("new_value");
182 hashmap_put(m, "key 1", val1);
183 r = hashmap_get(m, "key 1");
184 assert_se(streq(r, "old_value"));
186 hashmap_update(m, "key 1", val2);
187 r = hashmap_get(m, "key 1");
188 assert_se(streq(r, "new_value"));
195 static void test_hashmap_put(void) {
197 int valid_hashmap_put;
199 m = hashmap_new(&string_hash_ops);
201 valid_hashmap_put = hashmap_put(m, "key 1", (void*) (const char *) "val 1");
202 assert_se(valid_hashmap_put == 1);
208 static void test_hashmap_remove_and_put(void) {
209 _cleanup_hashmap_free_ Hashmap *m = NULL;
213 m = hashmap_new(&string_hash_ops);
216 valid = hashmap_remove_and_put(m, "unvalid key", "new key", NULL);
217 assert_se(valid < 0);
219 valid = hashmap_put(m, "key 1", (void*) (const char *) "val 1");
220 assert_se(valid == 1);
221 valid = hashmap_remove_and_put(m, "key 1", "key 2", (void*) (const char *) "val 2");
222 assert_se(valid == 0);
224 r = hashmap_get(m, "key 2");
225 assert_se(streq(r, "val 2"));
226 assert_se(!hashmap_get(m, "key 1"));
228 valid = hashmap_put(m, "key 3", (void*) (const char *) "val 3");
229 assert_se(valid == 1);
230 valid = hashmap_remove_and_put(m, "key 3", "key 2", (void*) (const char *) "val 2");
231 assert_se(valid < 0);
234 static void test_hashmap_ensure_allocated(void) {
238 m = hashmap_new(&string_hash_ops);
240 valid_hashmap = hashmap_ensure_allocated(&m, &string_hash_ops);
241 assert_se(valid_hashmap == 0);
247 static void test_hashmap_foreach_key(void) {
250 bool key_found[] = { false, false, false, false };
253 static const char key_table[] =
259 m = hashmap_new(&string_hash_ops);
261 NULSTR_FOREACH(key, key_table)
262 hashmap_put(m, key, (void*) (const char*) "my dummy val");
264 HASHMAP_FOREACH_KEY(s, key, m, i) {
265 if (!key_found[0] && streq(key, "key 1"))
267 else if (!key_found[1] && streq(key, "key 2"))
269 else if (!key_found[2] && streq(key, "key 3"))
271 else if (!key_found[3] && streq(key, "fail"))
276 assert_se(key_found[0] && key_found[1] && key_found[2] && !key_found[3]);
281 static void test_hashmap_foreach(void) {
284 bool value_found[] = { false, false, false, false };
285 char *val1, *val2, *val3, *val4, *s;
287 val1 = strdup("my val1");
289 val2 = strdup("my val2");
291 val3 = strdup("my val3");
293 val4 = strdup("my val4");
296 m = hashmap_new(&string_hash_ops);
298 hashmap_put(m, "Key 1", val1);
299 hashmap_put(m, "Key 2", val2);
300 hashmap_put(m, "Key 3", val3);
301 hashmap_put(m, "Key 4", val4);
303 HASHMAP_FOREACH(s, m, i) {
304 if (!value_found[0] && streq(s, val1))
305 value_found[0] = true;
306 else if (!value_found[1] && streq(s, val2))
307 value_found[1] = true;
308 else if (!value_found[2] && streq(s, val3))
309 value_found[2] = true;
310 else if (!value_found[3] && streq(s, val4))
311 value_found[3] = true;
315 assert_se(value_found[0] && value_found[1] && value_found[2] && value_found[3]);
317 hashmap_free_free(m);
320 static void test_hashmap_merge(void) {
323 char *val1, *val2, *val3, *val4, *r;
325 val1 = strdup("my val1");
327 val2 = strdup("my val2");
329 val3 = strdup("my val3");
331 val4 = strdup("my val4");
334 n = hashmap_new(&string_hash_ops);
335 m = hashmap_new(&string_hash_ops);
337 hashmap_put(m, "Key 1", val1);
338 hashmap_put(m, "Key 2", val2);
339 hashmap_put(n, "Key 3", val3);
340 hashmap_put(n, "Key 4", val4);
342 assert_se(hashmap_merge(m, n) == 0);
343 r = hashmap_get(m, "Key 3");
344 assert_se(r && streq(r, "my val3"));
345 r = hashmap_get(m, "Key 4");
346 assert_se(r && streq(r, "my val4"));
351 hashmap_free_free(m);
354 static void test_hashmap_contains(void) {
358 val1 = strdup("my val");
361 m = hashmap_new(&string_hash_ops);
363 assert_se(!hashmap_contains(m, "Key 1"));
364 hashmap_put(m, "Key 1", val1);
365 assert_se(hashmap_contains(m, "Key 1"));
368 hashmap_free_free(m);
371 static void test_hashmap_isempty(void) {
375 val1 = strdup("my val");
378 m = hashmap_new(&string_hash_ops);
380 assert_se(hashmap_isempty(m));
381 hashmap_put(m, "Key 1", val1);
382 assert_se(!hashmap_isempty(m));
385 hashmap_free_free(m);
388 static void test_hashmap_size(void) {
390 char *val1, *val2, *val3, *val4;
392 val1 = strdup("my val");
394 val2 = strdup("my val");
396 val3 = strdup("my val");
398 val4 = strdup("my val");
401 m = hashmap_new(&string_hash_ops);
403 hashmap_put(m, "Key 1", val1);
404 hashmap_put(m, "Key 2", val2);
405 hashmap_put(m, "Key 3", val3);
406 hashmap_put(m, "Key 4", val4);
409 assert_se(hashmap_size(m) == 4);
410 hashmap_free_free(m);
413 static void test_hashmap_get(void) {
418 val = strdup("my val");
421 m = hashmap_new(&string_hash_ops);
423 hashmap_put(m, "Key 1", val);
425 r = hashmap_get(m, "Key 1");
426 assert_se(streq(r, val));
429 hashmap_free_free(m);
432 static void test_hashmap_many(void) {
436 #define N_ENTRIES 100000
438 assert_se(h = hashmap_new(NULL));
440 for (i = 1; i < N_ENTRIES*3; i+=3) {
441 assert_se(hashmap_put(h, UINT_TO_PTR(i), UINT_TO_PTR(i)) >= 0);
442 assert_se(PTR_TO_UINT(hashmap_get(h, UINT_TO_PTR(i))) == i);
445 for (i = 1; i < N_ENTRIES*3; i++)
446 assert_se(hashmap_contains(h, UINT_TO_PTR(i)) == (i % 3 == 1));
448 log_info("%u <= %u * 0.75 = %g", hashmap_size(h), hashmap_buckets(h), hashmap_buckets(h) * 0.75);
450 assert_se(hashmap_size(h) <= hashmap_buckets(h) * 0.75);
451 assert_se(hashmap_size(h) == N_ENTRIES);
456 static void test_hashmap_first_key(void) {
457 _cleanup_hashmap_free_ Hashmap *m = NULL;
459 m = hashmap_new(&string_hash_ops);
462 assert_se(!hashmap_first_key(m));
463 assert_se(hashmap_put(m, "key 1", NULL) == 1);
464 assert_se(streq(hashmap_first_key(m), "key 1"));
465 assert_se(hashmap_put(m, "key 2", NULL) == 1);
467 assert_se(streq(hashmap_first_key(m), "key 1"));
468 assert_se(hashmap_remove(m, "key 1") == NULL);
469 assert_se(streq(hashmap_first_key(m), "key 2"));
473 static void test_hashmap_steal_first_key(void) {
474 _cleanup_hashmap_free_ Hashmap *m = NULL;
476 m = hashmap_new(&string_hash_ops);
479 assert_se(!hashmap_steal_first_key(m));
480 assert_se(hashmap_put(m, "key 1", NULL) == 1);
481 assert_se(streq(hashmap_steal_first_key(m), "key 1"));
483 assert_se(hashmap_isempty(m));
486 static void test_hashmap_steal_first(void) {
487 _cleanup_hashmap_free_ Hashmap *m = NULL;
491 m = hashmap_new(&string_hash_ops);
494 assert_se(hashmap_put(m, "key 1", (void*) "1") == 1);
495 assert_se(hashmap_put(m, "key 2", (void*) "22") == 1);
496 assert_se(hashmap_put(m, "key 3", (void*) "333") == 1);
498 while ((val = hashmap_steal_first(m)))
499 seen[strlen(val) - 1]++;
501 assert_se(seen[0] == 1 && seen[1] == 1 && seen[2] == 1);
503 assert_se(hashmap_isempty(m));
506 static void test_hashmap_clear_free_free(void) {
507 _cleanup_hashmap_free_ Hashmap *m = NULL;
509 m = hashmap_new(&string_hash_ops);
512 assert_se(hashmap_put(m, strdup("key 1"), NULL) == 1);
513 assert_se(hashmap_put(m, strdup("key 2"), NULL) == 1);
514 assert_se(hashmap_put(m, strdup("key 3"), NULL) == 1);
516 hashmap_clear_free_free(m);
517 assert_se(hashmap_isempty(m));
520 void test_hashmap_funcs(void) {
522 test_hashmap_get_strv();
523 test_hashmap_move_one();
524 test_hashmap_replace();
525 test_hashmap_update();
527 test_hashmap_remove_and_put();
528 test_hashmap_ensure_allocated();
529 test_hashmap_foreach();
530 test_hashmap_foreach_key();
531 test_hashmap_contains();
532 test_hashmap_merge();
533 test_hashmap_isempty();
537 test_hashmap_first_key();
538 test_hashmap_steal_first_key();
539 test_hashmap_steal_first();
540 test_hashmap_clear_free_free();