[libvirt] [PATCH v3 01/15] virNetworkObjListPtr: Turn list into a hash table

Peter Krempa pkrempa at redhat.com
Wed Mar 11 13:17:08 UTC 2015


On Tue, Mar 10, 2015 at 17:45:07 +0100, Michal Privoznik wrote:
> Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
> ---
>  src/conf/network_conf.c | 382 ++++++++++++++++++++++++++++++------------------
>  1 file changed, 237 insertions(+), 145 deletions(-)
> 

...

>  int virNetworkBridgeInUse(virNetworkObjListPtr nets,
>                            const char *bridge,
>                            const char *skipname)
>  {
> -    size_t i;
> -    unsigned int ret = 0;
> +    virNetworkObjPtr obj;
> +    struct virNetworkBridgeInUseHelperData data = {bridge, skipname};
>  
> -    for (i = 0; i < nets->count; i++) {
> -        virNetworkObjLock(nets->objs[i]);
> -        if (nets->objs[i]->def->bridge &&
> -            STREQ(nets->objs[i]->def->bridge, bridge) &&
> -            !(skipname && STREQ(nets->objs[i]->def->name, skipname)))
> -                ret = 1;
> -        virNetworkObjUnlock(nets->objs[i]);
> -    }
> +    obj = virHashSearch(nets->objs, virNetworkBridgeInUseHelper, &data);
>  
> -    return ret;
> +    return obj != NULL;
>  }
>  
>  char *virNetworkAllocateBridge(virNetworkObjListPtr nets,
> @@ -4271,6 +4299,52 @@ virNetworkMatch(virNetworkObjPtr netobj,
>  }
>  #undef MATCH
>  
> +struct virNetworkObjListData {
> +    virConnectPtr conn;
> +    virNetworkPtr *nets;
> +    virNetworkObjListFilter filter;
> +    unsigned int flags;
> +    int nnets;
> +    bool error;
> +};
> +
> +static void
> +virNetworkObjListPopulate(void *payload,
> +                          const void *name ATTRIBUTE_UNUSED,
> +                          void *opaque)
> +{
> +    struct virNetworkObjListData *data = opaque;
> +    virNetworkObjPtr obj = payload;
> +    virNetworkPtr net = NULL;

Similarly to the domain objects this will become problematic once you
drop the driver lock. I'm planing to fix the domain version soon, so
I'll need to update this one too as we don't have any prior art.

> +
> +    if (data->error)
> +        return;
> +
> +    virNetworkObjLock(obj);
> +
> +    if (data->filter &&
> +        !data->filter(data->conn, obj->def))
> +        goto cleanup;
> +
> +    if (!virNetworkMatch(obj, data->flags))
> +        goto cleanup;
> +
> +    if (!data->nets) {
> +        data->nnets++;
> +        goto cleanup;
> +    }
> +
> +    if (!(net = virGetNetwork(data->conn, obj->def->name, obj->def->uuid))) {
> +        data->error = true;
> +        goto cleanup;
> +    }
> +
> +    data->nets[data->nnets++] = net;
> +
> + cleanup:
> +    virNetworkObjUnlock(obj);
> +}
> +

...

> +static int
> +virNetworkObjListPruneHelper(const void *payload,
> +                             const void *name ATTRIBUTE_UNUSED,
> +                             const void *opaque)
> +{
> +    const struct virNetworkObjListPruneHelperData *data = opaque;
> +    virNetworkObjPtr obj = (virNetworkObjPtr) payload;
> +    int want = 0;
> +
> +    virNetworkObjLock(obj);
> +    want = virNetworkMatch(obj, data->flags);
> +    virNetworkObjUnlock(obj);
> +    return want;
>  }
>  
>  /**
> @@ -4428,21 +4534,7 @@ void
>  virNetworkObjListPrune(virNetworkObjListPtr nets,
>                         unsigned int flags)
>  {
> -    size_t i = 0;
> +    struct virNetworkObjListPruneHelperData data = {flags};
>  
> -    while (i < nets->count) {
> -        virNetworkObjPtr obj = nets->objs[i];
> -
> -        virNetworkObjLock(obj);
> -
> -        if (virNetworkMatch(obj, flags)) {
> -            virNetworkObjUnlock(obj);
> -            virNetworkObjFree(obj);
> -
> -            VIR_DELETE_ELEMENT(nets->objs, i, nets->count);
> -        } else {
> -            virNetworkObjUnlock(obj);
> -            i++;
> -        }
> -    }
> +    virHashRemoveSet(nets->objs, virNetworkObjListPruneHelper, &data);
>  }

Now that I've persusaded you to add a function like this you converted
the code to the hash table that supports deletion. Oh well :)

ACK

Peter
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20150311/c56bd17c/attachment-0001.sig>


More information about the libvir-list mailing list