[libvirt] [PATCH v3 08/16] util: Introduce virObjectLookupHash

John Ferlan jferlan at redhat.com
Thu Jun 22 14:02:38 UTC 2017


Using the virObjectLockable class as the base and the virObjectLookupKeys
uuid and name from the virObjectLookupKeys, create the virObjectLookupHash
to manage a common mechanism to store objects for a driver via self locking
hash tables.

Each hash table will have :

    tableElemsStart -> # of elements to create the initial table
    objsUUID        -> Hash table for the LookupKeys->UUID
    objsName        -> Hash table for the LookupKeys->name

A secondary benefit of self locking hash tables is each driver then
does not have to keep a higher level driver lock for interactions with
the object storage since the object itself can manage locking as needed.

Signed-off-by: John Ferlan <jferlan at redhat.com>
---
 src/libvirt_private.syms |  2 ++
 src/util/virobject.c     | 85 +++++++++++++++++++++++++++++++++++++++++++++++-
 src/util/virobject.h     | 24 ++++++++++++++
 3 files changed, 110 insertions(+), 1 deletion(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 6a87e6b..655a8f8 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2274,6 +2274,7 @@ virNumaSetupMemoryPolicy;
 # util/virobject.h
 virClassForObject;
 virClassForObjectLockable;
+virClassForObjectLookupHash;
 virClassForObjectLookupKeys;
 virClassIsDerivedFrom;
 virClassName;
@@ -2285,6 +2286,7 @@ virObjectListFree;
 virObjectListFreeCount;
 virObjectLock;
 virObjectLockableNew;
+virObjectLookupHashNew;
 virObjectLookupKeysGetName;
 virObjectLookupKeysGetUUID;
 virObjectLookupKeysIsActive;
diff --git a/src/util/virobject.c b/src/util/virobject.c
index 6e2b222..79f1fe9 100644
--- a/src/util/virobject.c
+++ b/src/util/virobject.c
@@ -67,9 +67,11 @@ struct _virClass {
 static virClassPtr virObjectClass;
 static virClassPtr virObjectLockableClass;
 static virClassPtr virObjectLookupKeysClass;
+static virClassPtr virObjectLookupHashClass;
 
 static void virObjectLockableDispose(void *anyobj);
 static void virObjectLookupKeysDispose(void *anyobj);
+static void virObjectLookupHashDispose(void *anyobj);
 
 static int
 virObjectOnceInit(void)
@@ -92,6 +94,12 @@ virObjectOnceInit(void)
                                                  virObjectLookupKeysDispose)))
         return -1;
 
+    if (!(virObjectLookupHashClass = virClassNew(virObjectLockableClass,
+                                                 "virObjectLookupHash",
+                                                 sizeof(virObjectLookupHash),
+                                                 virObjectLookupHashDispose)))
+        return -1;
+
     return 0;
 }
 
