Add a function to the virHashTable for getting an array of the hash table's key-value pairs and have the keys (optionally) sorted. Signed-off-by: Stefan Berger --- v5: - follwed Eric Blake's suggestions: - added better description to new function - return array of key-value pairs rather than only keys --- src/libvirt_private.syms | 2 ++ src/util/hash.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/util/hash.h | 22 ++++++++++++++++++++++ 3 files changed, 69 insertions(+) Index: libvirt-acl/src/util/hash.c =================================================================== --- libvirt-acl.orig/src/util/hash.c +++ libvirt-acl/src/util/hash.c @@ -618,3 +618,48 @@ void *virHashSearch(virHashTablePtr tabl return NULL; } + +struct getKeysIter +{ + virHashKeyValuePair *sortArray; + unsigned arrayIdx; +}; + +static void virHashGetKeysIterator(void *payload, + const void *key, void *data) +{ + struct getKeysIter *iter = data; + + iter->sortArray[iter->arrayIdx].key = key; + iter->sortArray[iter->arrayIdx].value = payload; + + iter->arrayIdx++; +} + +typedef int (*qsort_comp)(const void *, const void *); + +virHashKeyValuePairPtr virHashGetItems(virHashTablePtr table, + virHashKeyComparator compar) +{ + int numElems = virHashSize(table); + struct getKeysIter iter = { + .arrayIdx = 0, + .sortArray = NULL, + }; + + if (numElems < 0) + return NULL; + + if (VIR_ALLOC_N(iter.sortArray, numElems + 1)) { + virReportOOMError(); + return NULL; + } + + virHashForEach(table, virHashGetKeysIterator, &iter); + + if (compar) + qsort(&iter.sortArray[0], numElems, sizeof(iter.sortArray[0]), + (qsort_comp)compar); + + return iter.sortArray; +} Index: libvirt-acl/src/util/hash.h =================================================================== --- libvirt-acl.orig/src/util/hash.h +++ libvirt-acl/src/util/hash.h @@ -130,6 +130,28 @@ void *virHashLookup(virHashTablePtr tabl */ void *virHashSteal(virHashTablePtr table, const void *name); +/* + * Get the hash table's key/value pairs and have them optionally sorted. + * The returned array contains virHashSize() elements. Additionally, + * an empty element has been added to the end of the array (with key == NULL) + * to indicate the end of the array. + * The key/value pairs are only valid as long as the underlying hash + * table is not modified, i.e., no keys are removed or inserted, and + * the hash table is not deleted. + * The caller must only free the returned array using VIR_FREE(). + * The caller must make copies of all returned keys and values if they are + * to be used somewhere else. + */ +typedef struct _virHashKeyValuePair virHashKeyValuePair; +typedef virHashKeyValuePair *virHashKeyValuePairPtr; +struct _virHashKeyValuePair { + const void *key; + const void *value; +}; +typedef int (*virHashKeyComparator)(const virHashKeyValuePairPtr, + const virHashKeyValuePairPtr); +virHashKeyValuePairPtr virHashGetItems(virHashTablePtr table, + virHashKeyComparator compar); /* * Iterators Index: libvirt-acl/src/libvirt_private.syms =================================================================== --- libvirt-acl.orig/src/libvirt_private.syms +++ libvirt-acl/src/libvirt_private.syms @@ -559,6 +559,7 @@ virHashAddEntry; virHashCreate; virHashForEach; virHashFree; +virHashGetItems; virHashLookup; virHashRemoveEntry; virHashRemoveSet; @@ -566,6 +567,7 @@ virHashSearch; virHashSize; virHashSteal; virHashTableSize; +virHashUpdateEntry; # hooks.h