chiark / gitweb /
implement hashmap_copy() and hashmap_merge()
authorLennart Poettering <lennart@poettering.net>
Mon, 18 Jan 2010 22:49:49 +0000 (23:49 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 18 Jan 2010 22:49:49 +0000 (23:49 +0100)
hashmap.c
hashmap.h
set.c
set.h

index 1b2e059ddeb6b0c06b9dd6f7b8585fb084585d95..4db61732fae566011e06af51ae0b9de24ba37f74 100644 (file)
--- a/hashmap.c
+++ b/hashmap.c
@@ -18,7 +18,6 @@
 struct hashmap_entry {
         const void *key;
         void *value;
-
         struct hashmap_entry *bucket_next, *bucket_previous;
         struct hashmap_entry *iterate_next, *iterate_previous;
 };
@@ -323,3 +322,38 @@ bool hashmap_isempty(Hashmap *h) {
 
         return h->n_entries == 0;
 }
+
+int hashmap_merge(Hashmap *h, Hashmap *other) {
+        struct hashmap_entry *e;
+
+        assert(h);
+
+        if (!other)
+                return 0;
+
+        for (e = other->iterate_list_head; e; e = e->iterate_next) {
+                int r;
+
+                if ((r = hashmap_put(h, e->key, e->value)) < 0)
+                        if (r != -EEXIST)
+                                return r;
+        }
+
+        return 0;
+}
+
+Hashmap *hashmap_copy(Hashmap *h) {
+        Hashmap *copy;
+
+        assert(h);
+
+        if (!(copy = hashmap_new(h->hash_func, h->compare_func)))
+                return NULL;
+
+        if (hashmap_merge(copy, h) < 0) {
+                hashmap_free(copy);
+                return NULL;
+        }
+
+        return copy;
+}
index 4c946e35b9d53972df6f3bef996a1f0b39b34a99..e3b9d9aa309d6d47f6768011b6855bfe10830a08 100644 (file)
--- a/hashmap.h
+++ b/hashmap.h
@@ -22,12 +22,15 @@ unsigned trivial_hash_func(const void *p);
 int trivial_compare_func(const void *a, const void *b);
 
 Hashmap *hashmap_new(hash_func_t hash_func, compare_func_t compare_func);
-void hashmap_free(Hashmap*);
+void hashmap_free(Hashmap *h);
+Hashmap *hashmap_copy(Hashmap *h);
 
 int hashmap_put(Hashmap *h, const void *key, void *value);
 void* hashmap_get(Hashmap *h, const void *key);
 void* hashmap_remove(Hashmap *h, const void *key);
 
+int hashmap_merge(Hashmap *h, Hashmap *other);
+
 unsigned hashmap_size(Hashmap *h);
 bool hashmap_isempty(Hashmap *h);
 
diff --git a/set.c b/set.c
index 3aa227bbc7aded725c5d12d503c25ddd09e9ab93..21a1739b0338bc9b45370cc3592249c8c4664641 100644 (file)
--- a/set.c
+++ b/set.c
@@ -61,3 +61,11 @@ void* set_first(Set *s) {
 void* set_last(Set *s) {
         return hashmap_last(MAKE_HASHMAP(s));
 }
+
+int set_merge(Set *s, Set *other) {
+        return hashmap_merge(MAKE_HASHMAP(s), MAKE_HASHMAP(other));
+}
+
+Set* set_copy(Set *s) {
+        return MAKE_SET(hashmap_copy(MAKE_HASHMAP(s)));
+}
diff --git a/set.h b/set.h
index 9aefdbcb56e6803a0cc10bdd548975462319949c..a2e405941c618cc2b08df95cdbf63a08458f0dec 100644 (file)
--- a/set.h
+++ b/set.h
 typedef struct Set Set;
 
 Set *set_new(hash_func_t hash_func, compare_func_t compare_func);
-void set_free(Set* set);
+Set* set_copy(Set *s);
+void set_free(Set* s);
 
 int set_put(Set *s, void *value);
 void *set_get(Set *s, void *value);
 void *set_remove(Set *s, void *value);
 
+int set_merge(Set *s, Set *other);
+
 unsigned set_size(Set *s);
 bool set_isempty(Set *s);
 
-void *set_iterate(Set *h, void **state);
-void *set_iterate_backwards(Set *h, void **state);
+void *set_iterate(Set *s, void **state);
+void *set_iterate_backwards(Set *s, void **state);
 
-void *set_steal_first(Set *h);
-void* set_first(Set *h);
-void* set_last(Set *h);
+void *set_steal_first(Set *s);
+void* set_first(Set *s);
+void* set_last(Set *s);
 
 #define SET_FOREACH(e, s, state) \
         for ((state) = NULL, (e) = set_iterate((s), &(state)); (e); (e) = set_iterate((s), &(state)))