/* Web Polygraph       http://www.web-polygraph.org/
 * (C) 2003-2006 The Measurement Factory
 * Licensed under the Apache License, Version 2.0 */

#include "base/polygraph.h"

#include "xml/XmlText.h"
#include "xml/XmlParagraph.h"
#include "loganalyzers/ReportBlob.h"
#include "loganalyzers/PhaseInfo.h"
#include "loganalyzers/Stex.h"


Stex::Stex(const String &aKey, const String &aName): theKey(aKey), theName(aName), theParent(0) {
}

Stex::~Stex() {
}

void Stex::parent(const Stex *aParent) {
	Assert(!theParent || !aParent);
	theParent = aParent;
}

const TmSzStat *Stex::aggr(const PhaseInfo &phase) const {
	return trace(phase.availStats());
}

void Stex::describe(XmlNodes &nodes) const {
	nodes << XmlTextTag<XmlParagraph>("No description is available for "
		"this object class.");
	describeParent(nodes);
}

void Stex::describeParent(XmlNodes &nodes) const {
	if (parent()) {
		XmlTextTag<XmlParagraph> text;
		text.buf() << "This object class belongs to the '"
			<< parent()->name() << "' class.";
		nodes << text;
	}
}


/* HitsStex */

HitsStex::HitsStex(const String &aKey, const String &aName):
	Stex(aKey, aName) {
}

const TmSzHistStat *HitsStex::hist(const PhaseInfo &phase) const {
	return phase.hasStats() ? &phase.stats().theBasicXacts.hits() : 0;
}

const TmSzStat *HitsStex::trace(const StatIntvlRec &rec) const {
	return &rec.theRealHR.hits();
}

void HitsStex::describe(XmlNodes &nodes) const {
	Stex::describe(nodes);
}


/* MissesStex */

MissesStex::MissesStex(const String &aKey, const String &aName):
	Stex(aKey, aName) {
}

const TmSzHistStat *MissesStex::hist(const PhaseInfo &phase) const {
	return phase.hasStats() ? &phase.stats().theBasicXacts.misses() : 0;
}

const TmSzStat *MissesStex::trace(const StatIntvlRec &rec) const {
	return &rec.theRealHR.misses();
}

void MissesStex::describe(XmlNodes &nodes) const {
	Stex::describe(nodes);
}


/* HitMissesStex */

HitMissesStex::HitMissesStex(const String &aKey, const String &aName):
	Stex(aKey, aName) {
}

const TmSzHistStat *HitMissesStex::hist(const PhaseInfo &phase) const {
	if (phase.hasStats()) {
		theXactHist.reset();
		theXactHist = phase.stats().theBasicXacts.hits();
		theXactHist += phase.stats().theBasicXacts.misses();
		return &theXactHist;
	} else {
		return 0;
	}
}

const TmSzStat *HitMissesStex::trace(const StatIntvlRec &rec) const {
	theXactAggr = rec.theRealHR.xacts();
	return &theXactAggr;
}

void HitMissesStex::describe(XmlNodes &nodes) const {
	Stex::describe(nodes);
}


/* Ims200Stex */

Ims200Stex::Ims200Stex(const String &aKey, const String &aName):
	Stex(aKey, aName) {
}

const TmSzStat *Ims200Stex::aggr(const PhaseInfo &phase) const {
	if (phase.hasStats()) {
		theXactAggr = phase.stats().theImsXacts.hits().aggr();
		return &theXactAggr;
	} else {
		return 0;
	}
}

const TmSzHistStat *Ims200Stex::hist(const PhaseInfo &phase) const {
	return phase.hasStats() ? &phase.stats().theImsXacts.hits() : 0;
}

void Ims200Stex::describe(XmlNodes &nodes) const {
	Stex::describe(nodes);
}


/* Ims304Stex */

Ims304Stex::Ims304Stex(const String &aKey, const String &aName):
	Stex(aKey, aName) {
}

const TmSzStat *Ims304Stex::aggr(const PhaseInfo &phase) const {
	if (phase.hasStats()) {
		theXactAggr = phase.stats().theImsXacts.misses().aggr();
		return &theXactAggr;
	} else {
		return 0;
	}
}

const TmSzHistStat *Ims304Stex::hist(const PhaseInfo &phase) const {
	return phase.hasStats() ? &phase.stats().theImsXacts.misses() : 0;
}

void Ims304Stex::describe(XmlNodes &nodes) const {
	Stex::describe(nodes);
}


/* ImsStex */

ImsStex::ImsStex(const String &aKey, const String &aName):
	Stex(aKey, aName) {
}

const TmSzHistStat *ImsStex::hist(const PhaseInfo &phase) const {
	if (phase.hasStats()) {
		theXactHist.reset();
		theXactHist = phase.stats().theImsXacts.hits();
		theXactHist += phase.stats().theImsXacts.misses();
		return &theXactHist;
	} else {
		return 0;
	}
}

const TmSzStat *ImsStex::trace(const StatIntvlRec &rec) const {
	return &rec.theIms;
}

void ImsStex::describe(XmlNodes &nodes) const {
	Stex::describe(nodes);
}


/* CachableStex */

