[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH V4 01/10] Extend virHashTable with function to get hash tables keys



Add a function to the virHashTable for getting an array of the hash table's
keys and have the keys (optionally) sorted.

Signed-off-by: Stefan Berger <stefanb linux vnet ibm com>

---
 src/libvirt_private.syms |    3 +
 src/util/hash.c          |   98 +++++++++++++++++++++++++++++++++++++++++++++++
 src/util/hash.h          |   14 ++++++
 3 files changed, 115 insertions(+)

Index: libvirt-acl/src/util/hash.c
===================================================================
--- libvirt-acl.orig/src/util/hash.c
+++ libvirt-acl/src/util/hash.c
@@ -618,3 +618,101 @@ void *virHashSearch(virHashTablePtr tabl
 
     return NULL;
 }
+
+
+struct getKeysIter
+{
+    virHashTablePtr table;
+    void **array;
+    virHashKeyValuePair *sortArray;
+    unsigned arrayIdx;
+    bool error;
+};
+
+static void virHashGetKeysIterator(void *payload,
+                                   const void *name, void *data)
+{
+    struct getKeysIter *iter = data;
+    void *key;
+
+    if (iter->error)
+        return;
+
+    key = iter->table->keyCopy(name);
+
+    if (key == NULL) {
+        virReportOOMError();
+        iter->error = true;
+        return;
+    }
+
+    if (iter->sortArray) {
+        iter->sortArray[iter->arrayIdx].key = key;
+        iter->sortArray[iter->arrayIdx].value = payload;
+    } else {
+        iter->array[iter->arrayIdx] = iter->table->keyCopy(name);
+    }
+    iter->arrayIdx++;
+}
+
+void virHashFreeKeys(virHashTablePtr table, void **keys)
+{
+    unsigned i = 0;
+
+    if (keys == NULL)
+        return;
+
+    while (keys[i])
+        table->keyFree(keys[i++]);
+
+    VIR_FREE(keys);
+}
+
+typedef int (*qsort_comp)(const void *, const void *);
+
+void **virHashGetKeys(virHashTablePtr table,
+                      virHashKeyComparator compar)
+{
+    int i, numElems = virHashSize(table);
+    struct getKeysIter iter = {
+        .table = table,
+        .arrayIdx = 0,
+        .error = false,
+    };
+
+    if (numElems < 0) {
+        return NULL;
+    }
+
+    if (VIR_ALLOC_N(iter.array, numElems + 1)) {
+        virReportOOMError();
+        return NULL;
+    }
+
+    /* null-terminate array */
+    iter.array[numElems] =  NULL;
+
+    if (compar &&
+        VIR_ALLOC_N(iter.sortArray, numElems)) {
+        VIR_FREE(iter.array);
+        virReportOOMError();
+        return NULL;
+    }
+
+    virHashForEach(table, virHashGetKeysIterator, &iter);
+    if (iter.error) {
+        VIR_FREE(iter.sortArray);
+        virHashFreeKeys(table, iter.array);
+        return NULL;
+    }
+
+    if (compar) {
+        qsort(&iter.sortArray[0], numElems, sizeof(iter.sortArray[0]),
+              (qsort_comp)compar);
+        for (i = 0; i < numElems; i++)
+            iter.array[i] = iter.sortArray[i].key;
+        VIR_FREE(iter.sortArray);
+    }
+
+    return iter.array;
+}
Index: libvirt-acl/src/util/hash.h
===================================================================
--- libvirt-acl.orig/src/util/hash.h
+++ libvirt-acl/src/util/hash.h
@@ -130,6 +130,20 @@ void *virHashLookup(virHashTablePtr tabl
  */
 void *virHashSteal(virHashTablePtr table, const void *name);
 
+/*
+ * Get the set of keys and have them optionally sorted.
+ */
+typedef struct _virHashKeyValuePair virHashKeyValuePair;
+typedef virHashKeyValuePair *virHashKeyValuePairPtr;
+struct _virHashKeyValuePair {
+    void *key;
+    const void *value;
+};
+typedef int (*virHashKeyComparator)(const virHashKeyValuePairPtr ,
+                                    const virHashKeyValuePairPtr );
+void **virHashGetKeys(virHashTablePtr table, virHashKeyComparator compar);
+void virHashFreeKeys(virHashTablePtr table, void **);
+
 
 /*
  * Iterators
Index: libvirt-acl/src/libvirt_private.syms
===================================================================
--- libvirt-acl.orig/src/libvirt_private.syms
+++ libvirt-acl/src/libvirt_private.syms
@@ -559,6 +559,8 @@ virHashAddEntry;
 virHashCreate;
 virHashForEach;
 virHashFree;
+virHashFreeKeys;
+virHashGetKeys;
 virHashLookup;
 virHashRemoveEntry;
 virHashRemoveSet;
@@ -566,6 +568,7 @@ virHashSearch;
 virHashSize;
 virHashSteal;
 virHashTableSize;
+virHashUpdateEntry;
 
 
 # hooks.h


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]