]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Added several iterators to hashtable API
authorDaniel P. Berrange <berrange@redhat.com>
Wed, 15 Nov 2006 20:11:56 +0000 (20:11 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Wed, 15 Nov 2006 20:11:56 +0000 (20:11 +0000)
ChangeLog
src/hash.c
src/hash.h

index cd186694b2e84eaac4d49c1c8789250a9f16f2c5..5a45484e743219add3796ec3b6253db29dad3cda 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Wed Nov 15 15:59:13 EST 2006 Daniel Berrange <berrange@redhat.com>
+
+       * src/hash.c, src/hash.h: Added three new methods for iterating
+       over hashtable entries, virHashForEach, virHashRemoveSet &
+       virHashSearch.
+
 Wed Nov 15 15:52:01 EST 2006 Daniel Berrange <berrange@redhat.com>
 
        * src/conf.c, src/conf.h: Add two new APIs virConfNew() and
index cd3da8a8bfdad2aa1c835380c915e0297ff3b7b1..ebc6229a831d727da83c2db6c48666715c08f927 100644 (file)
@@ -473,6 +473,127 @@ virHashRemoveEntry(virHashTablePtr table, const char *name,
     }
 }
 
+
+/**
+ * virHashForEach
+ * @table: the hash table to process
+ * @iter: callback to process each element
+ * @data: opaque data to pass to the iterator
+ *
+ * Iterates over every element in the hash table, invoking the
+ * 'iter' callback. The callback must not call any other virHash*
+ * functions, and in particular must not attempt to remove the
+ * element.
+ *
+ * Returns number of items iterated over upon completion, -1 on failure
+ */
+int virHashForEach(virHashTablePtr table, virHashIterator iter, const void *data) {
+    int i, count = 0;
+
+    if (table == NULL || iter == NULL)
+        return (-1);
+
+    for (i = 0 ; i < table->size ; i++) {
+        virHashEntryPtr entry = table->table + i;
+        while (entry) {
+            if (entry->valid) {
+                iter(entry->payload, entry->name, data);
+                count++;
+            }
+            entry = entry->next;
+        }
+    }
+    return (count);
+}
+
+/**
+ * virHashRemoveSet
+ * @table: the hash table to process
+ * @iter: callback to identify elements for removal
+ * @f: callback to free memory from element payload
+ * @data: opaque data to pass to the iterator
+ *
+ * Iterates over all elements in the hash table, invoking the 'iter'
+ * callback. If the callback returns a non-zero value, the element
+ * will be removed from the hash table & its payload passed to the
+ * callback 'f' for de-allocation.
+ *
+ * Returns number of items removed on success, -1 on failure
+ */
+int virHashRemoveSet(virHashTablePtr table, virHashSearcher iter, virHashDeallocator f, const void *data) {
+    int i, count = 0;
+
+    if (table == NULL || iter == NULL)
+        return (-1);
+
+    for (i = 0 ; i < table->size ; i++) {
+        virHashEntryPtr prev = NULL;
+        virHashEntryPtr entry = &(table->table[i]);
+
+        while (entry && entry->valid) {
+            if (iter(entry->payload, entry->name, data)) {
+                count++;
+                f(entry->payload, entry->name);
+                if (entry->name)
+                    free(entry->name);
+                if (prev) {
+                    prev->next = entry->next;
+                    free(entry);
+                } else {
+                    if (entry->next == NULL) {
+                        entry->valid = 0;
+                        entry->name = NULL;
+                    } else {
+                        entry = entry->next;
+                        memcpy(&(table->table[i]), entry,
+                               sizeof(virHashEntry));
+                        free(entry);
+                        entry = NULL;
+                    }
+                }
+                table->nbElems--;
+            }
+            prev = entry;
+            if (entry) {
+                entry = entry->next;
+            } else {
+                entry = NULL;
+            }
+        }
+    }
+    return (count);
+}
+
+/**
+ * virHashSearch:
+ * @table: the hash table to search
+ * @iter: an iterator to identify the desired element
+ * @data: extra opaque information passed to the iter
+ *
+ * Iterates over the hash table calling the 'iter' callback
+ * for each element. The first element for which the iter
+ * returns non-zero will be returned by this function.
+ * The elements are processed in a undefined order
+ */
+void *virHashSearch(virHashTablePtr table, virHashSearcher iter, const void *data) {
+    int i;
+
+    if (table == NULL || iter == NULL)
+        return (NULL);
+
+    for (i = 0 ; i < table->size ; i++) {
+        virHashEntryPtr entry = table->table + i;
+        while (entry) {
+            if (entry->valid) {
+                if (iter(entry->payload, entry->name, data))
+                    return entry->payload;
+            }
+            entry = entry->next;
+        }
+    }
+    return (NULL);
+}
+
 /************************************************************************
  *                                                                     *
  *                     Domain and Connections allocations              *
@@ -770,3 +891,11 @@ done:
     xmlMutexUnlock(conn->domains_mux);
     return(ret);
 }
+/*
+ * Local variables:
+ *  indent-tabs-mode: nil
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 4
+ * End:
+ */
index 5becd9a4e34016398afcfaea869984ba5bd5e24c..6fc963c410a6d7453ea1daf3201bd0697cbd626a 100644 (file)
@@ -33,7 +33,27 @@ typedef virHashTable *virHashTablePtr;
  *
  * Callback to free data from a hash.
  */
-typedef void (*virHashDeallocator) (void *payload, char *name);
+typedef void (*virHashDeallocator) (void *payload, const char *name);
+/**
+ * virHashIterator:
+ * @payload: the data in the hash
+ * @name: the name associated
+ * @data: user supplied data blob
+ *
+ * Callback to process a hash entry during iteration
+ */
+typedef void (*virHashIterator) (const void *payload, const char *name, const void *data);
+/**
+ * virHashSearcher
+ * @payload: the data in the hash
+ * @name: the name associated
+ * @data: user supplied data blob
+ *
+ * Callback to identify hash entry desired
+ * Returns 1 if the hash entry is desired, 0 to move
+ * to next entry
+ */
+typedef int (*virHashSearcher) (const void *payload, const char *name, const void *data);
 
 /*
  * Constructor and destructor.
@@ -62,6 +82,14 @@ int virHashRemoveEntry(virHashTablePtr table,
  */
 void *virHashLookup(virHashTablePtr table, const char *name);
 
+
+/*
+ * Iterators
+ */
+int virHashForEach(virHashTablePtr table, virHashIterator iter, const void *data);
+int virHashRemoveSet(virHashTablePtr table, virHashSearcher iter, virHashDeallocator f, const void *data);
+void *virHashSearch(virHashTablePtr table, virHashSearcher iter, const void *data);
+
 #ifdef __cplusplus
 }
 #endif