mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-25 22:15:20 +00:00
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:
parent
5c5880e047
commit
7f1c65e551
116
src/util/hash.c
116
src/util/hash.c
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user