CachableStex::CachableStex(const String &aKey, const String &aName):
	Stex(aKey, aName) {
}

const TmSzStat *CachableStex::trace(const StatIntvlRec &rec) const {
	return &rec.theChbR.hits();
}

void CachableStex::describe(XmlNodes &nodes) const {
	Stex::describe(nodes);
}


/* UnCachableStex */

UnCachableStex::UnCachableStex(const String &aKey, const String &aName):
	Stex(aKey, aName) {
}

const TmSzStat *UnCachableStex::trace(const StatIntvlRec &rec) const {
	return &rec.theChbR.misses();
}

void UnCachableStex::describe(XmlNodes &nodes) const {
	Stex::describe(nodes);
}


/* AllCachableStex */

AllCachableStex::AllCachableStex(const String &aKey, const String &aName):
	Stex(aKey, aName) {
}

const TmSzStat *AllCachableStex::trace(const StatIntvlRec &rec) const {
	theXactAggr = rec.theChbR.xacts();
	return &theXactAggr;
}

void AllCachableStex::describe(XmlNodes &nodes) const {
	Stex::describe(nodes);
}


/* FillStex */

FillStex::FillStex(const String &aKey, const String &aName):
	Stex(aKey, aName) {
}

const TmSzStat *FillStex::trace(const StatIntvlRec &rec) const {
	return &rec.theFill;
}

void FillStex::describe(XmlNodes &nodes) const {
	Stex::describe(nodes);
}


/* SimpleStex */

SimpleStex::SimpleStex(const String &aKey, const String &aName, HistPtr aHist, TracePtr aTrace):
	Stex(aKey, aName), theHist(aHist), theTrace(aTrace) {
}

const TmSzHistStat *SimpleStex::hist(const PhaseInfo &phase) const {
	return theHist && phase.hasStats() ? &(phase.stats().*theHist) : 0;
}

const TmSzStat *SimpleStex::trace(const StatIntvlRec &rec) const {
	return theTrace ? &(rec.*theTrace) : 0;
}

void SimpleStex::describe(XmlNodes &nodes) const {
	Stex::describe(nodes);
}


/* AllMethodsStex */

AllMethodsStex::AllMethodsStex(const String &aKey, const String &aName):
	Stex(aKey, aName) {
}

const TmSzHistStat *AllMethodsStex::hist(const PhaseInfo &phase) const {
	if (phase.hasStats()) {
		theXactHist.reset();
		theXactHist += phase.stats().theHeadXacts;
		theXactHist += phase.stats().thePostXacts;
		theXactHist += phase.stats().thePutXacts;
		return &theXactHist;
	} else {
		return 0;
	}
}

const TmSzStat *AllMethodsStex::trace(const StatIntvlRec &rec) const {
	theXactAggr = rec.theHead + rec.thePost + rec.thePut;
	return &theXactAggr;
}

void AllMethodsStex::describe(XmlNodes &nodes) const {
	Stex::describe(nodes);
}


/* AllRepsStex */

AllRepsStex::AllRepsStex(const String &aKey, const String &aName):
	Stex(aKey, aName) {
}

const TmSzHistStat *AllRepsStex::hist(const PhaseInfo &phase) const {
	if (phase.hasStats()) {
		theXactHist.reset();
		phase.stats().repAll(theXactHist);
		return &theXactHist;
	} else {
		return 0;
	}
}

const TmSzStat *AllRepsStex::trace(const StatIntvlRec &rec) const {
	theXactAggr = rec.reps();
	return &theXactAggr;
}

void AllRepsStex::describe(XmlNodes &nodes) const {
	Stex::describe(nodes);
}


/* ContTypeStex */

ContTypeStex::ContTypeStex(const String &aKey, const String &aName, int anIdx):
	Stex(aKey, aName), theIdx(anIdx) {
}

const TmSzStat *ContTypeStex::aggr(const PhaseInfo &phase) const {
	if (phase.hasStats() && phase.stats().theContType.hasStats(theIdx)) {
		theXactAggr = TmSzStat(AggrStat(), 
			phase.stats().theContType.stats(theIdx));
		return &theXactAggr;
	} else {
		return 0;
	}
}

void ContTypeStex::describe(XmlNodes &nodes) const {
	XmlText text;
	text.buf() << "This object class represents one of the "
		<< "content types specified in the PGL workload file and labeled "
		<< "there as " << name() << '.' << endl;
	nodes << text;
}


/* AllContTypesStex */

AllContTypesStex::AllContTypesStex(const String &aKey, const String &aName):
	Stex(aKey, aName) {
}

const TmSzStat *AllContTypesStex::aggr(const PhaseInfo &phase) const {
	if (phase.hasStats()) {
		AggrStat szStat;
		for (int i = 0; i < ContTypeStat::Kinds().count(); ++i) {
			if (phase.stats().theContType.hasStats(i))
				szStat += phase.stats().theContType.stats(i);
		}
		theXactAggr = TmSzStat(AggrStat(), szStat);
		return &theXactAggr;
	} else { 
		return 0;
	}
}

void AllContTypesStex::describe(XmlNodes &nodes) const {
	Stex::describe(nodes);
}


syntax highlighted by Code2HTML, v. 0.9.1