예제 #1
0
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);
	}
    }
}
예제 #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;
}