[PATCH v2 03/12] util: hash: Introduce virHashForEachSorted

Peter Krempa pkrempa at redhat.com
Wed Nov 4 17:05:39 UTC 2020


Iterate the hash elements sorted by key. This is useful to provide a
stable ordering such as in cases when the output is checked in tests.

Signed-off-by: Peter Krempa <pkrempa at redhat.com>
---
 src/libvirt_private.syms |  1 +
 src/util/virhash.c       | 39 +++++++++++++++++++++++++++++++++++----
 src/util/virhash.h       |  1 +
 3 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 95e50835ad..1793b81ad9 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2203,6 +2203,7 @@ virHashAtomicSteal;
 virHashAtomicUpdate;
 virHashEqual;
 virHashForEach;
+virHashForEachSorted;
 virHashFree;
 virHashGetItems;
 virHashHasEntry;
diff --git a/src/util/virhash.c b/src/util/virhash.c
index f644990712..f205291de9 100644
--- a/src/util/virhash.c
+++ b/src/util/virhash.c
@@ -481,14 +481,25 @@ virHashRemoveEntry(virHashTablePtr table, const char *name)


 /**
- * virHashForEach
+ * virHashForEach, virHashForEachSorted
  * @table: the hash table to process
  * @iter: callback to process each element
  * @opaque: opaque data to pass to the iterator
  *
- * 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.
+ * Iterates over every element in the hash table, invoking the 'iter' callback.
+ *
+ * The elements are iterated in arbitrary order.
+ *
+ * virHashForEach allows the callback to remove the current
+ * element using virHashRemoveEntry but calling other virHash* functions is
+ * prohibited. Note that removing the entry invalidates @key and @payload in
+ * the callback.
+ *
+ * virHashForEachSorted iterates the elements in order by sorted key.
+ *
+ * virHashForEachSorted is more computationally
+ * expensive than virHashForEach.
+ *
  * If @iter fails and returns a negative value, the evaluation is stopped and -1
  * is returned.
  *
@@ -520,6 +531,26 @@ virHashForEach(virHashTablePtr table, virHashIterator iter, void *opaque)
 }


+int
+virHashForEachSorted(virHashTablePtr table,
+                     virHashIterator iter,
+                     void *opaque)
+{
+    g_autofree virHashKeyValuePairPtr items = virHashGetItems(table, NULL, true);
+    size_t i;
+
+    if (!items)
+        return -1;
+
+    for (i = 0; items[i].key; i++) {
+        if (iter((void *)items[i].value, items[i].key, opaque) < 0)
+            return -1;
+    }
+
+    return 0;
+}
+
+
 /**
  * virHashRemoveSet
  * @table: the hash table to process
diff --git a/src/util/virhash.h b/src/util/virhash.h
index 688e1adf4d..1a59e9799d 100644
--- a/src/util/virhash.h
+++ b/src/util/virhash.h
@@ -136,6 +136,7 @@ bool virHashEqual(const virHashTable *table1,
  * Iterators
  */
 int virHashForEach(virHashTablePtr table, virHashIterator iter, void *opaque);
+int virHashForEachSorted(virHashTablePtr table, virHashIterator iter, void *opaque);
 ssize_t virHashRemoveSet(virHashTablePtr table, virHashSearcher iter, const void *opaque);
 void *virHashSearch(const virHashTable *table, virHashSearcher iter,
                     const void *opaque, char **name);
-- 
2.26.2




More information about the libvir-list mailing list