[Libvir] [PATCH 2/6] Inactive domain support: new virHash APIs
Daniel P. Berrange
berrange at redhat.com
Wed Nov 15 02:18:48 UTC 2006
The attached patch adds a couple of new APIs to the hash table object to
allow various different ways of iterating over the contents of the hash
table. The methods are:
virHashForEach
virHashRemoveSet
virHashSearch
Docs for these methods are all inline. Compared to previous patch a logic
flaw in the virHashRemoveSet method was fixed prevently some severe memory
corruption!
Regards,
Dan.
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules: http://search.cpan.org/~danberr/ -=|
|=- Projects: http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
-------------- next part --------------
Index: src/hash.c
===================================================================
RCS file: /data/cvs/libvirt/src/hash.c,v
retrieving revision 1.10
diff -c -r1.10 hash.c
*** src/hash.c 21 Sep 2006 15:24:37 -0000 1.10
--- src/hash.c 15 Nov 2006 02:34:00 -0000
***************
*** 473,478 ****
--- 473,597 ----
}
}
+
+ /**
+ * 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 0 on completion, -1 on failure
+ */
+ int virHashForEach(virHashTablePtr table, virHashIterator iter, const void *data) {
+ int i;
+
+ 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);
+ }
+ entry = entry->next;
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * 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 0 on success, -1 on failure
+ */
+ int virHashRemoveSet(virHashTablePtr table, virHashSearcher iter, virHashDeallocator f, const void *data) {
+ int i;
+
+ 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)) {
+ 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 0;
+ }
+
+ /**
+ * 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,772 ****
--- 889,899 ----
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: src/hash.h
===================================================================
RCS file: /data/cvs/libvirt/src/hash.h,v
retrieving revision 1.5
diff -c -r1.5 hash.h
*** src/hash.h 9 Apr 2006 13:11:22 -0000 1.5
--- src/hash.h 15 Nov 2006 02:34:00 -0000
***************
*** 33,39 ****
*
* Callback to free data from a hash.
*/
! typedef void (*virHashDeallocator) (void *payload, char *name);
/*
* Constructor and destructor.
--- 33,41 ----
*
* Callback to free data from a hash.
*/
! typedef void (*virHashDeallocator) (void *payload, const char *name);
! typedef void (*virHashIterator) (const void *payload, const char *name, const void *data);
! typedef int (*virHashSearcher) (const void *payload, const char *name, const void *data);
/*
* Constructor and destructor.
***************
*** 62,67 ****
--- 64,75 ----
*/
void *virHashLookup(virHashTablePtr table, const char *name);
+
+
+ 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
More information about the libvir-list
mailing list