virJSONValueCopy: Don't use virJSONValue(Object|Array)Append

We know the exact number of keys or array members for the copied objects
so we can pre-allocate the arrays rather than inserting into them in a
loop incurring realloc copy penalty.

Also virJSONValueCopy now can't fail since all of the functions
allocating the different cases use just g_new/g_strdup internally so we
can remove the NULL checks from the recursive calls.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Peter Krempa 2021-02-12 10:44:49 +01:00
parent b116e715a8
commit 3e411cbc5f

View File

@ -1530,27 +1530,23 @@ virJSONValueCopy(const virJSONValue *in)
switch ((virJSONType) in->type) {
case VIR_JSON_TYPE_OBJECT:
out = virJSONValueNewObject();
out->data.object.pairs = g_new0(virJSONObjectPair, in->data.object.npairs);
out->data.object.npairs = in->data.object.npairs;
for (i = 0; i < in->data.object.npairs; i++) {
virJSONValuePtr val = NULL;
if (!(val = virJSONValueCopy(in->data.object.pairs[i].value)))
goto error;
if (virJSONValueObjectAppend(out, in->data.object.pairs[i].key,
val) < 0) {
virJSONValueFree(val);
goto error;
}
out->data.object.pairs[i].key = g_strdup(in->data.object.pairs[i].key);
out->data.object.pairs[i].value = virJSONValueCopy(in->data.object.pairs[i].value);
}
break;
case VIR_JSON_TYPE_ARRAY:
out = virJSONValueNewArray();
out->data.array.values = g_new0(virJSONValuePtr, in->data.array.nvalues);
out->data.array.nvalues = in->data.array.nvalues;
for (i = 0; i < in->data.array.nvalues; i++) {
virJSONValuePtr val = NULL;
if (!(val = virJSONValueCopy(in->data.array.values[i])))
goto error;
if (virJSONValueArrayAppend(out, val) < 0) {
virJSONValueFree(val);
goto error;
}
out->data.array.values[i] = virJSONValueCopy(in->data.array.values[i]);
}
break;
@ -1570,10 +1566,6 @@ virJSONValueCopy(const virJSONValue *in)
}
return out;
error:
virJSONValueFree(out);
return NULL;
}