void QmcMetric::extractValues(pmValueSet const* set) { int i, j, index, inst; pmValue const *value = NULL; bool found; QmcIndom *indomPtr = indom(); Q_ASSERT(set->pmid == desc().id()); if (set->numval > 0) { if (hasIndom()) { // If the number of instances are not the expected number // then mark the indom as changed if (!my.explicitInst && (my.values.size() != set->numval)) { if (pmDebug & DBG_TRACE_INDOM) { QTextStream cerr(stderr); cerr << "QmcMetric::extractValues: implicit indom " << pmInDomStr(indomPtr->id()) << " changed (" << set->numval << " != " << my.values.size() << ')' << endl; } indomPtr->hasChanged(); updateIndom(); } for (i = 0; i < numInst(); i++) { QmcMetricValue &valueRef = my.values[i]; inst = my.values[i].instance(); index = indomPtr->index(inst); found = false; // If the index is within range, try it first if (index >= 0 && index < set->numval) { value = &(set->vlist[index]); // Found it in the same spot as last time if (value->inst == indomPtr->inst(inst)) found = true; } // Search for it from the top for (j = 0; found == false && j < set->numval; j++) { if (set->vlist[j].inst == indomPtr->inst(inst)) { index = j; value = &(set->vlist[j]); indomPtr->setIndex(inst, j); found = true; } } if (found) { if (real()) extractNumericMetric(set, value, valueRef); else if (!event()) extractArrayMetric(set, value, valueRef); else extractEventMetric(set, index, valueRef); } else { // Cannot find it if (pmDebug & DBG_TRACE_OPTFETCH) { QTextStream cerr(stderr); cerr << "QmcMetric::extractValues: " << spec(true, true, i) << ": " << pmErrStr(PM_ERR_VALUE) << endl; } if (valueRef.previousError() != PM_ERR_VALUE) indomPtr->hasChanged(); valueRef.setCurrentError(PM_ERR_VALUE); } } } else if (set->numval == 1) { // We have no instances at this point in time if (my.values.size() == 0 && hasInstances()) indomPtr->hasChanged(); else { QmcMetricValue &valueRef = my.values[0]; value = &(set->vlist[0]); if (real()) extractNumericMetric(set, value, valueRef); else if (!event()) extractArrayMetric(set, value, valueRef); else extractEventMetric(set, 0, valueRef); } } else { // Did not expect any instances if (pmDebug & DBG_TRACE_OPTFETCH) { QTextStream cerr(stderr); cerr << "QmcMetric::extractValues: " << spec(true) << " is a singular metric but result contained " << set->numval << " values" << endl; } setError(PM_ERR_VALUE); } } else if (set->numval == 0) { if (!(hasInstances() && numInst() == 0)) { if (pmDebug & DBG_TRACE_OPTFETCH) { QTextStream cerr(stderr); cerr << "QmcMetric::extractValues: numval == 0: " << spec(true, false) << ": " << pmErrStr(PM_ERR_VALUE) << endl; } setError(PM_ERR_VALUE); if (hasInstances()) indomPtr->hasChanged(); } } else { if (pmDebug & DBG_TRACE_OPTFETCH) { QTextStream cerr(stderr); cerr << "QmcMetric::extractValues: numval < 0: " << spec(true, false) << ": " << pmErrStr(set->numval) << endl; } setError(set->numval); if (hasInstances()) indomPtr->hasChanged(); } }
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; }