From nobody Thu May 15 19:20:12 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1503523375323981.9562307721267; Wed, 23 Aug 2017 14:22:55 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1CFCC806A6; Wed, 23 Aug 2017 21:22:48 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id ED0B369566; Wed, 23 Aug 2017 21:22:47 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id B2D8D4EE50; Wed, 23 Aug 2017 21:22:47 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v7NLMjK0023961 for ; Wed, 23 Aug 2017 17:22:45 -0400 Received: by smtp.corp.redhat.com (Postfix) id C0B5366D39; Wed, 23 Aug 2017 21:22:45 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-123-165.rdu2.redhat.com [10.10.123.165]) by smtp.corp.redhat.com (Postfix) with ESMTP id E58C281EEB for ; Wed, 23 Aug 2017 21:22:38 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 1CFCC806A6 Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: John Ferlan To: libvir-list@redhat.com Date: Wed, 23 Aug 2017 17:21:58 -0400 Message-Id: <20170823212211.4693-3-jferlan@redhat.com> In-Reply-To: <20170823212211.4693-1-jferlan@redhat.com> References: <20170823212211.4693-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v5 02/15] util: Introduce virObjectLookupHash X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Wed, 23 Aug 2017 21:22:53 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Define an object meant to combine/manage the aspects of the various _vir*ObjList structs into one common purpose list management system that will store and manage _vir*Obj virObjectLockable objects rather than having multiple structs and API's to do that. The object will use the virObjectRWLockable class as the base and may have one or two hash tables that will be keyed by UUID or Name based on the needs of the consumer stored in: objsUUID -> Hash table for storing objects for lookup by UUID objsName -> Hash table for storing objects for lookup by Name The virObjectLookupHashNew will require the consumer to provide which hash tables are to be used via virObjectLookupHashNewFlags. 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 --- src/libvirt_private.syms | 2 ++ src/util/virobject.c | 93 ++++++++++++++++++++++++++++++++++++++++++++= +++- src/util/virobject.h | 34 ++++++++++++++++++ 3 files changed, 128 insertions(+), 1 deletion(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 2149b11..33dbd92 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2318,6 +2318,7 @@ virNumaSetupMemoryPolicy; # util/virobject.h virClassForObject; virClassForObjectLockable; +virClassForObjectLookupHash; virClassForObjectRWLockable; virClassIsDerivedFrom; virClassName; @@ -2329,6 +2330,7 @@ virObjectListFree; virObjectListFreeCount; virObjectLock; virObjectLockableNew; +virObjectLookupHashNew; virObjectNew; virObjectRef; virObjectRWLockableNew; diff --git a/src/util/virobject.c b/src/util/virobject.c index 38db692..edd8097 100644 --- a/src/util/virobject.c +++ b/src/util/virobject.c @@ -68,9 +68,11 @@ struct _virClass { static virClassPtr virObjectClass; static virClassPtr virObjectLockableClass; static virClassPtr virObjectRWLockableClass; +static virClassPtr virObjectLookupHashClass; =20 static void virObjectLockableDispose(void *anyobj); static void virObjectRWLockableDispose(void *anyobj); +static void virObjectLookupHashDispose(void *anyobj); =20 static int virObjectOnceInit(void) @@ -93,6 +95,12 @@ virObjectOnceInit(void) virObjectRWLockableDispos= e))) return -1; =20 + if (!(virObjectLookupHashClass =3D virClassNew(virObjectRWLockableClas= s, + "virObjectLookupHash", + sizeof(virObjectLookupHas= h), + virObjectLookupHashDispos= e))) + return -1; + return 0; } =20 @@ -145,6 +153,21 @@ virClassForObjectRWLockable(void) =20 =20 /** + * 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 @@ -328,6 +351,73 @@ virObjectRWLockableDispose(void *anyobj) =20 =20 /** + * virObjectLookupHashNew: + * @klass: the klass to check + * @tableElemsStart: initial size of each hash table + * @flags: virObjectLookupHashNewFlags to indicate which tables to create + * + * Create a new poolable hash table object for storing either 1 or 2 hash + * tables capable of storing virObjectLockable objects by UUID or Name. Th= is + * object will use the RWLockable objects in order to allow for concurrent + * table reads by multiple threads looking to return lists of data. + * + * Returns: New object on success, NULL on failure w/ error message set + */ +void * +virObjectLookupHashNew(virClassPtr klass, + int tableElemsStart, + virObjectLookupHashNewFlags flags) +{ + virObjectLookupHashPtr obj; + + if (!flags || !(flags & (VIR_OBJECT_LOOKUP_HASH_UUID | + VIR_OBJECT_LOOKUP_HASH_NAME))) { + virReportError(VIR_ERR_INVALID_ARG, + _("flags=3D%x must be non zero or properly set"), f= lags); + return NULL; + } + + if (!virClassIsDerivedFrom(klass, virClassForObjectLookupHash())) { + virReportInvalidArg(klass, + _("Class %s must derive from virObjectLookupHa= sh"), + virClassName(klass)); + return NULL; + } + + if (!(obj =3D virObjectRWLockableNew(klass))) + return NULL; + + if (flags & VIR_OBJECT_LOOKUP_HASH_UUID) { + if (!(obj->objsUUID =3D virHashCreate(tableElemsStart, + virObjectFreeHashData))) + goto error; + } + + if (flags & VIR_OBJECT_LOOKUP_HASH_NAME) { + if (!(obj->objsName =3D virHashCreate(tableElemsStart, + virObjectFreeHashData))) + goto error; + } + + return obj; + + error: + virObjectUnref(obj); + return NULL; +} + + +static void +virObjectLookupHashDispose(void *anyobj) +{ + virObjectLookupHashPtr obj =3D anyobj; + + virHashFree(obj->objsUUID); + virHashFree(obj->objsName); +} + + +/** * virObjectUnref: * @anyobj: any instance of virObjectPtr * @@ -404,7 +494,8 @@ virObjectGetLockableObj(void *anyobj) static virObjectRWLockablePtr virObjectGetRWLockableObj(void *anyobj) { - if (virObjectIsClass(anyobj, virObjectRWLockableClass)) + if (virObjectIsClass(anyobj, virObjectRWLockableClass) || + virObjectIsClass(anyobj, virObjectLookupHashClass)) return anyobj; =20 VIR_OBJECT_USAGE_PRINT_ERROR(anyobj, virObjectRWLockable); diff --git a/src/util/virobject.h b/src/util/virobject.h index ac6cf22..75efa90 100644 --- a/src/util/virobject.h +++ b/src/util/virobject.h @@ -23,6 +23,7 @@ # define __VIR_OBJECT_H__ =20 # include "internal.h" +# include "virhash.h" # include "virthread.h" =20 typedef struct _virClass virClass; @@ -37,6 +38,9 @@ typedef virObjectLockable *virObjectLockablePtr; typedef struct _virObjectRWLockable virObjectRWLockable; typedef virObjectRWLockable *virObjectRWLockablePtr; =20 +typedef struct _virObjectLookupHash virObjectLookupHash; +typedef virObjectLookupHash *virObjectLookupHashPtr; + typedef void (*virObjectDisposeCallback)(void *obj); =20 /* Most code should not play with the contents of this struct; however, @@ -71,6 +75,24 @@ virClassPtr virClassForObject(void); virClassPtr virClassForObjectLockable(void); virClassPtr virClassForObjectRWLockable(void); =20 +struct _virObjectLookupHash { + virObjectRWLockable parent; + + /* key1 string -> object mapping for O(1), + * lockless lookup-by-uuid */ + virHashTable *objsUUID; + + /* key2 string -> object mapping for O(1), + * lockless lookup-by-name */ + virHashTable *objsName; +}; + + +virClassPtr virClassForObject(void); +virClassPtr virClassForObjectLockable(void); +virClassPtr virClassForObjectRWLockable(void); +virClassPtr virClassForObjectLookupHash(void); + # ifndef VIR_PARENT_REQUIRED # define VIR_PARENT_REQUIRED ATTRIBUTE_NONNULL(1) # endif @@ -120,6 +142,18 @@ void * virObjectRWLockableNew(virClassPtr klass) ATTRIBUTE_NONNULL(1); =20 +typedef enum { + VIR_OBJECT_LOOKUP_HASH_UUID =3D (1 << 0), + VIR_OBJECT_LOOKUP_HASH_NAME =3D (1 << 1), +} virObjectLookupHashNewFlags; + +void * +virObjectLookupHashNew(virClassPtr klass, + int tableElemsStart, + virObjectLookupHashNewFlags flags) + + ATTRIBUTE_NONNULL(1); + void virObjectLock(void *lockableobj) ATTRIBUTE_NONNULL(1); --=20 2.9.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list