mirror of
https://github.com/libvirt/libvirt.git
synced 2026-09-03 20:53:04 -05:00
util: Refactor virHashForEach so it returns as soon as an iterator fails
The method will now return 0 on success and -1 on error, rather than number of items which it iterated over before it returned back to the caller. Since the only place where we actually check the number of elements iterated is in virhashtest, return value of 0 and -1 can be a pretty accurate hint that it iterated over all the items. However, if we really want to know the number of items iterated over (like virhashtest does), a counter has to be provided through opaque data to each iterator call. This patch adjusts return value of virHashForEach, refactors the body, so it returns as soon as one of the iterators fail and adjusts virhashtest to reflect these changes. Signed-off-by: Erik Skultety <eskultet@redhat.com>
This commit is contained in:
+15
-8
@@ -579,13 +579,16 @@ virHashRemoveEntry(virHashTablePtr table, const void *name)
|
|||||||
* Iterates over every element in the hash table, invoking the
|
* Iterates over every element in the hash table, invoking the
|
||||||
* 'iter' callback. The callback is allowed to remove the current element
|
* 'iter' callback. The callback is allowed to remove the current element
|
||||||
* using virHashRemoveEntry but calling other virHash* functions is prohibited.
|
* using virHashRemoveEntry but calling other virHash* functions is prohibited.
|
||||||
|
* If @iter fails and returns a negative value, the evaluation is stopped and -1
|
||||||
|
* is returned.
|
||||||
*
|
*
|
||||||
* Returns number of items iterated over upon completion, -1 on failure
|
* Returns 0 on success or -1 on failure.
|
||||||
*/
|
*/
|
||||||
ssize_t
|
int
|
||||||
virHashForEach(virHashTablePtr table, virHashIterator iter, void *data)
|
virHashForEach(virHashTablePtr table, virHashIterator iter, void *data)
|
||||||
{
|
{
|
||||||
size_t i, count = 0;
|
size_t i;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
if (table == NULL || iter == NULL)
|
if (table == NULL || iter == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -599,20 +602,24 @@ virHashForEach(virHashTablePtr table, virHashIterator iter, void *data)
|
|||||||
virHashEntryPtr entry = table->table[i];
|
virHashEntryPtr entry = table->table[i];
|
||||||
while (entry) {
|
while (entry) {
|
||||||
virHashEntryPtr next = entry->next;
|
virHashEntryPtr next = entry->next;
|
||||||
|
|
||||||
table->current = entry;
|
table->current = entry;
|
||||||
iter(entry->payload, entry->name, data);
|
ret = iter(entry->payload, entry->name, data);
|
||||||
table->current = NULL;
|
table->current = NULL;
|
||||||
|
|
||||||
count++;
|
if (ret < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
entry = next;
|
entry = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
table->iterating = false;
|
|
||||||
|
|
||||||
return count;
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
table->iterating = false;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virHashRemoveSet
|
* virHashRemoveSet
|
||||||
* @table: the hash table to process
|
* @table: the hash table to process
|
||||||
|
|||||||
+1
-1
@@ -191,7 +191,7 @@ bool virHashEqual(const virHashTable *table1,
|
|||||||
/*
|
/*
|
||||||
* Iterators
|
* Iterators
|
||||||
*/
|
*/
|
||||||
ssize_t virHashForEach(virHashTablePtr table, virHashIterator iter, void *data);
|
int virHashForEach(virHashTablePtr table, virHashIterator iter, void *data);
|
||||||
ssize_t virHashRemoveSet(virHashTablePtr table, virHashSearcher iter, const void *data);
|
ssize_t virHashRemoveSet(virHashTablePtr table, virHashSearcher iter, const void *data);
|
||||||
void *virHashSearch(const virHashTable *table, virHashSearcher iter,
|
void *virHashSearch(const virHashTable *table, virHashSearcher iter,
|
||||||
const void *data);
|
const void *data);
|
||||||
|
|||||||
+12
-20
@@ -61,24 +61,26 @@ testHashCheckForEachCount(void *payload ATTRIBUTE_UNUSED,
|
|||||||
const void *name ATTRIBUTE_UNUSED,
|
const void *name ATTRIBUTE_UNUSED,
|
||||||
void *data ATTRIBUTE_UNUSED)
|
void *data ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
|
size_t *count = data;
|
||||||
|
*count += 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
testHashCheckCount(virHashTablePtr hash, size_t count)
|
testHashCheckCount(virHashTablePtr hash, size_t count)
|
||||||
{
|
{
|
||||||
ssize_t iter_count = 0;
|
size_t iter_count = 0;
|
||||||
|
|
||||||
if (virHashSize(hash) != count) {
|
if (virHashSize(hash) != count) {
|
||||||
VIR_TEST_VERBOSE("\nhash contains %zu instead of %zu elements\n",
|
VIR_TEST_VERBOSE("\nhash contains %zd instead of %zu elements\n",
|
||||||
(size_t)virHashSize(hash), count);
|
virHashSize(hash), count);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
iter_count = virHashForEach(hash, testHashCheckForEachCount, NULL);
|
virHashForEach(hash, testHashCheckForEachCount, &iter_count);
|
||||||
if (count != iter_count) {
|
if (count != iter_count) {
|
||||||
VIR_TEST_VERBOSE("\nhash claims to have %zu elements but iteration finds %zu\n",
|
VIR_TEST_VERBOSE("\nhash claims to have %zu elements but iteration"
|
||||||
count, (size_t)iter_count);
|
"finds %zu\n", count, iter_count);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,18 +252,13 @@ testHashRemoveForEach(const void *data)
|
|||||||
{
|
{
|
||||||
const struct testInfo *info = data;
|
const struct testInfo *info = data;
|
||||||
virHashTablePtr hash;
|
virHashTablePtr hash;
|
||||||
int count;
|
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
if (!(hash = testHashInit(0)))
|
if (!(hash = testHashInit(0)))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
count = virHashForEach(hash, (virHashIterator) info->data, hash);
|
if (virHashForEach(hash, (virHashIterator) info->data, hash)) {
|
||||||
|
VIR_TEST_VERBOSE("\nvirHashForEach didn't go through all entries");
|
||||||
if (count != ARRAY_CARDINALITY(uuids)) {
|
|
||||||
VIR_TEST_VERBOSE("\nvirHashForEach didn't go through all entries,"
|
|
||||||
" %d != %zu\n",
|
|
||||||
count, ARRAY_CARDINALITY(uuids));
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,18 +340,13 @@ static int
|
|||||||
testHashForEach(const void *data ATTRIBUTE_UNUSED)
|
testHashForEach(const void *data ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
virHashTablePtr hash;
|
virHashTablePtr hash;
|
||||||
int count;
|
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
if (!(hash = testHashInit(0)))
|
if (!(hash = testHashInit(0)))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
count = virHashForEach(hash, testHashForEachIter, hash);
|
if (virHashForEach(hash, testHashForEachIter, hash)) {
|
||||||
|
VIR_TEST_VERBOSE("\nvirHashForEach didn't go through all entries");
|
||||||
if (count != ARRAY_CARDINALITY(uuids)) {
|
|
||||||
VIR_TEST_VERBOSE("\nvirHashForEach didn't go through all entries,"
|
|
||||||
" %d != %zu\n",
|
|
||||||
count, ARRAY_CARDINALITY(uuids));
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user