32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt This file is part of systemd
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Copyright 2013 Daniel Buch
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt systemd is free software; you can redistribute it and/or modify it
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt under the terms of the GNU Lesser General Public License as published by
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt the Free Software Foundation; either version 2.1 of the License, or
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt (at your option) any later version.
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt systemd is distributed in the hope that it will be useful, but
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt WITHOUT ANY WARRANTY; without even the implied warranty of
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt Lesser General Public License for more details.
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt You should have received a copy of the GNU Lesser General Public License
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt along with systemd; If not, see <http://www.gnu.org/licenses/>.
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert_se(hashmap_move_one(n, NULL, "key 3") == -ENOENT);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert_se(hashmap_move_one(n, m, "key 5") == -ENOENT);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert_se(hashmap_move_one(n, m, "key 3") == 0);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert_se(hashmap_move_one(n, m, "key 4") == 0);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert_se(hashmap_move_one(n, m, "key 3") == -EEXIST);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert_se(hashmap_update(m, "key 2", val2) == -ENOENT);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert_se(hashmap_update(m, "key 1", val2) == 0);
61c81750217af7492be86adde81b28e310cd5e82Tom Gundersen assert_se(hashmap_ensure_allocated(&m, &string_hash_ops) >= 0);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt valid_hashmap_put = hashmap_put(m, "key 1", val1);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert_se(hashmap_put(m, "key 1", val1) == 0);
435fc3176520a58f1c20ccb983c9fb40b30a1471Martin Pitt assert_se(hashmap_put(m, "key 1", val2) == -EEXIST);
435fc3176520a58f1c20ccb983c9fb40b30a1471Martin Pitt assert_se(hashmap_put(m, key1, val2) == -EEXIST);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt _cleanup_hashmap_free_free_free_ Hashmap *m = NULL;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = hashmap_remove_value(NULL, "key 1", (void*) "val 1");
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = hashmap_remove_value(m, "key 1", (void*) "val 1");
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = hashmap_remove_value(m, "key 1", (void*) "val 1");
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt r = hashmap_remove_value(m, "key 2", (void*) "val 1");
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtstatic void test_hashmap_remove_and_put(void) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt valid = hashmap_remove_and_put(m, "invalid key", "new key", NULL);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt valid = hashmap_put(m, "key 1", (void*) (const char *) "val 1");
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt valid = hashmap_remove_and_put(NULL, "key 1", "key 2", (void*) (const char *) "val 2");
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt valid = hashmap_remove_and_put(m, "key 1", "key 2", (void*) (const char *) "val 2");
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt valid = hashmap_put(m, "key 3", (void*) (const char *) "val 3");
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt valid = hashmap_remove_and_put(m, "key 3", "key 2", (void*) (const char *) "val 2");
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidtstatic void test_hashmap_remove_and_replace(void) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt valid = hashmap_remove_and_replace(m, key1, key2, NULL);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt valid = hashmap_remove_and_replace(NULL, key1, key2, key2);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt valid = hashmap_remove_and_replace(m, key1, key2, key2);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt valid = hashmap_remove_and_replace(m, key3, key2, key2);
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt /* Repeat this test several times to increase the chance of hitting
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt * the less likely case in hashmap_remove_and_replace where it
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt * compensates for the backward shift. */
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt for (i = 0; i < 20; i++) {
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt hashmap_put(m, UINT_TO_PTR(10*i + j), UINT_TO_PTR(10*i + j));
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt valid = hashmap_remove_and_replace(m, UINT_TO_PTR(10*i + 1),
e1323fbfbe8a574f28b704f2df8ce7f99e3a28f5Michal Schmidt assert_se(!hashmap_get(m, UINT_TO_PTR(10*i + 1)));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtstatic void test_hashmap_ensure_allocated(void) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt valid_hashmap = hashmap_ensure_allocated(&m, &string_hash_ops);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt bool key_found[] = { false, false, false, false };
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt const char *s;
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt hashmap_put(m, key, (void*) (const char*) "my dummy val");
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt else if (!key_found[1] && streq(key, "key 2"))
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt else if (!key_found[2] && streq(key, "key 3"))
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt else if (!key_found[3] && streq(key, "fail"))
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert_se(key_found[0] && key_found[1] && key_found[2] && !key_found[3]);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt bool value_found[] = { false, false, false, false };
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert_se(value_found[0] && value_found[1] && value_found[2] && value_found[3]);
b669934fae49c9158c35e612e54e1765edca8584Thomas Hindoe Paaboel Andersen assert_se(streq(key_orig, key_copy));
b826ab586c9e0a9c0d438a75c28cf3a8ab485929Tom Gundersenstatic void crippled_hashmap_func(const void *p, struct siphash *state) {
b826ab586c9e0a9c0d438a75c28cf3a8ab485929Tom Gundersen return trivial_hash_func(INT_TO_PTR(PTR_TO_INT(p) & 0xff), state);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidtstatic const struct hash_ops crippled_hashmap_ops = {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt unsigned i, j;
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt static const struct {
11de3decc9357714498f96e13f1c1c2da1046811Michal Schmidt { .ops = &crippled_hashmap_ops, .n_entries = 1 << 14 },
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt for (i = 1; i < tests[j].n_entries*3; i+=3) {
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert_se(hashmap_put(h, UINT_TO_PTR(i), UINT_TO_PTR(i)) >= 0);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert_se(PTR_TO_UINT(hashmap_get(h, UINT_TO_PTR(i))) == i);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert_se(hashmap_contains(h, UINT_TO_PTR(i)) == (i % 3 == 1));
ce79279bff6e7a1a17070509a039ab635796f129Michal Schmidt log_info("%u <= %u * 0.8 = %g", hashmap_size(h), hashmap_buckets(h), hashmap_buckets(h) * 0.8);
ce79279bff6e7a1a17070509a039ab635796f129Michal Schmidt assert_se(hashmap_size(h) <= hashmap_buckets(h) * 0.8);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert_se(hashmap_size(h) == tests[j].n_entries);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert_se(hashmap_put(m, "key 1", (void*) "val 1") == 1);
9ba81d5a61b7c992a1d2e5e02f334b8e2a0b0c22Michal Schmidt assert_se(hashmap_put(m, "key 2", (void*) "val 2") == 1);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert_se(hashmap_put(m, "key 1", NULL) == 1);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert_se(streq(hashmap_first_key(m), "key 1"));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert_se(hashmap_put(m, "key 2", NULL) == 1);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert_se(streq(hashmap_first_key(m), "key 1"));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert_se(hashmap_remove(m, "key 1") == NULL);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert_se(streq(hashmap_first_key(m), "key 2"));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtstatic void test_hashmap_steal_first_key(void) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert_se(hashmap_put(m, "key 1", NULL) == 1);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert_se(streq(hashmap_steal_first_key(m), "key 1"));
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert_se(hashmap_put(m, "key 1", (void*) "1") == 1);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert_se(hashmap_put(m, "key 2", (void*) "22") == 1);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert_se(hashmap_put(m, "key 3", (void*) "333") == 1);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert_se(seen[0] == 1 && seen[1] == 1 && seen[2] == 1);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidtstatic void test_hashmap_clear_free_free(void) {
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert_se(hashmap_put(m, strdup("key 1"), NULL) == 1);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert_se(hashmap_put(m, strdup("key 2"), NULL) == 1);
32a4456cc252689f51f383d150d34ed636bfec4dMichal Schmidt assert_se(hashmap_put(m, strdup("key 3"), NULL) == 1);
8f88aed740ded77af443bb1b7c79bb229b50f8f8Michal Schmidt assert_se(hashmap_put(m, "key 1", (void*) "val 1") == 1);
8f88aed740ded77af443bb1b7c79bb229b50f8f8Michal Schmidt assert_se(hashmap_reserve(m, UINT_MAX) == -ENOMEM);