https://bugzilla.redhat.com/show_bug.cgi?id=1264008
The existing algorithm assumed that someone was making small, incremental
changes; however, it is possible to change iothreads from 0 (or relatively
small number) to some really large number and the algorithm would possibly
spin its wheels doing unnecessary searches.
So, optimize the algorithm using a bitmap to find available iothread_id's
starting at 1 that aren't already defined by a "<thread
id='#'>" and
filling in the iothreadids array with those iothread_id values.
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
src/conf/domain_conf.c | 39 +++++++++++++++++++++++++++++++--------
1 file changed, 31 insertions(+), 8 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 70b2afc..3e15dcc 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2332,8 +2332,11 @@ virDomainIOThreadIDDefArrayFree(virDomainIOThreadIDDefPtr *def,
static int
virDomainIOThreadIDDefArrayInit(virDomainDefPtr def)
{
- unsigned int iothread_id = 1;
int retval = -1;
+ size_t i;
+ ssize_t nxt = -1;
+ virDomainIOThreadIDDefPtr iothrid = NULL;
+ virBitmapPtr thrmap = NULL;
/* Same value (either 0 or some number), then we have none to fill in or
* the iothreadid array was filled from the XML
@@ -2341,19 +2344,39 @@ virDomainIOThreadIDDefArrayInit(virDomainDefPtr def)
if (def->iothreads == def->niothreadids)
return 0;
- while (def->niothreadids != def->iothreads) {
- if (!virDomainIOThreadIDFind(def, iothread_id)) {
- virDomainIOThreadIDDefPtr iothrid;
+ /* iothread's are numbered starting at 1, account for that */
+ thrmap = virBitmapNew(def->iothreads + 1);
+ virBitmapSetAll(thrmap);
- if (!(iothrid = virDomainIOThreadIDAdd(def, iothread_id)))
- goto error;
- iothrid->autofill = true;
+ /* Clear 0 since we don't use it, then mark those which are
+ * already provided by the user */
+ ignore_value(virBitmapClearBit(thrmap, 0));
+ for (i = 0; i < def->niothreadids; i++)
+ ignore_value(virBitmapClearBit(thrmap,
+ def->iothreadids[i]->iothread_id));
+
+ /* resize array */
+ if (VIR_REALLOC_N(def->iothreadids, def->iothreads) < 0)
+ goto error;
+
+ /* Populate iothreadids[] using the set bit number from thrmap */
+ while (def->niothreadids < def->iothreads) {
+ if ((nxt = virBitmapNextSetBit(thrmap, nxt)) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("failed to populate iothreadids"));
+ goto error;
}
- iothread_id++;
+ if (VIR_ALLOC(iothrid) < 0)
+ goto error;
+ iothrid->iothread_id = nxt;
+ iothrid->autofill = true;
+ def->iothreadids[def->niothreadids++] = iothrid;
}
+
retval = 0;
error:
+ virBitmapFree(thrmap);
return retval;
}
--
2.1.0