[libvirt] [PATCH 1/3] util: Rework virStringListAdd

Erik Skultety eskultet at redhat.com
Fri Jul 27 08:21:17 UTC 2018


On Thu, Jul 26, 2018 at 05:36:27PM +0200, Michal Privoznik wrote:
> So every caller does the same: they use virStringListAdd() to add

^This sounds a bit like there's a handful of them ;).

> new item into the list and then free the old copy to replace it
> with new list. It's not very memory effective, nor environmental
> friendly.
>
> Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
> ---
>  src/util/virmacmap.c  |  8 ++------
>  src/util/virstring.c  | 34 ++++++++++++++--------------------
>  src/util/virstring.h  |  4 ++--
>  tests/virstringtest.c |  6 +-----
>  4 files changed, 19 insertions(+), 33 deletions(-)
>
> diff --git a/src/util/virmacmap.c b/src/util/virmacmap.c
> index 88ca9b3f36..c7b700fa05 100644
> --- a/src/util/virmacmap.c
> +++ b/src/util/virmacmap.c
> @@ -90,7 +90,6 @@ virMacMapAddLocked(virMacMapPtr mgr,
>  {
>      int ret = -1;
>      char **macsList = NULL;
> -    char **newMacsList = NULL;
>
>      if ((macsList = virHashLookup(mgr->macs, domain)) &&
>          virStringListHasString((const char**) macsList, mac)) {
> @@ -98,15 +97,12 @@ virMacMapAddLocked(virMacMapPtr mgr,
>          goto cleanup;
>      }
>
> -    if (!(newMacsList = virStringListAdd((const char **) macsList, mac)) ||
> -        virHashUpdateEntry(mgr->macs, domain, newMacsList) < 0)
> +    if (virStringListAdd(&macsList, mac) < 0 ||
> +        virHashUpdateEntry(mgr->macs, domain, macsList) < 0)
>          goto cleanup;
> -    newMacsList = NULL;
> -    virStringListFree(macsList);
>
>      ret = 0;
>   cleanup:
> -    virStringListFree(newMacsList);
>      return ret;
>  }
>
> diff --git a/src/util/virstring.c b/src/util/virstring.c
> index 93fda69d7f..59f57a97b8 100644
> --- a/src/util/virstring.c
> +++ b/src/util/virstring.c
> @@ -175,32 +175,26 @@ char *virStringListJoin(const char **strings,
>   * @strings: a NULL-terminated array of strings
>   * @item: string to add
>   *
> - * Creates new strings list with all strings duplicated and @item
> - * at the end of the list. Callers is responsible for freeing
> - * both @strings and returned list.
> + * Appends @item into string list @strings. If *@strings is not
> + * allocated yet new string list is created.
> + *
> + * Returns: 0 on success,
> + *         -1 otherwise
>   */
> -char **
> -virStringListAdd(const char **strings,
> +int
> +virStringListAdd(char ***strings,
>                   const char *item)
>  {
> -    char **ret = NULL;
> -    size_t i = virStringListLength(strings);
> +    size_t i = virStringListLength((const char **) *strings);
>
> -    if (VIR_ALLOC_N(ret, i + 2) < 0)
> -        goto error;

This scales linearly, but given the number of "every" caller of this and the
projected frequency of usage, I don't really care about N sentinels.
You could consider VIR_EXPAND_N to get rid of the explicit sentinel assignment
below, your call.

> +    if (VIR_REALLOC_N(*strings, i + 2) < 0)
> +        return -1;
>
> -    for (i = 0; strings && strings[i]; i++) {
> -        if (VIR_STRDUP(ret[i], strings[i]) < 0)
> -            goto error;
> -    }
> +    (*strings)[i + 1] = NULL;
> +    if (VIR_STRDUP((*strings)[i], item) < 0)
> +        return -1;
>
> -    if (VIR_STRDUP(ret[i], item) < 0)
> -        goto error;
> -
> -    return ret;
> - error:
> -    virStringListFree(ret);
> -    return NULL;
> +    return 0;

Reviewed-by: Erik Skultety <eskultet at redhat.com>




More information about the libvir-list mailing list