]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
introduce hashmap_ensure_replace()
authorMatteo Croce <teknoraver@meta.com>
Fri, 28 Jun 2024 14:16:50 +0000 (16:16 +0200)
committerMatteo Croce <teknoraver@meta.com>
Fri, 28 Jun 2024 16:55:31 +0000 (18:55 +0200)
Similar to hashmap_ensure_put(), but replace existing items in the map,
as hashmap_replace().

src/basic/hashmap.c
src/basic/hashmap.h
src/test/test-hashmap-plain.c

index a9fd7620295f0034321f914e4314f8a1b8e0849d..951f63ae6da9f3fb1f31a62a53101bffd4fc8310 100644 (file)
@@ -874,6 +874,26 @@ int _ordered_hashmap_ensure_put(OrderedHashmap **h, const struct hash_ops *hash_
         return ordered_hashmap_put(*h, key, value);
 }
 
+int _ordered_hashmap_ensure_replace(OrderedHashmap **h, const struct hash_ops *hash_ops, const void *key, void *value  HASHMAP_DEBUG_PARAMS) {
+        int r;
+
+        r = _ordered_hashmap_ensure_allocated(h, hash_ops  HASHMAP_DEBUG_PASS_ARGS);
+        if (r < 0)
+                return r;
+
+        return ordered_hashmap_replace(*h, key, value);
+}
+
+int _hashmap_ensure_replace(Hashmap **h, const struct hash_ops *hash_ops, const void *key, void *value  HASHMAP_DEBUG_PARAMS) {
+        int r;
+
+        r = _hashmap_ensure_allocated(h, hash_ops  HASHMAP_DEBUG_PASS_ARGS);
+        if (r < 0)
+                return r;
+
+        return hashmap_replace(*h, key, value);
+}
+
 static void hashmap_free_no_clear(HashmapBase *h) {
         assert(!h->has_indirect);
         assert(h->n_direct_entries == 0);
index 49d9d118cc373bb0bcf844090a74d5dcda10493e..01a4fb32043368738b903280c1c7ce014a4c037d 100644 (file)
@@ -130,14 +130,19 @@ HashmapBase* _hashmap_copy(HashmapBase *h  HASHMAP_DEBUG_PARAMS);
 int _hashmap_ensure_allocated(Hashmap **h, const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS);
 int _hashmap_ensure_put(Hashmap **h, const struct hash_ops *hash_ops, const void *key, void *value  HASHMAP_DEBUG_PARAMS);
 int _ordered_hashmap_ensure_allocated(OrderedHashmap **h, const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS);
+int _hashmap_ensure_replace(Hashmap **h, const struct hash_ops *hash_ops, const void *key, void *value  HASHMAP_DEBUG_PARAMS);
 
 #define hashmap_ensure_allocated(h, ops) _hashmap_ensure_allocated(h, ops  HASHMAP_DEBUG_SRC_ARGS)
 #define hashmap_ensure_put(s, ops, key, value) _hashmap_ensure_put(s, ops, key, value  HASHMAP_DEBUG_SRC_ARGS)
 #define ordered_hashmap_ensure_allocated(h, ops) _ordered_hashmap_ensure_allocated(h, ops  HASHMAP_DEBUG_SRC_ARGS)
+#define hashmap_ensure_replace(s, ops, key, value) _hashmap_ensure_replace(s, ops, key, value  HASHMAP_DEBUG_SRC_ARGS)
 
 int _ordered_hashmap_ensure_put(OrderedHashmap **h, const struct hash_ops *hash_ops, const void *key, void *value  HASHMAP_DEBUG_PARAMS);
 #define ordered_hashmap_ensure_put(s, ops, key, value) _ordered_hashmap_ensure_put(s, ops, key, value  HASHMAP_DEBUG_SRC_ARGS)
 
+int _ordered_hashmap_ensure_replace(OrderedHashmap **h, const struct hash_ops *hash_ops, const void *key, void *value  HASHMAP_DEBUG_PARAMS);
+#define ordered_hashmap_ensure_replace(s, ops, key, value) _ordered_hashmap_ensure_replace(s, ops, key, value  HASHMAP_DEBUG_SRC_ARGS)
+
 IteratedCache* _hashmap_iterated_cache_new(HashmapBase *h);
 static inline IteratedCache* hashmap_iterated_cache_new(Hashmap *h) {
         return (IteratedCache*) _hashmap_iterated_cache_new(HASHMAP_BASE(h));
index f2d2d4f75da019000f7e568d7dff6425f2e742df..cb45c150879a668e80af65af485f12127a97c9cb 100644 (file)
@@ -49,6 +49,30 @@ TEST(hashmap_replace) {
         ASSERT_STREQ(r, "val5");
 }
 
+TEST(hashmap_ensure_replace) {
+        _cleanup_hashmap_free_ Hashmap *m = NULL;
+        _cleanup_free_ char *val1 = NULL, *val2 = NULL;
+
+        val1 = strdup("val1");
+        ASSERT_NOT_NULL(val1);
+        val2 = strdup("val2");
+        ASSERT_NOT_NULL(val2);
+
+        ASSERT_OK(hashmap_ensure_replace(&m, &string_hash_ops, val1, val2));
+
+        ASSERT_OK(hashmap_ensure_replace(&m, &string_hash_ops, "key 1", val1));
+        ASSERT_STREQ(hashmap_get(m, "key 1"), "val1");
+
+        ASSERT_OK(hashmap_ensure_replace(&m, &string_hash_ops, "key 2", val2));
+        ASSERT_STREQ(hashmap_get(m, "key 2"), "val2");
+
+        ASSERT_OK(hashmap_ensure_replace(&m, &string_hash_ops, "key 3", val1));
+        ASSERT_STREQ(hashmap_get(m, "key 3"), "val1");
+
+        ASSERT_OK(hashmap_ensure_replace(&m, &string_hash_ops, "key 3", val2));
+        ASSERT_STREQ(hashmap_get(m, "key 3"), "val2");
+}
+
 TEST(hashmap_copy) {
         _cleanup_hashmap_free_ Hashmap *m = NULL;
         _cleanup_hashmap_free_free_ Hashmap *copy = NULL;