[Libvir] [Patch 2/4]: Xen inactive domains: hash file

Daniel P. Berrange berrange at redhat.com
Mon Sep 4 00:33:01 UTC 2006


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  -=| 
-------------- next part --------------
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


More information about the libvir-list mailing list