void QmcMetric::setupIndom(pmMetricSpec *metricSpec) { int i, j; QmcIndom *indomPtr = indom(); if (!hasIndom()) { if (metricSpec->ninst > 0) { my.status = PM_ERR_INST; dumpErr(metricSpec->inst[0]); } else setupValues(1); } else if (metricSpec->ninst) { Q_ASSERT(hasInstances()); setupValues(metricSpec->ninst); for (i = 0 ; i < metricSpec->ninst && my.status >= 0; i++) { j = indomPtr->lookup(metricSpec->inst[i]); if (j >= 0) my.values[i].setInstance(j); else { my.status = PM_ERR_INST; my.values[i].setInstance(PM_ERR_INST); dumpErr(metricSpec->inst[i]); } } my.explicitInst = true; } else { Q_ASSERT(hasInstances()); if (my.active) { setupValues(indomPtr->numActiveInsts()); indomPtr->refAll(my.active); for (i = 0, j = 0; i < indomPtr->listLen(); i++) if (!indomPtr->nullInst(i) && indomPtr->activeInst(i)) my.values[j++].setInstance(i); } else { setupValues(indomPtr->numInsts()); indomPtr->refAll(my.active); for (i = 0, j = 0; i < indomPtr->listLen(); i++) if (!indomPtr->nullInst(i)) my.values[j++].setInstance(i); } } }
bool QmcMetric::updateIndom(void) { int i = 0, j, oldNum = numInst(), newNum, newInst; QmcIndom *indomPtr = indom(); if (status() < 0 || !hasIndom()) return false; if (indomPtr->changed()) indomPtr->update(); my.explicitInst = false; newNum = my.active ? indomPtr->numActiveInsts() : indomPtr->numInsts(); // If the number of instances are the same then we know that no // modifications to the metric instance list is required as these // instances are all referenced in the indom // // If the instance list is only active instances, then we need to // check all the instances as the number may be the same // if (newNum == oldNum) { if (my.active) { for (i = 0; i < my.values.size(); i++) if (!indomPtr->activeInst(my.values[i].instance())) break; } if (!my.active || i == my.values.size()) { if (pmDebug & DBG_TRACE_INDOM) { QTextStream cerr(stderr); cerr << "QmcMetric::updateIndom: No change required" << endl; } return false; } } // Duplicate the current values // Replace the old index into the indom instance list with the // internal instance identifiers so that these can be correlated // if the order of instances changes QList<QmcMetricValue> oldValues = my.values; for (i = 0; i < oldNum; i++) { oldValues[i].setInstance(indomPtr->inst(my.values[i].instance())); indomPtr->removeRef(my.values[i].instance()); } setupValues(newNum); indomPtr->refAll(my.active); if (my.active) { for (i = 0, j = 0; i < indomPtr->listLen(); i++) if (!indomPtr->nullInst(i) && indomPtr->activeInst(i)) my.values[j++].setInstance(i); } else { for (i = 0, j = 0; i < indomPtr->listLen(); i++) if (!indomPtr->nullInst(i)) my.values[j++].setInstance(i); } // Copy values of instances that have not gone away // Note that their position may have changed for (i = 0; i < my.values.size(); i++) { if (i < oldValues.size() && indomPtr->inst(my.values[i].instance()) == oldValues[i].instance()) { newInst = my.values[i].instance(); my.values[i] = oldValues[i]; my.values[i].setInstance(newInst); continue; } for (j = 0; j < oldValues.size(); j++) if (indomPtr->inst(my.values[i].instance()) == oldValues[j].instance()) { newInst = my.values[i].instance(); my.values[i] = oldValues[j]; my.values[i].setInstance(newInst); break; } // Need to set all error flags to avoid problems with rate conversion if (j == oldValues.size()) my.values[i].setAllErrors(PM_ERR_VALUE); } if (pmDebug & DBG_TRACE_PMC) { QTextStream cerr(stderr); cerr << "QmcMetric::updateIndom: " << spec(true) << ": Had " << oldNum << " instances, now have " << numInst() << endl; } indomPtr->update(); return true; }