]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
util: hash: Add delete-safe hash iterator
authorPeter Krempa <pkrempa@redhat.com>
Mon, 26 Oct 2020 14:30:10 +0000 (15:30 +0100)
committerPeter Krempa <pkrempa@redhat.com>
Fri, 6 Nov 2020 09:31:57 +0000 (10:31 +0100)
'virHashForEach' historically allowed deletion of the current element as
'virHashRemoveSet' didn't exist. To prevent us from having to deeply
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 <pkrempa@redhat.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Reviewed-by: Matt Coleman <matt@datto.com>
src/libvirt_private.syms
src/util/virhash.c
src/util/virhash.h

index 157a97d4a965d4c17101f2ca07e45f24e034499d..e257f373169080528d026e32719881680564031c 100644 (file)
@@ -2207,6 +2207,7 @@ virHashAtomicSteal;
 virHashAtomicUpdate;
 virHashEqual;
 virHashForEach;
+virHashForEachSafe;
 virHashForEachSorted;
 virHashFree;
 virHashGetItems;
index f205291de9b50d25e268debfa028770caee4e75c..e54052985fdc494ed9e94c2eb052f26ed3ff3851 100644 (file)
@@ -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,
index 1a59e9799dd9b2e2c71083e80382b98746f36d89..b00ab0447e4b9e9ac1734a408878db76d45cf2ea 100644 (file)
@@ -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,