[libvirt] [PATCH v6 3/4] nodedev: Convert virNodeDeviceObjListPtr to use hash tables

John Ferlan jferlan at redhat.com
Mon Jul 24 12:07:04 UTC 2017



On 07/24/2017 03:52 AM, Erik Skultety wrote:
> On Thu, Jul 20, 2017 at 10:08:14AM -0400, John Ferlan wrote:
>> Rather than use a forward linked list of elements, it'll be much more
>> efficient to use a hash table to reference the elements by unique name
>> and to perform hash searches.
>>
>> This patch does all the heavy lifting of converting the list object to
>> use a self locking list that contains the hash table. Each of the FindBy
>> functions that do not involve finding the object by it's key (name) is
>> converted to use virHashSearch in order to find the specific object.
>> When searching for the key (name), it's possible to use virHashLookup.
>> For any of the list perusal functions that are required to evaluate
>> each object, the virHashForEach function is used.
>>
>> Signed-off-by: John Ferlan <jferlan at redhat.com>
>> ---
>>  src/conf/virnodedeviceobj.c | 575 ++++++++++++++++++++++++++++++--------------
>>  1 file changed, 400 insertions(+), 175 deletions(-)
>>
>> diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c
>> index 035a56d..58481e7 100644
>> --- a/src/conf/virnodedeviceobj.c
>> +++ b/src/conf/virnodedeviceobj.c
>> @@ -25,6 +25,7 @@
>>  #include "viralloc.h"
>>  #include "virnodedeviceobj.h"
>>  #include "virerror.h"
>> +#include "virhash.h"
>>  #include "virlog.h"
>>  #include "virstring.h"
>>
>> @@ -39,13 +40,19 @@ struct _virNodeDeviceObj {
>>  };
>>
>>  struct _virNodeDeviceObjList {
>> -    size_t count;
>> -    virNodeDeviceObjPtr *objs;
>> +    virObjectLockable parent;
>> +
>> +    /* name string -> virNodeDeviceObj  mapping
>> +     * for O(1), lockless lookup-by-uuid */
>> +    virHashTable *objs;
>> +
>>  };
>>
>>
>>  static virClassPtr virNodeDeviceObjClass;
>> +static virClassPtr virNodeDeviceObjListClass;
>>  static void virNodeDeviceObjDispose(void *opaque);
>> +static void virNodeDeviceObjListDispose(void *opaque);
>>
>>  static int
>>  virNodeDeviceObjOnceInit(void)
>> @@ -56,6 +63,12 @@ virNodeDeviceObjOnceInit(void)
>>                                                virNodeDeviceObjDispose)))
>>          return -1;
>>
>> +    if (!(virNodeDeviceObjListClass = virClassNew(virClassForObjectLockable(),
>> +                                                  "virNodeDeviceObjList",
>> +                                                  sizeof(virNodeDeviceObjList),
>> +                                                  virNodeDeviceObjListDispose)))
>> +        return -1;
>> +
>>      return 0;
>>  }
>>
>> @@ -211,26 +224,49 @@ virNodeDeviceFindVPORTCapDef(const virNodeDeviceObj *obj)
>>  }
>>
>>
>> +static int
>> +virNodeDeviceObjListFindBySysfsPathCallback(const void *payload,
>> +                                            const void *name ATTRIBUTE_UNUSED,
>> +                                            const void *opaque)
>> +{
>> +    virNodeDeviceObjPtr obj = (virNodeDeviceObjPtr) payload;
>> +    virNodeDeviceDefPtr def;
> 
> As we discussed in v5, I'd like you to drop ^these @def (and only @def...)
> declarations and usages across the whole patch for the reasons I already
> mentioned - it makes sense in general, but it's not very useful in this
> specific case.
> 

<sigh> OK, I really do dislike the obj->def->X syntax "just" for a few
functions while others use the @def nomenclature.

>> +    const char *sysfs_path = opaque;
>> +    int want = 0;
>> +
>> +    virObjectLock(obj);
>> +    def = obj->def;
> 
> ...
> 
>>  virNodeDeviceObjPtr
>>  virNodeDeviceObjListFindBySysfsPath(virNodeDeviceObjListPtr devs,
>>                                      const char *sysfs_path)
>>  {
>> -    size_t i;
>> +    virNodeDeviceObjPtr obj;
>>
>> -    for (i = 0; i < devs->count; i++) {
>> -        virNodeDeviceObjPtr obj = devs->objs[i];
>> -        virNodeDeviceDefPtr def;
>> +    virObjectLock(devs);
>> +    obj = virHashSearch(devs->objs, virNodeDeviceObjListFindBySysfsPathCallback,
>> +                        (void *)sysfs_path, NULL);
>> +    virObjectRef(obj);
>> +    virObjectUnlock(devs);
>>
>> +    if (obj)
>>          virObjectLock(obj);
>> -        def = obj->def;
>> -        if ((def->sysfs_path != NULL) &&
>> -            (STREQ(def->sysfs_path, sysfs_path))) {
>> -            return virObjectRef(obj);
>> -        }
>> -        virObjectUnlock(obj);
>> -    }
>>
>> -    return NULL;
>> +    return obj;
> 
> With reference to v5:
> The fact that creating a helper wasn't met with an agreement from the
> reviewer's side in one case doesn't mean it doesn't make sense to do in an
> other case, like this one. So, what I actually meant by creating a helper for:
> 
> BySysfsPath
> ByWWNs
> ByFabricWWN
> ByCap
> ByCapSCSIByWWNs
> 
> is just simply move the lock and search logic to a separate function, that's
> all, see my attached patch. And then, as you suggested in your v5 response to
> this patch, we can move from here (my patch included) and potentially do some
> more refactoring.

Replies don't include your patch; however, I will note if you jump to
patch 13:

https://www.redhat.com/archives/libvir-list/2017-June/msg00929.html

of the virObject series I posted last month:

https://www.redhat.com/archives/libvir-list/2017-June/msg00916.html

that you'll see that is the direction this would be headed anyway. I can
do this sooner that's fine, although I prefer the name
virNodeDeviceObjListSearch as opposed to virNodeDeviceObjListFindHelper.

Ironically though you didn't like the @def usage, still you chose
virHashSearcher cb = $functionName which has one use to be used as an
argument to the function even though $functionName could be used
directly in the call. The only advantage of @cb is that it reduces the
line length of the call.

John

> 
> ACK if you move the lock-search-ref-unlock-return snippets to a separate
> function for the cases mentioned above.
> 
> Erik
> 




More information about the libvir-list mailing list