chiark / gitweb /
journal: properly serialize fields with multiple values into JSON
[elogind.git] / src / shared / hashmap.c
index 5d1e63208a64648c8b8e11b8bd380874d607dfb0..ef78070f4c0854cd767e7a2803317fccb51b7691 100644 (file)
@@ -265,6 +265,8 @@ static void remove_entry(Hashmap *h, struct hashmap_entry *e) {
 
 void hashmap_free(Hashmap*h) {
 
+        /* Free the hashmap, but nothing in it */
+
         if (!h)
                 return;
 
@@ -277,11 +279,14 @@ void hashmap_free(Hashmap*h) {
 }
 
 void hashmap_free_free(Hashmap *h) {
-        void *p;
 
-        while ((p = hashmap_steal_first(h)))
-                free(p);
+        /* Free the hashmap and all data objects in it, but not the
+         * keys */
 
+        if (!h)
+                return;
+
+        hashmap_clear_free(h);
         hashmap_free(h);
 }
 
@@ -293,6 +298,16 @@ void hashmap_clear(Hashmap *h) {
                 remove_entry(h, h->iterate_list_head);
 }
 
+void hashmap_clear_free(Hashmap *h) {
+        void *p;
+
+        if (!h)
+                return;
+
+        while ((p = hashmap_steal_first(h)))
+                free(p);
+}
+
 static struct hashmap_entry *hash_scan(Hashmap *h, unsigned hash, const void *key) {
         struct hashmap_entry *e;
         assert(h);
@@ -313,7 +328,8 @@ int hashmap_put(Hashmap *h, const void *key, void *value) {
 
         hash = h->hash_func(key) % NBUCKETS;
 
-        if ((e = hash_scan(h, hash, key))) {
+        e = hash_scan(h, hash, key);
+        if (e) {
 
                 if (e->value == value)
                         return 0;
@@ -344,8 +360,8 @@ int hashmap_replace(Hashmap *h, const void *key, void *value) {
         assert(h);
 
         hash = h->hash_func(key) % NBUCKETS;
-
-        if ((e = hash_scan(h, hash, key))) {
+        e = hash_scan(h, hash, key);
+        if (e) {
                 e->key = key;
                 e->value = value;
                 return 0;
@@ -354,6 +370,21 @@ int hashmap_replace(Hashmap *h, const void *key, void *value) {
         return hashmap_put(h, key, value);
 }
 
+int hashmap_update(Hashmap *h, const void *key, void *value) {
+        struct hashmap_entry *e;
+        unsigned hash;
+
+        assert(h);
+
+        hash = h->hash_func(key) % NBUCKETS;
+        e = hash_scan(h, hash, key);
+        if (!e)
+                return -ENOENT;
+
+        e->value = value;
+        return 0;
+}
+
 void* hashmap_get(Hashmap *h, const void *key) {
         unsigned hash;
         struct hashmap_entry *e;
@@ -362,13 +393,45 @@ void* hashmap_get(Hashmap *h, const void *key) {
                 return NULL;
 
         hash = h->hash_func(key) % NBUCKETS;
+        e = hash_scan(h, hash, key);
+        if (!e)
+                return NULL;
 
-        if (!(e = hash_scan(h, hash, key)))
+        return e->value;
+}
+
+void* hashmap_get2(Hashmap *h, const void *key, void **key2) {
+        unsigned hash;
+        struct hashmap_entry *e;
+
+        if (!h)
                 return NULL;
 
+        hash = h->hash_func(key) % NBUCKETS;
+        e = hash_scan(h, hash, key);
+        if (!e)
+                return NULL;
+
+        if (key2)
+                *key2 = (void*) e->key;
+
         return e->value;
 }
 
+bool hashmap_contains(Hashmap *h, const void *key) {
+        unsigned hash;
+
+        if (!h)
+                return false;
+
+        hash = h->hash_func(key) % NBUCKETS;
+
+        if (!hash_scan(h, hash, key))
+                return false;
+
+        return true;
+}
+
 void* hashmap_remove(Hashmap *h, const void *key) {
         struct hashmap_entry *e;
         unsigned hash;
@@ -729,3 +792,25 @@ char **hashmap_get_strv(Hashmap *h) {
 
         return sv;
 }
+
+void *hashmap_next(Hashmap *h, const void *key) {
+        unsigned hash;
+        struct hashmap_entry *e;
+
+        assert(h);
+        assert(key);
+
+        if (!h)
+                return NULL;
+
+        hash = h->hash_func(key) % NBUCKETS;
+        e = hash_scan(h, hash, key);
+        if (!e)
+                return NULL;
+
+        e = e->iterate_next;
+        if (!e)
+                return NULL;
+
+        return e->value;
+}