summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2010-01-18 23:49:49 +0100
committerLennart Poettering <lennart@poettering.net>2010-01-18 23:49:49 +0100
commit91cdde8a7a08c6797995cc67f4b55ac43780cdd8 (patch)
treee6bcc2d96a186a47b3076e0a95f495933dc5d9bd
parent3efd4195676c3880771b9f5e3b3bd9ff35c5ad4b (diff)
implement hashmap_copy() and hashmap_merge()
-rw-r--r--hashmap.c36
-rw-r--r--hashmap.h5
-rw-r--r--set.c8
-rw-r--r--set.h15
4 files changed, 56 insertions, 8 deletions
diff --git a/hashmap.c b/hashmap.c
index 1b2e059dd..4db61732f 100644
--- 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;
+}
diff --git a/hashmap.h b/hashmap.h
index 4c946e35b..e3b9d9aa3 100644
--- 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 3aa227bbc..21a1739b0 100644
--- 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 9aefdbcb5..a2e405941 100644
--- a/set.h
+++ b/set.h
@@ -14,21 +14,24 @@
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)))