factor common code in virHashAddEntry and virHashUpdateEntry

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.
This commit is contained in:
Christophe Fergeau 2011-02-17 22:14:57 +01:00 committed by Eric Blake
parent 5c5880e047
commit 7f1c65e551

View File

@ -22,6 +22,7 @@
#include <config.h> #include <config.h>
#include <string.h> #include <string.h>
#include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
#include "virterror_internal.h" #include "virterror_internal.h"
@ -243,24 +244,16 @@ virHashFree(virHashTablePtr table, virHashDeallocator f)
VIR_FREE(table); VIR_FREE(table);
} }
/** static int
* virHashAddEntry: virHashAddOrUpdateEntry(virHashTablePtr table, const char *name,
* @table: the hash table void *userdata, virHashDeallocator f,
* @name: the name of the userdata bool is_update)
* @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)
{ {
unsigned long key, len = 0; unsigned long key, len = 0;
virHashEntryPtr entry; virHashEntryPtr entry;
virHashEntryPtr insert; virHashEntryPtr insert;
char *new_name; char *new_name;
bool found;
if ((table == NULL) || (name == NULL)) if ((table == NULL) || (name == NULL))
return (-1); return (-1);
@ -268,19 +261,33 @@ virHashAddEntry(virHashTablePtr table, const char *name, void *userdata)
/* /*
* Check for duplicate and insertion location. * Check for duplicate and insertion location.
*/ */
found = false;
key = virHashComputeKey(table, name); key = virHashComputeKey(table, name);
if (table->table[key].valid == 0) { if (table->table[key].valid == 0) {
insert = NULL; insert = NULL;
} else { } else {
for (insert = &(table->table[key]); insert->next != NULL; for (insert = &(table->table[key]); insert->next != NULL;
insert = insert->next) { insert = insert->next) {
if (STREQ(insert->name, name)) if (STREQ(insert->name, name)) {
return (-1); found = true;
break;
}
len++; len++;
} }
if (STREQ(insert->name, name)) 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); return (-1);
} }
}
if (insert == NULL) { if (insert == NULL) {
entry = &(table->table[key]); entry = &(table->table[key]);
@ -314,6 +321,23 @@ virHashAddEntry(virHashTablePtr table, const char *name, void *userdata)
return (0); return (0);
} }
/**
* 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: * virHashUpdateEntry:
* @table: the hash table * @table: the hash table
@ -331,67 +355,7 @@ int
virHashUpdateEntry(virHashTablePtr table, const char *name, virHashUpdateEntry(virHashTablePtr table, const char *name,
void *userdata, virHashDeallocator f) void *userdata, virHashDeallocator f)
{ {
unsigned long key, len = 0; return virHashAddOrUpdateEntry(table, name, userdata, f, true);
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);
} }
/** /**