From fb74987c522a141b2f61d303377453cbbfae0788 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 23 Feb 2009 12:22:15 -0800 Subject: [PATCH] stats: Try to make the names of things more intuitive. Basically, this means renaming several things called data to info, which is information about the statistics. Things that are named data now are actual data stored for the statistic. --- src/base/statistics.cc | 74 +++++------ src/base/statistics.hh | 263 +++++++++++++++++++++------------------ src/base/stats/mysql.cc | 211 ++++++++++++++++--------------- src/base/stats/mysql.hh | 42 +++---- src/base/stats/statdb.cc | 6 +- src/base/stats/statdb.hh | 10 +- src/base/stats/text.cc | 182 +++++++++++++-------------- src/base/stats/text.hh | 14 +-- src/base/stats/visit.hh | 28 ++--- 9 files changed, 422 insertions(+), 408 deletions(-) diff --git a/src/base/statistics.cc b/src/base/statistics.cc index cf2e6d4e7..93c1742b0 100644 --- a/src/base/statistics.cc +++ b/src/base/statistics.cc @@ -48,65 +48,59 @@ using namespace std; namespace Stats { -StatData * -DataAccess::find() const +Info * +InfoAccess::find() const { return Database::find(const_cast((const void *)this)); } -const StatData * -getStatData(const void *stat) +const Info * +getInfo(const void *stat) { return Database::find(const_cast(stat)); } void -DataAccess::map(StatData *data) +InfoAccess::setInfo(Info *info) { - Database::regStat(this, data); + Database::regStat(this, info); } -StatData * -DataAccess::statData() -{ - StatData *ptr = find(); - assert(ptr); - return ptr; -} - -const StatData * -DataAccess::statData() const +void +InfoAccess::setInit() { - const StatData *ptr = find(); - assert(ptr); - return ptr; + info()->flags |= init; } -void -DataAccess::setInit() +Info * +InfoAccess::info() { - statData()->flags |= init; + Info *info = find(); + assert(info); + return info; } -void -DataAccess::setPrint() +const Info * +InfoAccess::info() const { - Database::regPrint(this); + const Info *info = find(); + assert(info); + return info; } -StatData::StatData() +Info::Info() : flags(none), precision(-1), prereq(0) { static int count = 0; id = count++; } -StatData::~StatData() +Info::~Info() { } bool -StatData::less(StatData *stat1, StatData *stat2) +Info::less(Info *stat1, Info *stat2) { const string &name1 = stat1->name; const string &name2 = stat2->name; @@ -132,7 +126,7 @@ StatData::less(StatData *stat1, StatData *stat2) } bool -StatData::baseCheck() const +Info::baseCheck() const { if (!(flags & init)) { #ifdef DEBUG @@ -190,7 +184,7 @@ FormulaBase::zero() const } void -FormulaBase::update(StatData *) +FormulaBase::update(Info *) { } @@ -238,20 +232,20 @@ check() iter_t i, end = Database::stats().end(); for (i = Database::stats().begin(); i != end; ++i) { - StatData *data = *i; - assert(data); - if (!data->check() || !data->baseCheck()) - panic("stat check failed for %s\n", data->name); + Info *info = *i; + assert(info); + if (!info->check() || !info->baseCheck()) + panic("stat check failed for %s\n", info->name); } off_t j = 0; for (i = Database::stats().begin(); i != end; ++i) { - StatData *data = *i; - if (!(data->flags & print)) - data->name = "__Stat" + to_string(j++); + Info *info = *i; + if (!(info->flags & print)) + info->name = "__Stat" + to_string(j++); } - Database::stats().sort(StatData::less); + Database::stats().sort(Info::less); if (i == end) return; @@ -275,8 +269,8 @@ reset() Database::stat_list_t::iterator i = Database::stats().begin(); Database::stat_list_t::iterator end = Database::stats().end(); while (i != end) { - StatData *data = *i; - data->reset(); + Info *info = *i; + info->reset(); ++i; } diff --git a/src/base/statistics.hh b/src/base/statistics.hh index d50302d49..0bc770899 100644 --- a/src/base/statistics.hh +++ b/src/base/statistics.hh @@ -26,7 +26,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Nathan Binkert - * Erik Hallnor */ /** @file @@ -60,6 +59,7 @@ #include #include +#include "base/cast.hh" #include "base/cprintf.hh" #include "base/intmath.hh" #include "base/refcnt.hh" @@ -85,8 +85,9 @@ typedef std::numeric_limits CounterLimits; // Statistics Framework Base classes // ////////////////////////////////////////////////////////////////////// -struct StatData +class Info { + public: /** The name of the stat. */ std::string name; /** The description of the stat. */ @@ -96,15 +97,16 @@ struct StatData /** The display precision. */ int precision; /** A pointer to a prerequisite Stat. */ - const StatData *prereq; + const Info *prereq; /** * A unique stat ID for each stat in the simulator. * Can be used externally for lookups as well as for debugging. */ int id; - StatData(); - virtual ~StatData(); + public: + Info(); + virtual ~Info(); /** * Reset the corresponding stat to the default state. @@ -138,10 +140,10 @@ struct StatData * @param stat2 The second stat. * @return stat1's name is alphabetically before stat2's */ - static bool less(StatData *stat1, StatData *stat2); + static bool less(Info *stat1, Info *stat2); }; -class ScalarData : public StatData +class ScalarInfoBase : public Info { public: virtual Counter value() const = 0; @@ -151,13 +153,13 @@ class ScalarData : public StatData }; template -class ScalarStatData : public ScalarData +class ScalarInfo : public ScalarInfoBase { protected: Stat &s; public: - ScalarStatData(Stat &stat) : s(stat) {} + ScalarInfo(Stat &stat) : s(stat) {} virtual bool check() const { return s.check(); } virtual Counter value() const { return s.value(); } @@ -167,12 +169,14 @@ class ScalarStatData : public ScalarData virtual bool zero() const { return s.zero(); } }; -struct VectorData : public StatData +class VectorInfoBase : public Info { + public: /** Names and descriptions of subfields. */ mutable std::vector subnames; mutable std::vector subdescs; + public: virtual size_type size() const = 0; virtual const VCounter &value() const = 0; virtual const VResult &result() const = 0; @@ -193,7 +197,7 @@ struct VectorData : public StatData }; template -class VectorStatData : public VectorData +class VectorInfo : public VectorInfoBase { protected: Stat &s; @@ -201,7 +205,7 @@ class VectorStatData : public VectorData mutable VResult rvec; public: - VectorStatData(Stat &stat) : s(stat) {} + VectorInfo(Stat &stat) : s(stat) {} virtual bool check() const { return s.check(); } virtual bool zero() const { return s.zero(); } @@ -234,7 +238,7 @@ class VectorStatData : public VectorData } }; -struct DistDataData +struct DistData { Counter min_val; Counter max_val; @@ -252,20 +256,21 @@ struct DistDataData bool fancy; }; -struct DistData : public StatData +class DistInfoBase : public Info { + public: /** Local storage for the entry values, used for printing. */ - DistDataData data; + DistData data; }; template -class DistStatData : public DistData +class DistInfo : public DistInfoBase { protected: Stat &s; public: - DistStatData(Stat &stat) : s(stat) {} + DistInfo(Stat &stat) : s(stat) {} virtual bool check() const { return s.check(); } virtual void reset() { s.reset(); } @@ -279,17 +284,20 @@ class DistStatData : public DistData } }; -struct VectorDistData : public StatData +class VectorDistInfoBase : public Info { - std::vector data; + public: + std::vector data; /** Names and descriptions of subfields. */ mutable std::vector subnames; mutable std::vector subdescs; + protected: /** Local storage for the entry values, used for printing. */ mutable VResult rvec; + public: virtual size_type size() const = 0; void @@ -305,13 +313,13 @@ struct VectorDistData : public StatData }; template -class VectorDistStatData : public VectorDistData +class VectorDistInfo : public VectorDistInfoBase { protected: Stat &s; public: - VectorDistStatData(Stat &stat) : s(stat) {} + VectorDistInfo(Stat &stat) : s(stat) {} virtual bool check() const { return s.check(); } virtual void reset() { s.reset(); } @@ -327,8 +335,9 @@ class VectorDistStatData : public VectorDistData } }; -struct Vector2dData : public StatData +class Vector2dInfoBase : public Info { + public: /** Names and descriptions of subfields. */ std::vector subnames; std::vector subdescs; @@ -339,6 +348,7 @@ struct Vector2dData : public StatData mutable size_type x; mutable size_type y; + public: void update() { @@ -348,13 +358,13 @@ struct Vector2dData : public StatData }; template -class Vector2dStatData : public Vector2dData +class Vector2dInfo : public Vector2dInfoBase { protected: Stat &s; public: - Vector2dStatData(Stat &stat) : s(stat) {} + Vector2dInfo(Stat &stat) : s(stat) {} virtual bool check() const { return s.check(); } virtual void reset() { s.reset(); } @@ -369,43 +379,42 @@ class Vector2dStatData : public Vector2dData } }; -class DataAccess +class InfoAccess { protected: - StatData *find() const; - void map(StatData *data); - - StatData *statData(); - const StatData *statData() const; - + Info *find() const; + /** Set up an info class for this statistic */ + void setInfo(Info *info); + /** Save Storage class parameters if any */ void setInit(); - void setPrint(); + + Info *info(); + const Info *info() const; }; -template class Data> +template class Info> class Wrap : public Child { + public: + typedef Parent ParentType; + typedef Child ChildType; + typedef Info InfoType; + protected: Parent &self() { return *reinterpret_cast(this); } protected: - Data * - statData() + InfoType * + info() { - StatData *__data = DataAccess::statData(); - Data *ptr = dynamic_cast *>(__data); - assert(ptr); - return ptr; + return safe_cast(InfoAccess::info()); } public: - const Data * - statData() const + const InfoType * + info() const { - const StatData *__data = DataAccess::statData(); - const Data *ptr = dynamic_cast *>(__data); - assert(ptr); - return ptr; + return safe_cast(InfoAccess::info()); } protected: @@ -422,7 +431,7 @@ class Wrap : public Child public: Wrap() { - this->map(new Data(*this)); + this->setInfo(new InfoType(*this)); } /** @@ -433,9 +442,9 @@ class Wrap : public Child Parent & name(const std::string &_name) { - Data *data = this->statData(); - data->name = _name; - this->setPrint(); + InfoType *info = this->info(); + info->name = _name; + info->flags |= print; return this->self(); } @@ -448,7 +457,7 @@ class Wrap : public Child Parent & desc(const std::string &_desc) { - this->statData()->desc = _desc; + this->info()->desc = _desc; return this->self(); } @@ -460,7 +469,7 @@ class Wrap : public Child Parent & precision(int _precision) { - this->statData()->precision = _precision; + this->info()->precision = _precision; return this->self(); } @@ -472,7 +481,7 @@ class Wrap : public Child Parent & flags(StatFlags _flags) { - this->statData()->flags |= _flags; + this->info()->flags |= _flags; return this->self(); } @@ -486,14 +495,19 @@ class Wrap : public Child Parent & prereq(const Stat &prereq) { - this->statData()->prereq = prereq.statData(); + this->info()->prereq = prereq.info(); return this->self(); } }; -template class Data> -class WrapVec : public Wrap +template class Info> +class WrapVec : public Wrap { + public: + typedef Parent ParentType; + typedef Child ChildType; + typedef Info InfoType; + public: // The following functions are specific to vectors. If you use them // in a non vector context, you will get a nice compiler error! @@ -508,7 +522,7 @@ class WrapVec : public Wrap Parent & subname(off_type index, const std::string &name) { - std::vector &subn = this->statData()->subnames; + std::vector &subn = this->info()->subnames; if (subn.size() <= index) subn.resize(index + 1); subn[index] = name; @@ -525,7 +539,7 @@ class WrapVec : public Wrap Parent & subdesc(off_type index, const std::string &desc) { - std::vector &subd = this->statData()->subdescs; + std::vector &subd = this->info()->subdescs; if (subd.size() <= index) subd.resize(index + 1); subd[index] = desc; @@ -535,9 +549,14 @@ class WrapVec : public Wrap }; -template class Data> -class WrapVec2d : public WrapVec +template class Info> +class WrapVec2d : public WrapVec { + public: + typedef Parent ParentType; + typedef Child ChildType; + typedef Info InfoType; + public: /** * @warning This makes the assumption that if you're gonna subnames a 2d @@ -546,20 +565,20 @@ class WrapVec2d : public WrapVec Parent & ysubnames(const char **names) { - Data *data = this->statData(); - data->y_subnames.resize(this->y); + InfoType *info = this->info(); + info->y_subnames.resize(this->y); for (off_type i = 0; i < this->y; ++i) - data->y_subnames[i] = names[i]; + info->y_subnames[i] = names[i]; return this->self(); } Parent & ysubname(off_type index, const std::string subname) { - Data *data = this->statData(); + InfoType *info = this->info(); assert(index < this->y); - data->y_subnames.resize(this->y); - data->y_subnames[index] = subname.c_str(); + info->y_subnames.resize(this->y); + info->y_subnames[index] = subname.c_str(); return this->self(); } }; @@ -573,7 +592,7 @@ class WrapVec2d : public WrapVec /** * Templatized storage and interface for a simple scalar stat. */ -struct StatStor +class StatStor { public: /** The paramaters for this storage type, none for a scalar. */ @@ -638,7 +657,7 @@ struct StatStor * being watched. This is good for keeping track of residencies in structures * among other things. */ -struct AvgStor +class AvgStor { public: /** The paramaters for this storage type */ @@ -665,7 +684,8 @@ struct AvgStor * @param p The parameters for this storage. */ void - set(Counter val, Params &p) { + set(Counter val, Params &p) + { total += current * (curTick - last); last = curTick; current = val; @@ -726,7 +746,7 @@ struct AvgStor * Storage template. */ template -class ScalarBase : public DataAccess +class ScalarBase : public InfoAccess { public: typedef Stor Storage; @@ -851,7 +871,7 @@ class ScalarBase : public DataAccess }; -class ProxyData : public ScalarData +class ProxyInfo : public ScalarInfoBase { public: virtual void visit(Visit &visitor) { visitor.visit(*this); } @@ -863,7 +883,7 @@ class ProxyData : public ScalarData }; template -class ValueProxy : public ProxyData +class ValueProxy : public ProxyInfo { private: T *scalar; @@ -876,7 +896,7 @@ class ValueProxy : public ProxyData }; template -class FunctorProxy : public ProxyData +class FunctorProxy : public ProxyInfo { private: T *functor; @@ -888,10 +908,10 @@ class FunctorProxy : public ProxyData virtual Result total() const { return (*functor)(); } }; -class ValueBase : public DataAccess +class ValueBase : public InfoAccess { private: - ProxyData *proxy; + ProxyInfo *proxy; public: ValueBase() : proxy(NULL) { } @@ -983,7 +1003,8 @@ class ScalarProxy * @return A reference to this proxy. */ const ScalarProxy & - operator=(const ScalarProxy &sp) { + operator=(const ScalarProxy &sp) + { stat = sp.stat; index = sp.index; return *this; @@ -1058,7 +1079,7 @@ class ScalarProxy std::string str() const { - return csprintf("%s[%d]", stat->statData()->name, index); + return csprintf("%s[%d]", stat->info()->name, index); } }; @@ -1067,7 +1088,7 @@ class ScalarProxy * Storage class. @sa ScalarBase */ template -class VectorBase : public DataAccess +class VectorBase : public InfoAccess { public: typedef Stor Storage; @@ -1207,7 +1228,7 @@ class VectorBase : public DataAccess return Proxy(this, index); } - void update(StatData *data) {} + void update(Info *data) {} }; template @@ -1292,7 +1313,7 @@ class VectorProxy }; template -class Vector2dBase : public DataAccess +class Vector2dBase : public InfoAccess { public: typedef Stor Storage; @@ -1318,12 +1339,12 @@ class Vector2dBase : public DataAccess assert(_x > 0 && _y > 0 && "sizes must be positive!"); assert(!storage && "already initialized"); - Vector2dData *statdata = dynamic_cast(find()); + Vector2dInfoBase *info = dynamic_cast(find()); x = _x; y = _y; - statdata->x = _x; - statdata->y = _y; + info->x = _x; + info->y = _y; _size = x * y; char *ptr = new char[_size * sizeof(Storage)]; @@ -1351,12 +1372,12 @@ class Vector2dBase : public DataAccess } void - update(Vector2dData *newdata) + update(Vector2dInfoBase *newinfo) { size_type size = this->size(); - newdata->cvec.resize(size); + newinfo->cvec.resize(size); for (off_type i = 0; i < size; ++i) - newdata->cvec[i] = data(i)->value(params); + newinfo->cvec[i] = data(i)->value(); } std::string ysubname(off_type i) const { return (*this->y_subnames)[i]; } @@ -1414,7 +1435,7 @@ class Vector2dBase : public DataAccess /** * Templatized storage and interface for a distrbution stat. */ -struct DistStor +class DistStor { public: /** The parameters for a distribution stat. */ @@ -1507,7 +1528,7 @@ struct DistStor } void - update(DistDataData *data, const Params ¶ms) + update(DistData *data, const Params ¶ms) { data->min = params.min; data->max = params.max; @@ -1552,7 +1573,7 @@ struct DistStor * Templatized storage and interface for a distribution that calculates mean * and variance. */ -struct FancyStor +class FancyStor { public: /** @@ -1595,7 +1616,7 @@ struct FancyStor } void - update(DistDataData *data, const Params ¶ms) + update(DistData *data, const Params ¶ms) { data->sum = sum; data->squares = squares; @@ -1630,7 +1651,7 @@ struct FancyStor * Templatized storage for distribution that calculates per tick mean and * variance. */ -struct AvgFancy +class AvgFancy { public: /** No parameters for this storage. */ @@ -1665,7 +1686,7 @@ struct AvgFancy } void - update(DistDataData *data, const Params ¶ms) + update(DistData *data, const Params ¶ms) { data->sum = sum; data->squares = squares; @@ -1700,7 +1721,7 @@ struct AvgFancy * determined by the Storage template. @sa ScalarBase */ template -class DistBase : public DataAccess +class DistBase : public InfoAccess { public: typedef Stor Storage; @@ -1766,7 +1787,7 @@ class DistBase : public DataAccess bool zero() const { return data()->zero(params); } void - update(DistData *base) + update(DistInfoBase *base) { base->data.fancy = Storage::fancy; data()->update(&(base->data), params); @@ -1792,7 +1813,7 @@ template class DistProxy; template -class VectorDistBase : public DataAccess +class VectorDistBase : public InfoAccess { public: typedef Stor Storage; @@ -1886,7 +1907,7 @@ class VectorDistBase : public DataAccess } void - update(VectorDistData *base) + update(VectorDistInfoBase *base) { size_type size = this->size(); base->data.resize(size); @@ -2011,11 +2032,11 @@ typedef RefCountingPtr NodePtr; class ScalarStatNode : public Node { private: - const ScalarData *data; + const ScalarInfoBase *data; mutable VResult vresult; public: - ScalarStatNode(const ScalarData *d) : data(d), vresult(1) {} + ScalarStatNode(const ScalarInfoBase *d) : data(d), vresult(1) {} virtual const VResult & result() const @@ -2078,10 +2099,10 @@ class ScalarProxyNode : public Node class VectorStatNode : public Node { private: - const VectorData *data; + const VectorInfoBase *data; public: - VectorStatNode(const VectorData *d) : data(d) { } + VectorStatNode(const VectorInfoBase *d) : data(d) { } virtual const VResult &result() const { return data->result(); } virtual Result total() const { return data->total(); }; @@ -2364,7 +2385,7 @@ class SumNode : public Node * @sa Stat, ScalarBase, StatStor */ template -class Scalar : public Wrap, ScalarBase, ScalarStatData> +class Scalar : public Wrap, ScalarBase, ScalarInfo> { public: /** The base implementation. */ @@ -2384,7 +2405,7 @@ class Scalar : public Wrap, ScalarBase, ScalarStatData> void operator=(const U &v) { Base::operator=(v); } }; -class Value : public Wrap +class Value : public Wrap { public: /** The base implementation. */ @@ -2412,7 +2433,7 @@ class Value : public Wrap * @sa Stat, ScalarBase, AvgStor */ template -class Average : public Wrap, ScalarBase, ScalarStatData> +class Average : public Wrap, ScalarBase, ScalarInfo> { public: /** The base implementation. */ @@ -2441,7 +2462,7 @@ class Average : public Wrap, ScalarBase, ScalarStatData> * @sa Stat, VectorBase, StatStor */ template -class Vector : public WrapVec, VectorBase, VectorStatData> +class Vector : public WrapVec, VectorBase, VectorInfo> { public: /** The base implementation. */ @@ -2466,7 +2487,7 @@ class Vector : public WrapVec, VectorBase, VectorStatData> */ template class AverageVector - : public WrapVec, VectorBase, VectorStatData> + : public WrapVec, VectorBase, VectorInfo> { public: /** @@ -2488,7 +2509,7 @@ class AverageVector */ template class Vector2d - : public WrapVec2d, Vector2dBase, Vector2dStatData> + : public WrapVec2d, Vector2dBase, Vector2dInfo> { public: Vector2d & @@ -2505,7 +2526,7 @@ class Vector2d */ template class Distribution - : public Wrap, DistBase, DistStatData> + : public Wrap, DistBase, DistInfo> { public: /** Base implementation. */ @@ -2539,7 +2560,7 @@ class Distribution */ template class StandardDeviation - : public Wrap, DistBase, DistStatData> + : public Wrap, DistBase, DistInfo> { public: /** The base implementation */ @@ -2563,7 +2584,7 @@ class StandardDeviation */ template class AverageDeviation - : public Wrap, DistBase, DistStatData> + : public Wrap, DistBase, DistInfo> { public: /** The base implementation */ @@ -2589,7 +2610,7 @@ template class VectorDistribution : public WrapVec, VectorDistBase, - VectorDistStatData> + VectorDistInfo> { public: /** The base implementation */ @@ -2626,7 +2647,7 @@ template class VectorStandardDeviation : public WrapVec, VectorDistBase, - VectorDistStatData> + VectorDistInfo> { public: /** The base implementation */ @@ -2656,7 +2677,7 @@ template class VectorAverageDeviation : public WrapVec, VectorDistBase, - VectorDistStatData> + VectorDistInfo> { public: /** The base implementation */ @@ -2683,7 +2704,7 @@ class VectorAverageDeviation * stored as a tree of Nodes that represent the equation to calculate. * @sa Stat, ScalarStat, VectorStat, Node, Temp */ -class FormulaBase : public DataAccess +class FormulaBase : public InfoAccess { protected: /** The root of the tree which represents the Formula */ @@ -2732,12 +2753,12 @@ class FormulaBase : public DataAccess /** * */ - void update(StatData *); + void update(Info *); std::string str() const; }; -class FormulaData : public VectorData +class FormulaInfoBase : public VectorInfoBase { public: virtual std::string str() const = 0; @@ -2745,7 +2766,7 @@ class FormulaData : public VectorData }; template -class FormulaStatData : public FormulaData +class FormulaInfo : public FormulaInfoBase { protected: Stat &s; @@ -2753,7 +2774,7 @@ class FormulaStatData : public FormulaData mutable VCounter cvec; public: - FormulaStatData(Stat &stat) : s(stat) {} + FormulaInfo(Stat &stat) : s(stat) {} virtual bool zero() const { return s.zero(); } virtual void reset() { s.reset(); } @@ -2784,7 +2805,7 @@ class Temp; class Formula : public WrapVec + FormulaInfo> { public: /** @@ -2861,7 +2882,7 @@ class Temp */ template Temp(const Scalar &s) - : node(new ScalarStatNode(s.statData())) + : node(new ScalarStatNode(s.info())) { } /** @@ -2869,7 +2890,7 @@ class Temp * @param s The ScalarStat to place in a node. */ Temp(const Value &s) - : node(new ScalarStatNode(s.statData())) + : node(new ScalarStatNode(s.info())) { } /** @@ -2878,7 +2899,7 @@ class Temp */ template Temp(const Average &s) - : node(new ScalarStatNode(s.statData())) + : node(new ScalarStatNode(s.info())) { } /** @@ -2887,7 +2908,7 @@ class Temp */ template Temp(const Vector &s) - : node(new VectorStatNode(s.statData())) + : node(new VectorStatNode(s.info())) { } /** diff --git a/src/base/stats/mysql.cc b/src/base/stats/mysql.cc index 8d263d2b9..2f096765f 100644 --- a/src/base/stats/mysql.cc +++ b/src/base/stats/mysql.cc @@ -503,11 +503,11 @@ MySql::configure() } for (i = stats().begin(); i != end; ++i) { - StatData *data = *i; - if (data->prereq) { + Info *info = *i; + if (info->prereq) { // update the prerequisite - uint16_t stat_id = find(data->id); - uint16_t prereq_id = find(data->prereq->id); + uint16_t stat_id = find(info->id); + uint16_t prereq_id = find(info->prereq->id); assert(stat_id && prereq_id); stringstream update; @@ -528,153 +528,152 @@ MySql::configure() configured = true; } - bool -MySql::configure(const StatData &data, string type) +MySql::configure(const Info &info, string type) { stat.init(); - stat.name = data.name; - stat.descr = data.desc; + stat.name = info.name; + stat.descr = info.desc; stat.type = type; - stat.print = data.flags & print; - stat.prec = data.precision; - stat.nozero = data.flags & nozero; - stat.nonan = data.flags & nonan; - stat.total = data.flags & total; - stat.pdf = data.flags & pdf; - stat.cdf = data.flags & cdf; + stat.print = info.flags & print; + stat.prec = info.precision; + stat.nozero = info.flags & nozero; + stat.nonan = info.flags & nonan; + stat.total = info.flags & total; + stat.pdf = info.flags & pdf; + stat.cdf = info.flags & cdf; return stat.print; } void -MySql::configure(const ScalarData &data) +MySql::configure(const ScalarInfoBase &info) { - if (!configure(data, "SCALAR")) + if (!configure(info, "SCALAR")) return; - insert(data.id, stat.setup(run)); + insert(info.id, stat.setup(run)); } void -MySql::configure(const VectorData &data) +MySql::configure(const VectorInfoBase &info) { - if (!configure(data, "VECTOR")) + if (!configure(info, "VECTOR")) return; uint16_t statid = stat.setup(run); - if (!data.subnames.empty()) { + if (!info.subnames.empty()) { InsertSubData subdata; subdata.stat = statid; subdata.y = 0; - for (off_type i = 0; i < data.subnames.size(); ++i) { + for (off_type i = 0; i < info.subnames.size(); ++i) { subdata.x = i; - subdata.name = data.subnames[i]; - subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i]; + subdata.name = info.subnames[i]; + subdata.descr = info.subdescs.empty() ? "" : info.subdescs[i]; if (!subdata.name.empty() || !subdata.descr.empty()) subdata.setup(run); } } - insert(data.id, statid); + insert(info.id, statid); } void -MySql::configure(const DistData &data) +MySql::configure(const DistInfoBase &info) { - if (!configure(data, "DIST")) + if (!configure(info, "DIST")) return; - if (!data.data.fancy) { - stat.size = data.data.size; - stat.min = data.data.min; - stat.max = data.data.max; - stat.bktsize = data.data.bucket_size; + if (!info.data.fancy) { + stat.size = info.data.size; + stat.min = info.data.min; + stat.max = info.data.max; + stat.bktsize = info.data.bucket_size; } - insert(data.id, stat.setup(run)); + insert(info.id, stat.setup(run)); } void -MySql::configure(const VectorDistData &data) +MySql::configure(const VectorDistInfoBase &info) { - if (!configure(data, "VECTORDIST")) + if (!configure(info, "VECTORDIST")) return; - if (!data.data[0].fancy) { - stat.size = data.data[0].size; - stat.min = data.data[0].min; - stat.max = data.data[0].max; - stat.bktsize = data.data[0].bucket_size; + if (!info.data[0].fancy) { + stat.size = info.data[0].size; + stat.min = info.data[0].min; + stat.max = info.data[0].max; + stat.bktsize = info.data[0].bucket_size; } uint16_t statid = stat.setup(run); - if (!data.subnames.empty()) { + if (!info.subnames.empty()) { InsertSubData subdata; subdata.stat = statid; subdata.y = 0; - for (off_type i = 0; i < data.subnames.size(); ++i) { + for (off_type i = 0; i < info.subnames.size(); ++i) { subdata.x = i; - subdata.name = data.subnames[i]; - subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i]; + subdata.name = info.subnames[i]; + subdata.descr = info.subdescs.empty() ? "" : info.subdescs[i]; if (!subdata.name.empty() || !subdata.descr.empty()) subdata.setup(run); } } - insert(data.id, statid); + insert(info.id, statid); } void -MySql::configure(const Vector2dData &data) +MySql::configure(const Vector2dInfoBase &info) { - if (!configure(data, "VECTOR2D")) + if (!configure(info, "VECTOR2D")) return; uint16_t statid = stat.setup(run); - if (!data.subnames.empty()) { + if (!info.subnames.empty()) { InsertSubData subdata; subdata.stat = statid; subdata.y = -1; - for (off_type i = 0; i < data.subnames.size(); ++i) { + for (off_type i = 0; i < info.subnames.size(); ++i) { subdata.x = i; - subdata.name = data.subnames[i]; - subdata.descr = data.subdescs.empty() ? "" : data.subdescs[i]; + subdata.name = info.subnames[i]; + subdata.descr = info.subdescs.empty() ? "" : info.subdescs[i]; if (!subdata.name.empty() || !subdata.descr.empty()) subdata.setup(run); } } - if (!data.y_subnames.empty()) { + if (!info.y_subnames.empty()) { InsertSubData subdata; subdata.stat = statid; subdata.x = -1; subdata.descr = ""; - for (off_type i = 0; i < data.y_subnames.size(); ++i) { + for (off_type i = 0; i < info.y_subnames.size(); ++i) { subdata.y = i; - subdata.name = data.y_subnames[i]; + subdata.name = info.y_subnames[i]; if (!subdata.name.empty()) subdata.setup(run); } } - insert(data.id, statid); + insert(info.id, statid); } void -MySql::configure(const FormulaData &data) +MySql::configure(const FormulaInfoBase &info) { MySQL::Connection &mysql = run->conn(); assert(mysql.connected()); - configure(data, "FORMULA"); - insert(data.id, stat.setup(run)); + configure(info, "FORMULA"); + insert(info.id, stat.setup(run)); - uint16_t stat = find(data.id); - string formula = data.str(); + uint16_t stat = find(info.id); + string formula = info.str(); stringstream insert_formula; ccprintf(insert_formula, @@ -720,7 +719,7 @@ MySql::output() Database::stat_list_t::const_iterator i, end = Database::stats().end(); for (i = Database::stats().begin(); i != end; ++i) { - StatData *stat = *i; + Info *stat = *i; stat->visit(*this); if (mysql.commit()) panic("could not commit transaction\n%s\n", mysql.error); @@ -735,32 +734,31 @@ MySql::event(const std::string &event) newevent.insert(event); } - void -MySql::output(const ScalarData &data) +MySql::output(const ScalarInfoBase &info) { - if (!(data.flags & print)) + if (!(info.flags & print)) return; - newdata.stat = find(data.id); + newdata.stat = find(info.id); newdata.x = 0; newdata.y = 0; - newdata.data = data.value(); + newdata.data = info.value(); newdata.insert(); } void -MySql::output(const VectorData &data) +MySql::output(const VectorInfoBase &info) { - if (!(data.flags & print)) + if (!(info.flags & print)) return; - newdata.stat = find(data.id); + newdata.stat = find(info.id); newdata.y = 0; - const VCounter &cvec = data.value(); - size_type size = data.size(); + const VCounter &cvec = info.value(); + size_type size = info.size(); for (off_type x = 0; x < size; x++) { newdata.x = x; newdata.data = cvec[x]; @@ -769,7 +767,7 @@ MySql::output(const VectorData &data) } void -MySql::output(const DistDataData &data) +MySql::output(const DistData &data) { const int db_sum = -1; const int db_squares = -2; @@ -817,54 +815,53 @@ MySql::output(const DistDataData &data) } } - void -MySql::output(const DistData &data) +MySql::output(const DistInfoBase &info) { - if (!(data.flags & print)) + if (!(info.flags & print)) return; - newdata.stat = find(data.id); + newdata.stat = find(info.id); newdata.y = 0; - output(data.data); + output(info.data); } void -MySql::output(const VectorDistData &data) +MySql::output(const VectorDistInfoBase &info) { - if (!(data.flags & print)) + if (!(info.flags & print)) return; - newdata.stat = find(data.id); + newdata.stat = find(info.id); - size_type size = data.data.size(); + size_type size = info.data.size(); for (off_type y = 0; y < size; ++y) { newdata.y = y; - output(data.data[y]); + output(info.data[y]); } } void -MySql::output(const Vector2dData &data) +MySql::output(const Vector2dInfoBase &info) { - if (!(data.flags & print)) + if (!(info.flags & print)) return; - newdata.stat = find(data.id); + newdata.stat = find(info.id); off_type index = 0; - for (off_type x = 0; x < data.x; x++) { + for (off_type x = 0; x < info.x; x++) { newdata.x = x; - for (off_type y = 0; y < data.y; y++) { + for (off_type y = 0; y < info.y; y++) { newdata.y = y; - newdata.data = data.cvec[index++]; + newdata.data = info.cvec[index++]; newdata.insert(); } } } void -MySql::output(const FormulaData &data) +MySql::output(const FormulaInfoBase &info) { } @@ -872,60 +869,60 @@ MySql::output(const FormulaData &data) * Implement the visitor */ void -MySql::visit(const ScalarData &data) +MySql::visit(const ScalarInfoBase &info) { if (!configured) - configure(data); + configure(info); else - output(data); + output(info); } void -MySql::visit(const VectorData &data) +MySql::visit(const VectorInfoBase &info) { if (!configured) - configure(data); + configure(info); else - output(data); + output(info); } void -MySql::visit(const DistData &data) +MySql::visit(const DistInfoBase &info) { return; if (!configured) - configure(data); + configure(info); else - output(data); + output(info); } void -MySql::visit(const VectorDistData &data) +MySql::visit(const VectorDistInfoBase &info) { return; if (!configured) - configure(data); + configure(info); else - output(data); + output(info); } void -MySql::visit(const Vector2dData &data) +MySql::visit(const Vector2dInfoBase &info) { return; if (!configured) - configure(data); + configure(info); else - output(data); + output(info); } void -MySql::visit(const FormulaData &data) +MySql::visit(const FormulaInfoBase &info) { if (!configured) - configure(data); + configure(info); else - output(data); + output(info); } bool diff --git a/src/base/stats/mysql.hh b/src/base/stats/mysql.hh index 6e47719ce..f0f79bebd 100644 --- a/src/base/stats/mysql.hh +++ b/src/base/stats/mysql.hh @@ -40,7 +40,7 @@ namespace MySQL { class Connection; } namespace Stats { -class DistDataData; +class DistInfoBase; class MySqlRun; struct SetupStat @@ -121,7 +121,7 @@ class MySql : public Output SetupStat stat; InsertData newdata; InsertEvent newevent; - std::list formulas; + std::list formulas; bool configured; protected: @@ -155,12 +155,12 @@ class MySql : public Output public: // Implement Visit - virtual void visit(const ScalarData &data); - virtual void visit(const VectorData &data); - virtual void visit(const DistData &data); - virtual void visit(const VectorDistData &data); - virtual void visit(const Vector2dData &data); - virtual void visit(const FormulaData &data); + virtual void visit(const ScalarInfoBase &info); + virtual void visit(const VectorInfoBase &info); + virtual void visit(const DistInfoBase &info); + virtual void visit(const VectorDistInfoBase &info); + virtual void visit(const Vector2dInfoBase &info); + virtual void visit(const FormulaInfoBase &info); // Implement Output virtual bool valid() const; @@ -171,22 +171,22 @@ class MySql : public Output protected: // Output helper - void output(const DistDataData &data); - void output(const ScalarData &data); - void output(const VectorData &data); + void output(const ScalarInfoBase &info); + void output(const VectorInfoBase &info); + void output(const DistInfoBase &info); + void output(const VectorDistInfoBase &info); + void output(const Vector2dInfoBase &info); + void output(const FormulaInfoBase &info); void output(const DistData &data); - void output(const VectorDistData &data); - void output(const Vector2dData &data); - void output(const FormulaData &data); void configure(); - bool configure(const StatData &data, std::string type); - void configure(const ScalarData &data); - void configure(const VectorData &data); - void configure(const DistData &data); - void configure(const VectorDistData &data); - void configure(const Vector2dData &data); - void configure(const FormulaData &data); + bool configure(const Info &info, std::string type); + void configure(const ScalarInfoBase &info); + void configure(const VectorInfoBase &info); + void configure(const DistInfoBase &info); + void configure(const VectorDistInfoBase &info); + void configure(const Vector2dInfoBase &info); + void configure(const FormulaInfoBase &info); }; bool initMySQL(std::string host, std::string database, std::string user, diff --git a/src/base/stats/statdb.cc b/src/base/stats/statdb.cc index c54dbb8ec..8ead17c52 100644 --- a/src/base/stats/statdb.cc +++ b/src/base/stats/statdb.cc @@ -38,7 +38,7 @@ using namespace std; namespace Stats { namespace Database { -StatData * +Info * find(void *stat) { stat_map_t::const_iterator i = map().find(stat); @@ -50,7 +50,7 @@ find(void *stat) } void -regStat(void *stat, StatData *data) +regStat(void *stat, Info *data) { if (map().find(stat) != map().end()) panic("shouldn't register stat twice!"); @@ -68,7 +68,7 @@ regStat(void *stat, StatData *data) void regPrint(void *stat) { - StatData *data = find(stat); + Info *data = find(stat); assert(data); data->flags |= print; } diff --git a/src/base/stats/statdb.hh b/src/base/stats/statdb.hh index a5b9be7eb..d12c6166b 100644 --- a/src/base/stats/statdb.hh +++ b/src/base/stats/statdb.hh @@ -40,12 +40,12 @@ class Python; namespace Stats { -class StatData; +class Info; namespace Database { -typedef std::map stat_map_t; -typedef std::list stat_list_t; +typedef std::map stat_map_t; +typedef std::list stat_list_t; // We wrap the database in a struct to make sure it is built in time. struct TheDatabase @@ -58,8 +58,8 @@ TheDatabase &db(); inline stat_map_t &map() { return db().map; } inline stat_list_t &stats() { return db().stats; } -StatData *find(void *stat); -void regStat(void *stat, StatData *data); +Info *find(void *stat); +void regStat(void *stat, Info *data); void regPrint(void *stat); inline std::string name() { return "Statistics Database"; } diff --git a/src/base/stats/text.cc b/src/base/stats/text.cc index 00efd977b..877c4c650 100644 --- a/src/base/stats/text.cc +++ b/src/base/stats/text.cc @@ -143,12 +143,12 @@ Text::output() } bool -Text::noOutput(const StatData &data) +Text::noOutput(const Info &info) { - if (!(data.flags & print)) + if (!(info.flags & print)) return true; - if (data.prereq && data.prereq->zero()) + if (info.prereq && info.prereq->zero()) return true; return false; @@ -535,19 +535,19 @@ DistPrint::operator()(ostream &stream) const } void -Text::visit(const ScalarData &data) +Text::visit(const ScalarInfoBase &info) { - if (noOutput(data)) + if (noOutput(info)) return; ScalarPrint print; - print.value = data.result(); - print.name = data.name; - print.desc = data.desc; - print.flags = data.flags; + print.value = info.result(); + print.name = info.name; + print.desc = info.desc; + print.flags = info.flags; print.compat = compat; print.descriptions = descriptions; - print.precision = data.precision; + print.precision = info.precision; print.pdf = NAN; print.cdf = NAN; @@ -555,32 +555,32 @@ Text::visit(const ScalarData &data) } void -Text::visit(const VectorData &data) +Text::visit(const VectorInfoBase &info) { - if (noOutput(data)) + if (noOutput(info)) return; - size_type size = data.size(); + size_type size = info.size(); VectorPrint print; - print.name = data.name; - print.desc = data.desc; - print.flags = data.flags; + print.name = info.name; + print.desc = info.desc; + print.flags = info.flags; print.compat = compat; print.descriptions = descriptions; - print.precision = data.precision; - print.vec = data.result(); - print.total = data.total(); + print.precision = info.precision; + print.vec = info.result(); + print.total = info.total(); - if (!data.subnames.empty()) { + if (!info.subnames.empty()) { for (off_type i = 0; i < size; ++i) { - if (!data.subnames[i].empty()) { - print.subnames = data.subnames; + if (!info.subnames[i].empty()) { + print.subnames = info.subnames; print.subnames.resize(size); for (off_type i = 0; i < size; ++i) { - if (!data.subnames[i].empty() && - !data.subdescs[i].empty()) { - print.subdescs = data.subdescs; + if (!info.subnames[i].empty() && + !info.subdescs[i].empty()) { + print.subdescs = info.subdescs; print.subdescs.resize(size); break; } @@ -594,54 +594,54 @@ Text::visit(const VectorData &data) } void -Text::visit(const Vector2dData &data) +Text::visit(const Vector2dInfoBase &info) { - if (noOutput(data)) + if (noOutput(info)) return; bool havesub = false; VectorPrint print; - print.subnames = data.y_subnames; - print.flags = data.flags; + print.subnames = info.y_subnames; + print.flags = info.flags; print.compat = compat; print.descriptions = descriptions; - print.precision = data.precision; + print.precision = info.precision; - if (!data.subnames.empty()) { - for (off_type i = 0; i < data.x; ++i) - if (!data.subnames[i].empty()) + if (!info.subnames.empty()) { + for (off_type i = 0; i < info.x; ++i) + if (!info.subnames[i].empty()) havesub = true; } - VResult tot_vec(data.y); + VResult tot_vec(info.y); Result super_total = 0.0; - for (off_type i = 0; i < data.x; ++i) { - if (havesub && (i >= data.subnames.size() || data.subnames[i].empty())) + for (off_type i = 0; i < info.x; ++i) { + if (havesub && (i >= info.subnames.size() || info.subnames[i].empty())) continue; - off_type iy = i * data.y; - VResult yvec(data.y); + off_type iy = i * info.y; + VResult yvec(info.y); Result total = 0.0; - for (off_type j = 0; j < data.y; ++j) { - yvec[j] = data.cvec[iy + j]; + for (off_type j = 0; j < info.y; ++j) { + yvec[j] = info.cvec[iy + j]; tot_vec[j] += yvec[j]; total += yvec[j]; super_total += yvec[j]; } - print.name = data.name + "_" + - (havesub ? data.subnames[i] : to_string(i)); - print.desc = data.desc; + print.name = info.name + "_" + + (havesub ? info.subnames[i] : to_string(i)); + print.desc = info.desc; print.vec = yvec; print.total = total; print(*stream); } - if ((data.flags & ::Stats::total) && (data.x > 1)) { - print.name = data.name; - print.desc = data.desc; + if ((info.flags & ::Stats::total) && (info.x > 1)) { + print.name = info.name; + print.desc = info.desc; print.vec = tot_vec; print.total = super_total; print(*stream); @@ -649,82 +649,84 @@ Text::visit(const Vector2dData &data) } void -Text::visit(const DistData &data) +Text::visit(const DistInfoBase &info) { - if (noOutput(data)) + if (noOutput(info)) return; DistPrint print; - print.name = data.name; - print.desc = data.desc; - print.flags = data.flags; + print.name = info.name; + print.desc = info.desc; + print.flags = info.flags; print.compat = compat; print.descriptions = descriptions; - print.precision = data.precision; + print.precision = info.precision; - print.min_val = data.data.min_val; - print.max_val = data.data.max_val; - print.underflow = data.data.underflow; - print.overflow = data.data.overflow; - print.vec.resize(data.data.cvec.size()); + const DistData &data = info.data; + + print.min_val = data.min_val; + print.max_val = data.max_val; + print.underflow = data.underflow; + print.overflow = data.overflow; + print.vec.resize(data.cvec.size()); for (off_type i = 0; i < print.vec.size(); ++i) - print.vec[i] = (Result)data.data.cvec[i]; - print.sum = data.data.sum; - print.squares = data.data.squares; - print.samples = data.data.samples; + print.vec[i] = (Result)data.cvec[i]; + print.sum = data.sum; + print.squares = data.squares; + print.samples = data.samples; - print.min = data.data.min; - print.max = data.data.max; - print.bucket_size = data.data.bucket_size; - print.size = data.data.size; - print.fancy = data.data.fancy; + print.min = data.min; + print.max = data.max; + print.bucket_size = data.bucket_size; + print.size = data.size; + print.fancy = data.fancy; print(*stream); } void -Text::visit(const VectorDistData &data) +Text::visit(const VectorDistInfoBase &info) { - if (noOutput(data)) + if (noOutput(info)) return; - for (off_type i = 0; i < data.size(); ++i) { + for (off_type i = 0; i < info.size(); ++i) { DistPrint print; - print.name = data.name + "_" + - (data.subnames[i].empty() ? (to_string(i)) : data.subnames[i]); - print.desc = data.subdescs[i].empty() ? data.desc : data.subdescs[i]; - print.flags = data.flags; + print.name = info.name + "_" + + (info.subnames[i].empty() ? (to_string(i)) : info.subnames[i]); + print.desc = info.subdescs[i].empty() ? info.desc : info.subdescs[i]; + print.flags = info.flags; print.compat = compat; print.descriptions = descriptions; - print.precision = data.precision; + print.precision = info.precision; - print.min_val = data.data[i].min_val; - print.max_val = data.data[i].max_val; - print.underflow = data.data[i].underflow; - print.overflow = data.data[i].overflow; - print.vec.resize(data.data[i].cvec.size()); + print.min_val = info.data[i].min_val; + print.max_val = info.data[i].max_val; + print.underflow = info.data[i].underflow; + print.overflow = info.data[i].overflow; + print.vec.resize(info.data[i].cvec.size()); for (off_type j = 0; j < print.vec.size(); ++j) - print.vec[j] = (Result)data.data[i].cvec[j]; - print.sum = data.data[i].sum; - print.squares = data.data[i].squares; - print.samples = data.data[i].samples; + print.vec[j] = (Result)info.data[i].cvec[j]; + print.sum = info.data[i].sum; + print.squares = info.data[i].squares; + print.samples = info.data[i].samples; - print.min = data.data[i].min; - print.max = data.data[i].max; - print.bucket_size = data.data[i].bucket_size; - print.size = data.data[i].size; - print.fancy = data.data[i].fancy; + print.min = info.data[i].min; + print.max = info.data[i].max; + print.bucket_size = info.data[i].bucket_size; + print.size = info.data[i].size; + print.fancy = info.data[i].fancy; print(*stream); } } void -Text::visit(const FormulaData &data) +Text::visit(const FormulaInfoBase &info) { - visit((const VectorData &)data); + visit((const VectorInfoBase &)info); } bool diff --git a/src/base/stats/text.hh b/src/base/stats/text.hh index 781d1083d..38e0202eb 100644 --- a/src/base/stats/text.hh +++ b/src/base/stats/text.hh @@ -46,7 +46,7 @@ class Text : public Output std::ostream *stream; protected: - bool noOutput(const StatData &data); + bool noOutput(const Info &info); public: bool compat; @@ -62,12 +62,12 @@ class Text : public Output void open(const std::string &file); // Implement Visit - virtual void visit(const ScalarData &data); - virtual void visit(const VectorData &data); - virtual void visit(const DistData &data); - virtual void visit(const VectorDistData &data); - virtual void visit(const Vector2dData &data); - virtual void visit(const FormulaData &data); + virtual void visit(const ScalarInfoBase &info); + virtual void visit(const VectorInfoBase &info); + virtual void visit(const DistInfoBase &info); + virtual void visit(const VectorDistInfoBase &info); + virtual void visit(const Vector2dInfoBase &info); + virtual void visit(const FormulaInfoBase &info); // Implement Output virtual bool valid() const; diff --git a/src/base/stats/visit.hh b/src/base/stats/visit.hh index 0087c227c..9d6996689 100644 --- a/src/base/stats/visit.hh +++ b/src/base/stats/visit.hh @@ -38,26 +38,26 @@ namespace Stats { -class StatData; -class ScalarData; -class VectorData; -class DistDataData; -class DistData; -class VectorDistData; -class Vector2dData; -class FormulaData; +class Info; +class ScalarInfoBase; +class VectorInfoBase; +class DistInfoBase; +class DistInfoBase; +class VectorDistInfoBase; +class Vector2dInfoBase; +class FormulaInfoBase; struct Visit { Visit(); virtual ~Visit(); - virtual void visit(const ScalarData &data) = 0; - virtual void visit(const VectorData &data) = 0; - virtual void visit(const DistData &data) = 0; - virtual void visit(const VectorDistData &data) = 0; - virtual void visit(const Vector2dData &data) = 0; - virtual void visit(const FormulaData &data) = 0; + virtual void visit(const ScalarInfoBase &info) = 0; + virtual void visit(const VectorInfoBase &info) = 0; + virtual void visit(const DistInfoBase &info) = 0; + virtual void visit(const VectorDistInfoBase &info) = 0; + virtual void visit(const Vector2dInfoBase &info) = 0; + virtual void visit(const FormulaInfoBase &info) = 0; }; /* namespace Stats */ } -- 2.30.2