@@ -144,6 +152,21 @@ virClassForObjectLookupKeys(void)
 
 
 /**
+ * virClassForObjectLookupHash:
+ *
+ * Returns the class instance for the virObjectLookupHash type
+ */
+virClassPtr
+virClassForObjectLookupHash(void)
+{
+    if (virObjectInitialize() < 0)
+        return NULL;
+
+    return virObjectLookupHashClass;
+}
+
+
+/**
  * virClassNew:
  * @parent: the parent class
  * @name: the class name
@@ -344,6 +367,65 @@ virObjectLookupKeysDispose(void *anyobj)
 
 
 /**
+ * virObjectLookupHashNew:
+ * @klass: the klass to check
+ * @tableElemsStart: number of elements initially in the table
+ *
+ * Create a new poolable hash table object for storing hash tables capable
+ * of storing virObjectLookupKeys objects.
+ *
+ * Returns: New object on success, NULL on failure w/ error message set
+ */
+void *
+virObjectLookupHashNew(virClassPtr klass,
+                       int tableElemsStart)
+{
+    virObjectLookupHashPtr obj;
+
+    if (!virClassIsDerivedFrom(klass, virClassForObjectLookupHash())) {
+        virReportInvalidArg(klass,
+                            _("Class %s must derive from virObjectLookupHash"),
+                            virClassName(klass));
+        return NULL;
+    }
+
+    if (!(obj = virObjectLockableNew(klass)))
+        return NULL;
+
+    obj->tableElemsStart = tableElemsStart;
+
+    if (!(obj->objsUUID = virHashCreate(tableElemsStart,
+                                        virObjectFreeHashData)))
+        goto error;
+
+    if (!(obj->objsName = virHashCreate(tableElemsStart,
+                                        virObjectFreeHashData)))
+        goto error;
+
+    VIR_DEBUG("obj=%p, elems=%d objsUUID=%p objsName=%p",
+              obj, tableElemsStart, obj->objsUUID, obj->objsName);
+
+    return obj;
+
+ error:
+    virObjectUnref(obj);
+    return NULL;
+}
+
+
+static void
+virObjectLookupHashDispose(void *anyobj)
+{
+    virObjectLookupHashPtr obj = anyobj;
+
+    VIR_DEBUG("dispose obj=%p", obj);
+
+    virHashFree(obj->objsUUID);
+    virHashFree(obj->objsName);
+}
+
+
+/**
  * virObjectUnref:
  * @anyobj: any instance of virObjectPtr
  *
@@ -410,7 +492,8 @@ static virObjectLockablePtr
 virObjectGetLockableObj(void *anyobj)
 {
     if (virObjectIsClass(anyobj, virObjectLockableClass) ||
-        virObjectIsClass(anyobj, virObjectLookupKeysClass))
+        virObjectIsClass(anyobj, virObjectLookupKeysClass) ||
+        virObjectIsClass(anyobj, virObjectLookupHashClass))
         return anyobj;
 
     VIR_OBJECT_USAGE_PRINT_WARNING(anyobj, virObjectLockableClass);
diff --git a/src/util/virobject.h b/src/util/virobject.h
index 9e0ecc1..3c45182 100644
--- a/src/util/virobject.h
+++ b/src/util/virobject.h
@@ -23,6 +23,7 @@
 # define __VIR_OBJECT_H__
 
 # include "internal.h"
+# include "virhash.h"
 # include "virthread.h"
 
 typedef struct _virClass virClass;
@@ -37,6 +38,9 @@ typedef virObjectLockable *virObjectLockablePtr;
 typedef struct _virObjectLookupKeys virObjectLookupKeys;
 typedef virObjectLookupKeys *virObjectLookupKeysPtr;
 
+typedef struct _virObjectLookupHash virObjectLookupHash;
+typedef virObjectLookupHash *virObjectLookupHashPtr;
+
 typedef void (*virObjectDisposeCallback)(void *obj);
 
 /* Most code should not play with the contents of this struct; however,
@@ -71,10 +75,25 @@ struct _virObjectLookupKeys {
     bool active;           /* true if object is active */
 };
 
+struct _virObjectLookupHash {
+    virObjectLockable parent;
+
+    int tableElemsStart;
+
+    /* uuid string -> object mapping for O(1),
+     * lockless lookup-by-uuid */
+    virHashTable *objsUUID;
+
+    /* name key -> object mapping for O(1),
+     * lockless lookup-by-name */
+    virHashTable *objsName;
+};
+
 
 virClassPtr virClassForObject(void);
 virClassPtr virClassForObjectLockable(void);
 virClassPtr virClassForObjectLookupKeys(void);
+virClassPtr virClassForObjectLookupHash(void);
 
 # ifndef VIR_PARENT_REQUIRED
 #  define VIR_PARENT_REQUIRED ATTRIBUTE_NONNULL(1)
@@ -127,6 +146,11 @@ virObjectLookupKeysNew(virClassPtr klass,
                        const char *name)
     ATTRIBUTE_NONNULL(1);
 
+void *
+virObjectLookupHashNew(virClassPtr klass,
+                       int tableElemsStart)
+    ATTRIBUTE_NONNULL(1);
+
 void
 virObjectLock(void *lockableobj)
     ATTRIBUTE_NONNULL(1);
-- 
2.9.4




More information about the libvir-list mailing list