chiark / gitweb /
sysctl: support multiple prefixes in a single invocation
[elogind.git] / src / hashmap.c
index 5a993b6e4761a36ba410c1f9b1cbba7a5de95a58..53502576ad8b9773d08a528853ce7c27948c865c 100644 (file)
@@ -1,4 +1,4 @@
-/*-*- Mode: C; c-basic-offset: 8 -*-*/
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 
 /***
   This file is part of systemd.
@@ -173,6 +173,15 @@ void hashmap_free(Hashmap*h) {
         free(h);
 }
 
+void hashmap_free_free(Hashmap *h) {
+        void *p;
+
+        while ((p = hashmap_steal_first(h)))
+                free(p);
+
+        hashmap_free(h);
+}
+
 void hashmap_clear(Hashmap *h) {
         if (!h)
                 return;
@@ -296,6 +305,33 @@ int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key,
         return 0;
 }
 
+int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_key, void *value) {
+        struct hashmap_entry *e, *k;
+        unsigned old_hash, new_hash;
+
+        if (!h)
+                return -ENOENT;
+
+        old_hash = h->hash_func(old_key) % NBUCKETS;
+        if (!(e = hash_scan(h, old_hash, old_key)))
+                return -ENOENT;
+
+        new_hash = h->hash_func(new_key) % NBUCKETS;
+
+        if ((k = hash_scan(h, new_hash, new_key)))
+                if (e != k)
+                        remove_entry(h, k);
+
+        unlink_entry(h, e, old_hash);
+
+        e->key = new_key;
+        e->value = value;
+
+        link_entry(h, e, new_hash);
+
+        return 0;
+}
+
 void* hashmap_remove_value(Hashmap *h, const void *key, void *value) {
         struct hashmap_entry *e;
         unsigned hash;
@@ -440,6 +476,21 @@ void* hashmap_steal_first(Hashmap *h) {
         return data;
 }
 
+void* hashmap_steal_first_key(Hashmap *h) {
+        void *key;
+
+        if (!h)
+                return NULL;
+
+        if (!h->iterate_list_head)
+                return NULL;
+
+        key = (void*) h->iterate_list_head->key;
+        remove_entry(h, h->iterate_list_head);
+
+        return key;
+}
+
 unsigned hashmap_size(Hashmap *h) {
 
         if (!h)
@@ -541,3 +592,21 @@ Hashmap *hashmap_copy(Hashmap *h) {
 
         return copy;
 }
+
+char **hashmap_get_strv(Hashmap *h) {
+        char **sv;
+        Iterator it;
+        char *path;
+        int n;
+
+        sv = malloc((h->n_entries+1) * sizeof(char *));
+        if (sv == NULL)
+                return NULL;
+
+        n = 0;
+        HASHMAP_FOREACH(path, h, it)
+                sv[n++] = path;
+        sv[n] = NULL;
+
+        return sv;
+}