On 11/4/20 2:05 PM, Peter Krempa wrote:
'virHashForEach' historically allowed deletion of the current element as
'virHashRemoveSet' didn't exits. To prevent us from having to deepy

s/exits/exist

Not sure if you meant 'deeply' instead of deepy (apparently deepy is a
slang for deep, according to google). Either way is fine AFAIC.


Reviewed-by: Daniel Henrique Barboza <danielhb...@gmail.com>

analyse all iterators add virHashForEachSafe which first gets a list of
elements and iterates them outside of the hash table.

This will allow replace the internals of the hash table with other
implementation which don't allow such operation.

Signed-off-by: Peter Krempa <pkre...@redhat.com>
---
  src/libvirt_private.syms |  1 +
  src/util/virhash.c       | 26 +++++++++++++++++++++++---
  src/util/virhash.h       |  1 +
  3 files changed, 25 insertions(+), 3 deletions(-)

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


  /**
- * virHashForEach, virHashForEachSorted
+ * virHashForEach, virHashForEachSorted, virHashForEachSafe
   * @table: the hash table to process
   * @iter: callback to process each element
   * @opaque: opaque data to pass to the iterator
@@ -490,14 +490,14 @@ virHashRemoveEntry(virHashTablePtr table, const char 
*name)
   *
   * The elements are iterated in arbitrary order.
   *
- * virHashForEach allows the callback to remove the current
+ * virHashForEach, virHashForEachSafe allow 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
+ * virHashForEachSorted and virHashForEachSafe are more computationally
   * expensive than virHashForEach.
   *
   * If @iter fails and returns a negative value, the evaluation is stopped and 
-1
@@ -531,6 +531,26 @@ virHashForEach(virHashTablePtr table, virHashIterator 
iter, void *opaque)
  }


+int
+virHashForEachSafe(virHashTablePtr table,
+                   virHashIterator iter,
+                   void *opaque)
+{
+    g_autofree virHashKeyValuePairPtr items = virHashGetItems(table, NULL, 
false);
+    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;
+}
+
+
  int
  virHashForEachSorted(virHashTablePtr table,
                       virHashIterator iter,
diff --git a/src/util/virhash.h b/src/util/virhash.h
index 1a59e9799d..b00ab0447e 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 virHashForEachSafe(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,


Reply via email to