From: Lennart Poettering Date: Tue, 26 Jan 2016 18:49:08 +0000 (+0100) Subject: systemctl: piece-meal strv extension is expensive X-Git-Tag: v229~76^2~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1b53f64b001d2a8acb398eb8d546ec4570c1f235;p=thirdparty%2Fsystemd.git systemctl: piece-meal strv extension is expensive If we have many entries to add to an strv we really should try to be smarter than constantly realloc()ing the strv array. Instead, grow it exponentially. --- diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 94c99c4d91f..73f5710b9cd 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -2658,14 +2658,25 @@ static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***r if (!strv_isempty(globs)) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; _cleanup_free_ UnitInfo *unit_infos = NULL; + size_t allocated, n; r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply); if (r < 0) return r; - for (i = 0; i < r; i++) - if (strv_extend(&mangled, unit_infos[i].id) < 0) + n = strv_length(mangled); + allocated = n + 1; + + for (i = 0; i < r; i++) { + if (!GREEDY_REALLOC(mangled, allocated, n+2)) + return log_oom(); + + mangled[n] = strdup(unit_infos[i].id); + if (!mangled[n]) return log_oom(); + + mangled[++n] = NULL; + } } *ret = mangled;