示例#1
0
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();
    }
}
示例#2
0
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;
}