[libvirt] [PATCH 4/8] factor common code in virHashAddEntry and virHashUpdateEntry

Christophe Fergeau teuf at gnome.org
Sun Feb 13 21:45:20 UTC 2011


The only difference between these 2 functions is that one errors
out when the entry is already present while the other modifies
the existing entry. Add an helper function with a boolean argument
indicating whether existing entries should be updated or not, and
use this helper in both functions.
---
 src/util/hash.c |  115 +++++++++++++++++++------------------------------------
 1 files changed, 40 insertions(+), 75 deletions(-)

diff --git a/src/util/hash.c b/src/util/hash.c
index 8e337eb..031e5af 100644
--- a/src/util/hash.c
+++ b/src/util/hash.c
@@ -21,6 +21,7 @@
 #include <config.h>
 
 #include <string.h>
+#include <stdbool.h>
 #include <stdlib.h>
 
 #include "virterror_internal.h"
@@ -237,24 +238,16 @@ virHashFree(virHashTablePtr table, virHashDeallocator f)
     VIR_FREE(table);
 }
 
-/**
- * virHashAddEntry:
- * @table: the hash table
- * @name: the name of the userdata
- * @userdata: a pointer to the userdata
- *
- * Add the @userdata to the hash @table. This can later be retrieved
- * by using @name. Duplicate entries generate errors.
- *
- * Returns 0 the addition succeeded and -1 in case of error.
- */
-int
-virHashAddEntry(virHashTablePtr table, const char *name, void *userdata)
+static int
+virHashAddOrUpdateEntry(virHashTablePtr table, const char *name,
+                        void *userdata, virHashDeallocator f,
+                        bool is_update)
 {
     unsigned long key, len = 0;
     virHashEntryPtr entry;
     virHashEntryPtr insert;
     char *new_name;
+    bool found;
 
     if ((table == NULL) || (name == NULL))
         return (-1);
@@ -262,18 +255,32 @@ virHashAddEntry(virHashTablePtr table, const char *name, void *userdata)
     /*
      * Check for duplicate and insertion location.
      */
+    found = false;
     key = virHashComputeKey(table, name);
     if (table->table[key].valid == 0) {
         insert = NULL;
     } else {
         for (insert = &(table->table[key]); insert->next != NULL;
              insert = insert->next) {
-            if (STREQ(insert->name, name))
-                return (-1);
+            if (STREQ(insert->name, name)) {
+                found = true;
+                break;
+            }
             len++;
         }
         if (STREQ(insert->name, name))
+            found = true;
+    }
+
+    if (found) {
+        if (is_update) {
+            if (f)
+                f(insert->payload, insert->name);
+            insert->payload = userdata;
+            return (0);
+        } else {
             return (-1);
+        }
     }
 
     if (insert == NULL) {
@@ -306,6 +313,23 @@ virHashAddEntry(virHashTablePtr table, const char *name, void *userdata)
 }
 
 /**
+ * virHashAddEntry:
+ * @table: the hash table
+ * @name: the name of the userdata
+ * @userdata: a pointer to the userdata
+ *
+ * Add the @userdata to the hash @table. This can later be retrieved
+ * by using @name. Duplicate entries generate errors.
+ *
+ * Returns 0 the addition succeeded and -1 in case of error.
+ */
+int
+virHashAddEntry(virHashTablePtr table, const char *name, void *userdata)
+{
+    return virHashAddOrUpdateEntry(table, name, userdata, NULL, false);
+}
+
+/**
  * virHashUpdateEntry:
  * @table: the hash table
  * @name: the name of the userdata
@@ -322,66 +346,7 @@ int
 virHashUpdateEntry(virHashTablePtr table, const char *name,
                    void *userdata, virHashDeallocator f)
 {
-    unsigned long key, len = 0;
-    virHashEntryPtr entry;
-    virHashEntryPtr insert;
-
-    if ((table == NULL) || name == NULL)
-        return (-1);
-
-    /*
-     * Check for duplicate and insertion location.
-     */
-    key = virHashComputeKey(table, name);
-    if (table->table[key].valid == 0) {
-        insert = NULL;
-    } else {
-        for (insert = &(table->table[key]); insert->next != NULL;
-             insert = insert->next) {
-            if (STREQ(insert->name, name)) {
-                if (f)
-                    f(insert->payload, insert->name);
-                insert->payload = userdata;
-                return (0);
-            }
-            len++;
-        }
-        if (STREQ(insert->name, name)) {
-            if (f)
-                f(insert->payload, insert->name);
-            insert->payload = userdata;
-            return (0);
-        }
-    }
-
-    if (insert == NULL) {
-        entry = &(table->table[key]);
-    } else {
-        if (VIR_ALLOC(entry) < 0)
-            return (-1);
-    }
-
-    new_name= strdup(name);
-    if (new_name == NULL) {
-        if (insert != NULL)
-            VIR_FREE(entry);
-        return (-1);
-    }
-    entry->name = new_name;
-    entry->payload = userdata;
-    entry->next = NULL;
-    entry->valid = 1;
-    table->nbElems++;
-
-
-    if (insert != NULL) {
-        insert->next = entry;
-    }
-
-    if (len > MAX_HASH_LEN)
-        virHashGrow(table, MAX_HASH_LEN * table->size);
-
-    return (0);
+    return virHashAddOrUpdateEntry(table, name, userdata, f, true);
 }
 
 /**
-- 
1.7.4




More information about the libvir-list mailing list