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 | 116 +++++++++++++++++++------------------------------------
1 files changed, 40 insertions(+), 76 deletions(-)
diff --git a/src/util/hash.c b/src/util/hash.c
index 595f447..f19d249 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"
@@ -243,24 +244,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);
@@ -268,18 +261,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) {
@@ -315,6 +322,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
@@ -331,67 +355,7 @@ int
virHashUpdateEntry(virHashTablePtr table, const char *name,
void *userdata, virHashDeallocator f)
{
- unsigned long key, len = 0;
- virHashEntryPtr entry;
- virHashEntryPtr insert;
- char *new_name;
-
- 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