mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 03:12:22 +00:00
util: hash: Add delete-safe hash iterator
'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>
This commit is contained in:
parent
5f1b1da1b9
commit
80f3af5fd8
@ -2207,6 +2207,7 @@ virHashAtomicSteal;
|
||||
virHashAtomicUpdate;
|
||||
virHashEqual;
|
||||
virHashForEach;
|
||||
virHashForEachSafe;
|
||||
virHashForEachSorted;
|
||||
virHashFree;
|
||||
virHashGetItems;
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user