[libvirt] [PATCH v4 2/7] util: Refactor virHashForEach so it returns as soon as an iterator fails
Michal Privoznik
mprivozn at redhat.com
Tue Feb 16 16:18:11 UTC 2016
On 12.02.2016 11:08, Erik Skultety wrote:
> 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 at redhat.com>
> ---
> src/util/virhash.c | 23 +++++++++++++++--------
> src/util/virhash.h | 2 +-
> tests/virhashtest.c | 35 ++++++++++++++---------------------
> 3 files changed, 30 insertions(+), 30 deletions(-)
>
> diff --git a/src/util/virhash.c b/src/util/virhash.c
> index d6f208e..a8e0edf 100644
> --- a/src/util/virhash.c
> +++ b/src/util/virhash.c
> @@ -579,13 +579,16 @@ virHashRemoveEntry(virHashTablePtr table, const void *name)
> * Iterates over every element in the hash table, invoking the
> * 'iter' callback. The callback is allowed to remove the current element
> * 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)
> {
> - size_t i, count = 0;
> + size_t i;
> + int ret = -1;
>
> if (table == NULL || iter == NULL)
> return -1;
> @@ -599,20 +602,24 @@ virHashForEach(virHashTablePtr table, virHashIterator iter, void *data)
> virHashEntryPtr entry = table->table[i];
> while (entry) {
> virHashEntryPtr next = entry->next;
> -
> table->current = entry;
> - iter(entry->payload, entry->name, data);
> + ret = iter(entry->payload, entry->name, data);
> table->current = NULL;
>
> - count++;
> + if (ret < 0)
> + goto cleanup;
> +
> entry = next;
> }
> }
> - table->iterating = false;
>
> - return count;
> + ret = 0;
> + cleanup:
> + table->iterating = false;
> + return ret;
> }
>
> +
> /**
> * virHashRemoveSet
> * @table: the hash table to process
> diff --git a/src/util/virhash.h b/src/util/virhash.h
> index ed6bba3..61c172b 100644
> --- a/src/util/virhash.h
> +++ b/src/util/virhash.h
> @@ -191,7 +191,7 @@ bool virHashEqual(const virHashTable *table1,
> /*
> * 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);
> void *virHashSearch(const virHashTable *table, virHashSearcher iter,
> const void *data);
> diff --git a/tests/virhashtest.c b/tests/virhashtest.c
> index 323c68e..e538ea4 100644
> --- a/tests/virhashtest.c
> +++ b/tests/virhashtest.c
> @@ -61,24 +61,27 @@ testHashCheckForEachCount(void *payload ATTRIBUTE_UNUSED,
> const void *name ATTRIBUTE_UNUSED,
> void *data ATTRIBUTE_UNUSED)
> {
> + ssize_t *count = data;
> + *count += 1;
> return 0;
> }
>
> static int
> -testHashCheckCount(virHashTablePtr hash, size_t count)
> +testHashCheckCount(virHashTablePtr hash, int count)
> {
> - ssize_t iter_count = 0;
> + int iter_count = 0;
Why are you changing the type if the callback expects ssize_t anyway?
>
> if (virHashSize(hash) != count) {
> VIR_TEST_VERBOSE("\nhash contains %zu instead of %zu elements\n",
> - (size_t)virHashSize(hash), count);
> + (size_t)virHashSize(hash), (size_t)count);
This makes not much sense. We are in the control of formatting string, so why the typecasting?
> return -1;
> }
>
> - iter_count = virHashForEach(hash, testHashCheckForEachCount, NULL);
> + virHashForEach(hash, testHashCheckForEachCount, &iter_count);
> if (count != iter_count) {
> - VIR_TEST_VERBOSE("\nhash claims to have %zu elements but iteration finds %zu\n",
> - count, (size_t)iter_count);
> + VIR_TEST_VERBOSE("\nhash claims to have %zu elements but iteration"
> + "finds %zu\n",
> + (size_t)count, (size_t)iter_count);
> return -1;
> }
>
ACK with this squashed in:
diff --git a/tests/virhashtest.c b/tests/virhashtest.c
index e538ea4..ed9ad46 100644
--- a/tests/virhashtest.c
+++ b/tests/virhashtest.c
@@ -67,21 +67,20 @@ testHashCheckForEachCount(void *payload ATTRIBUTE_UNUSED,
}
static int
-testHashCheckCount(virHashTablePtr hash, int count)
+testHashCheckCount(virHashTablePtr hash, size_t count)
{
- int iter_count = 0;
+ ssize_t iter_count = 0;
if (virHashSize(hash) != count) {
- VIR_TEST_VERBOSE("\nhash contains %zu instead of %zu elements\n",
- (size_t)virHashSize(hash), (size_t)count);
+ VIR_TEST_VERBOSE("\nhash contains %zd instead of %zu elements\n",
+ virHashSize(hash), count);
return -1;
}
virHashForEach(hash, testHashCheckForEachCount, &iter_count);
if (count != iter_count) {
- VIR_TEST_VERBOSE("\nhash claims to have %zu elements but iteration"
- "finds %zu\n",
- (size_t)count, (size_t)iter_count);
+ VIR_TEST_VERBOSE("\nhash claims to have %zd elements but iteration"
+ "finds %zd\n", count, iter_count);
return -1;
}
Michal
More information about the libvir-list
mailing list