The management of inactive domains uses the hashtable APIs for managing its list of config files. In doing so it needed some extra capabilities. This patch adds 3 new routines: - virHashForEach - iterate over all values in the hashtable invoking a callback for each one. Modifying the hashtable from the callback is forbidden, or bad stuff will happen. - virHashRemoteSet - iterate over all values in the hashtable invoking a callback for each one. If the callback returns non zero, the element will be removed. - virHashSearch - iterate over all values in the hashtable invoking a callback for each one. The first entry for which the callback returnbs non-zero will be returned. 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 -=|
Index: src/hash.c =================================================================== RCS file: /data/cvs/libvirt/src/hash.c,v retrieving revision 1.9 diff -u -r1.9 hash.c --- src/hash.c 29 May 2006 18:03:27 -0000 1.9 +++ src/hash.c 4 Sep 2006 01:15:07 -0000 @@ -473,6 +473,82 @@ } } +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; +} + +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 (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); + } + } + table->nbElems--; + } + } + prev = entry; + entry = entry->next; + } + } + return 0; +} + +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 * @@ -661,6 +737,26 @@ return(NULL); } +virDomainPtr +virGetExistingDomain(virConnectPtr conn, const char *name) { + virDomainPtr ret = NULL; + + if ((!VIR_IS_CONNECT(conn)) || (name == NULL) || + (conn->domains_mux == NULL)) { + virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); + return(NULL); + } + xmlMutexLock(conn->domains_mux); + + /* TODO search by UUID first as they are better differenciators */ + + ret = (virDomainPtr) virHashLookup(conn->domains, name); + if (ret) + ret->uses++; + xmlMutexUnlock(conn->domains_mux); + return(ret); +} + /** * virFreeDomain: * @conn: the hypervisor connection Index: src/hash.h =================================================================== RCS file: /data/cvs/libvirt/src/hash.h,v retrieving revision 1.5 diff -u -r1.5 hash.h --- src/hash.h 9 Apr 2006 13:11:22 -0000 1.5 +++ src/hash.h 4 Sep 2006 01:15:07 -0000 @@ -33,7 +33,9 @@ * * Callback to free data from a hash. */ -typedef void (*virHashDeallocator) (void *payload, char *name); +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,6 +64,12 @@ */ 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