X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=base%2Fstatistics.hh;h=c46744cac6b4a9b74528748f3e3d94ddf351ca3a;hb=5aa71721193c49016ffa69934b44ce38672e4eed;hp=3fc019edc521acc587cac27eb0dc8f4a6d5b3fd3;hpb=ecd3ecb4f55b64b55fb91722f913131f018a4996;p=gem5.git diff --git a/base/statistics.hh b/base/statistics.hh index 3fc019edc..c46744cac 100644 --- a/base/statistics.hh +++ b/base/statistics.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 The Regents of The University of Michigan + * Copyright (c) 2003-2005 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -42,85 +42,36 @@ * VectorStandardDeviation totals * Document Namespaces */ -#ifndef __STATISTICS_HH__ -#define __STATISTICS_HH__ +#ifndef __BASE_STATISTICS_HH__ +#define __BASE_STATISTICS_HH__ #include +#include +#include #include #include #include #include #include -#include - +#include "base/cprintf.hh" +#include "base/intmath.hh" #include "base/refcnt.hh" #include "base/str.hh" -#include "base/intmath.hh" -#include +#include "base/stats/bin.hh" +#include "base/stats/flags.hh" +#include "base/stats/visit.hh" +#include "base/stats/types.hh" +#include "config/stats_binning.hh" #include "sim/host.hh" -#ifdef FS_MEASURE -#include "base/trace.hh" -#endif -// -// Un-comment this to enable weirdo-stat debugging -// -// #define STAT_DEBUG - - -#ifndef NAN -float __nan(); -/** Define Not a number. */ -#define NAN (__nan()) -/** Need to define __nan() */ -#define __M5_NAN -#endif - class Callback; /** The current simulated cycle. */ extern Tick curTick; /* A namespace for all of the Statistics */ -namespace Statistics { -/** All results are doubles. */ -typedef double result_t; -/** A vector to hold results. */ -typedef std::vector rvec_t; - -/** - * Define the storage for format flags. - * @todo Can probably shrink this. - */ -typedef u_int32_t FormatFlags; -/** Nothing extra to print. */ -const FormatFlags none = 0x0000; -/** Print the total. */ -const FormatFlags total = 0x0001; -/** Print the percent of the total that this entry represents. */ -const FormatFlags pdf = 0x0002; -/** Print the cumulative percentage of total upto this entry. */ -const FormatFlags cdf = 0x0004; -/** Don't print if this is zero. */ -const FormatFlags nozero = 0x0010; -/** Don't print if this is NAN */ -const FormatFlags nonan = 0x0020; -/** Print the distribution. */ -const FormatFlags dist = 0x0100; -/** Used for SS compatability. */ -const FormatFlags __substat = 0x8000; -/** Mask of flags that can't be set directly */ -const FormatFlags __reserved = __substat; - -enum DisplayMode -{ - mode_m5, - mode_simplescalar, - mode_python -}; - -extern DisplayMode default_mode; +namespace Stats { /* Contains the statistic implementation details */ ////////////////////////////////////////////////////////////////////// @@ -130,30 +81,23 @@ extern DisplayMode default_mode; ////////////////////////////////////////////////////////////////////// struct StatData { - /** True if the stat has been initialized. */ - bool init; - /** True if the stat should be printed. */ - bool print; /** The name of the stat. */ std::string name; /** The description of the stat. */ std::string desc; + /** The formatting flags. */ + StatFlags flags; /** The display precision. */ int precision; - /** Display Mode */ - DisplayMode mode; - /** The formatting flags. */ - FormatFlags flags; - - /** A pointer to a prerequisite Stat. */ const StatData *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() - : init(false), print(false), precision(-1), mode(default_mode), - flags(0), prereq(0) - {} - + StatData(); virtual ~StatData(); /** @@ -161,13 +105,6 @@ struct StatData */ virtual bool binned() const = 0; - /** - * Print this stat to the given ostream. - * @param stream The stream to print to. - */ - virtual void display(std::ostream &stream) const = 0; - bool dodisplay() const { return !prereq || !prereq->zero(); } - /** * Reset the corresponding stat to the default state. */ @@ -187,6 +124,11 @@ struct StatData virtual bool check() const = 0; bool baseCheck() const; + /** + * Visitor entry for outputing statistics data + */ + virtual void visit(Visit &visitor) = 0; + /** * Checks if the first stat's name is alphabetically less than the second. * This function breaks names up at periods and considers each subname @@ -198,62 +140,66 @@ struct StatData static bool less(StatData *stat1, StatData *stat2); }; -struct ScalarDataBase : public StatData +class ScalarData : public StatData { - virtual result_t val() const = 0; - virtual result_t total() const = 0; - - virtual void display(std::ostream &stream) const; + public: + virtual Counter value() const = 0; + virtual Result result() const = 0; + virtual Result total() const = 0; + virtual void visit(Visit &visitor) { visitor.visit(*this); } }; -template -class ScalarData : public ScalarDataBase +template +class ScalarStatData : public ScalarData { protected: - T &s; + Stat &s; public: - ScalarData(T &stat) : s(stat) {} + ScalarStatData(Stat &stat) : s(stat) {} virtual bool binned() const { return s.binned(); } virtual bool check() const { return s.check(); } - virtual result_t val() const { return s.val(); } - virtual result_t total() const { return s.total(); } + virtual Counter value() const { return s.value(); } + virtual Result result() const { return s.result(); } + virtual Result total() const { return s.total(); } virtual void reset() { s.reset(); } virtual bool zero() const { return s.zero(); } }; -struct VectorDataBase : public StatData +struct VectorData : public StatData { /** Names and descriptions of subfields. */ mutable std::vector subnames; mutable std::vector subdescs; - virtual void display(std::ostream &stream) const; - virtual size_t size() const = 0; - virtual const rvec_t &val() const = 0; - virtual result_t total() const = 0; - virtual void update() - { - int s = size(); - if (subnames.size() < s) - subnames.resize(s); - - if (subdescs.size() < s) - subdescs.resize(s); + virtual const VCounter &value() const = 0; + virtual const VResult &result() const = 0; + virtual Result total() const = 0; + void update() + { + if (!subnames.empty()) { + int s = size(); + if (subnames.size() < s) + subnames.resize(s); + + if (subdescs.size() < s) + subdescs.resize(s); + } } }; -template -class VectorData : public VectorDataBase +template +class VectorStatData : public VectorData { protected: - T &s; - mutable rvec_t vec; + Stat &s; + mutable VCounter cvec; + mutable VResult rvec; public: - VectorData(T &stat) : s(stat) {} + VectorStatData(Stat &stat) : s(stat) {} virtual bool binned() const { return s.binned(); } virtual bool check() const { return s.check(); } @@ -261,64 +207,70 @@ class VectorData : public VectorDataBase virtual void reset() { s.reset(); } virtual size_t size() const { return s.size(); } - virtual const rvec_t &val() const + virtual VCounter &value() const { - s.val(vec); - return vec; + s.value(cvec); + return cvec; + } + virtual const VResult &result() const + { + s.result(rvec); + return rvec; } - virtual result_t total() const { return s.total(); } - virtual void update() + virtual Result total() const { return s.total(); } + virtual void visit(Visit &visitor) { - VectorDataBase::update(); + update(); s.update(this); + visitor.visit(*this); } }; - struct DistDataData { - result_t min_val; - result_t max_val; - result_t underflow; - result_t overflow; - rvec_t vec; - result_t sum; - result_t squares; - result_t samples; - - int min; - int max; - int bucket_size; + Counter min_val; + Counter max_val; + Counter underflow; + Counter overflow; + VCounter cvec; + Counter sum; + Counter squares; + Counter samples; + + Counter min; + Counter max; + Counter bucket_size; int size; bool fancy; }; -struct DistDataBase : public StatData +struct DistData : public StatData { /** Local storage for the entry values, used for printing. */ DistDataData data; - - virtual void display(std::ostream &stream) const; - virtual void update() = 0; }; -template -class DistData : public DistDataBase +template +class DistStatData : public DistData { protected: - T &s; + Stat &s; public: - DistData(T &stat) : s(stat) {} + DistStatData(Stat &stat) : s(stat) {} virtual bool binned() const { return s.binned(); } virtual bool check() const { return s.check(); } virtual void reset() { s.reset(); } virtual bool zero() const { return s.zero(); } - virtual void update() { return s.update(this); } + virtual void visit(Visit &visitor) + { + s.update(this); + visitor.visit(*this); + } }; -struct VectorDistDataBase : public StatData +struct VectorDistData : public StatData { std::vector data; @@ -327,11 +279,10 @@ struct VectorDistDataBase : public StatData mutable std::vector subdescs; /** Local storage for the entry values, used for printing. */ - mutable rvec_t vec; + mutable VResult rvec; virtual size_t size() const = 0; - virtual void display(std::ostream &stream) const; - virtual void update() + void update() { int s = size(); if (subnames.size() < s) @@ -342,28 +293,30 @@ struct VectorDistDataBase : public StatData } }; -template -class VectorDistData : public VectorDistDataBase +template +class VectorDistStatData : public VectorDistData { protected: - T &s; + Stat &s; + typedef typename Stat::bin_t bin_t; public: - VectorDistData(T &stat) : s(stat) {} + VectorDistStatData(Stat &stat) : s(stat) {} - virtual bool binned() const { return T::bin_t::binned; } + virtual bool binned() const { return bin_t::binned; } virtual bool check() const { return s.check(); } virtual void reset() { s.reset(); } virtual size_t size() const { return s.size(); } virtual bool zero() const { return s.zero(); } - virtual void update() + virtual void visit(Visit &visitor) { - VectorDistDataBase::update(); - return s.update(this); + update(); + s.update(this); + visitor.visit(*this); } }; -struct Vector2dDataBase : public StatData +struct Vector2dData : public StatData { /** Names and descriptions of subfields. */ std::vector subnames; @@ -371,35 +324,36 @@ struct Vector2dDataBase : public StatData std::vector y_subnames; /** Local storage for the entry values, used for printing. */ - mutable rvec_t vec; + mutable VCounter cvec; mutable int x; mutable int y; - virtual void display(std::ostream &stream) const; - virtual void update() + void update() { if (subnames.size() < x) subnames.resize(x); } }; -template -class Vector2dData : public Vector2dDataBase +template +class Vector2dStatData : public Vector2dData { protected: - T &s; + Stat &s; + typedef typename Stat::bin_t bin_t; public: - Vector2dData(T &stat) : s(stat) {} + Vector2dStatData(Stat &stat) : s(stat) {} - virtual bool binned() const { return T::bin_t::binned; } + virtual bool binned() const { return bin_t::binned; } virtual bool check() const { return s.check(); } virtual void reset() { s.reset(); } virtual bool zero() const { return s.zero(); } - virtual void update() + virtual void visit(Visit &visitor) { - Vector2dDataBase::update(); + update(); s.update(this); + visitor.visit(*this); } }; @@ -417,7 +371,7 @@ class DataAccess void setPrint(); }; -template class Data> +template class Data> class Wrap : public Child { protected: @@ -441,10 +395,20 @@ class Wrap : public Child return ptr; } + protected: + /** + * Copy constructor, copies are not allowed. + */ + Wrap(const Wrap &stat); + /** + * Can't copy stats. + */ + void operator=(const Wrap &); + public: Wrap() { - map(new Data(*this)); + map(new Data(*this)); } /** @@ -454,10 +418,10 @@ class Wrap : public Child */ Parent &name(const std::string &_name) { - Data *data = statData(); + Data *data = this->statData(); data->name = _name; - setPrint(); - return self(); + this->setPrint(); + return this->self(); } /** @@ -468,8 +432,8 @@ class Wrap : public Child */ Parent &desc(const std::string &_desc) { - statData()->desc = _desc; - return self(); + this->statData()->desc = _desc; + return this->self(); } /** @@ -479,8 +443,8 @@ class Wrap : public Child */ Parent &precision(int _precision) { - statData()->precision = _precision; - return self(); + this->statData()->precision = _precision; + return this->self(); } /** @@ -488,10 +452,10 @@ class Wrap : public Child * @param f The new flags. * @return A reference to this stat. */ - Parent &flags(FormatFlags _flags) + Parent &flags(StatFlags _flags) { - statData()->flags |= _flags; - return self(); + this->statData()->flags |= _flags; + return this->self(); } /** @@ -500,11 +464,11 @@ class Wrap : public Child * @param prereq The prerequisite stat. * @return A reference to this stat. */ - template - Parent &prereq(const T &prereq) + template + Parent &prereq(const Stat &prereq) { - statData()->prereq = prereq.statData(); - return self(); + this->statData()->prereq = prereq.statData(); + return this->self(); } }; @@ -524,11 +488,11 @@ class WrapVec : public Wrap */ Parent &subname(int index, const std::string &name) { - std::vector &subn = statData()->subnames; + std::vector &subn = this->statData()->subnames; if (subn.size() <= index) subn.resize(index + 1); subn[index] = name; - return self(); + return this->self(); } /** @@ -540,12 +504,12 @@ class WrapVec : public Wrap */ Parent &subdesc(int index, const std::string &desc) { - std::vector &subd = statData()->subdescs; + std::vector &subd = this->statData()->subdescs; if (subd.size() <= index) subd.resize(index + 1); subd[index] = desc; - return self(); + return this->self(); } }; @@ -560,19 +524,19 @@ class WrapVec2d : public WrapVec */ Parent &ysubnames(const char **names) { - Data *data = statData(); - data->y_subnames.resize(y); - for (int i = 0; i < y; ++i) + Data *data = this->statData(); + data->y_subnames.resize(this->y); + for (int i = 0; i < this->y; ++i) data->y_subnames[i] = names[i]; - return self(); + return this->self(); } Parent &ysubname(int index, const std::string subname) { - Data *data = statData(); - assert(i < y); - data->y_subnames.resize(y); - data->y_subnames[i] = subname.c_str(); - return self(); + Data *data = this->statData(); + assert(index < this->y); + data->y_subnames.resize(this->y); + data->y_subnames[index] = subname.c_str(); + return this->self(); } }; @@ -585,7 +549,6 @@ class WrapVec2d : public WrapVec /** * Templatized storage and interface for a simple scalar stat. */ -template struct StatStor { public: @@ -594,59 +557,54 @@ struct StatStor private: /** The statistic value. */ - T data; - static T &Null() - { - static T __T = T(); - return __T; - } + Counter data; public: /** * Builds this storage element and calls the base constructor of the * datatype. */ - StatStor(const Params &) : data(Null()) {} + StatStor(const Params &) : data(Counter()) {} /** * The the stat to the given value. * @param val The new value. * @param p The paramters of this storage type. */ - void set(T val, const Params &p) { data = val; } + void set(Counter val, const Params &p) { data = val; } /** * Increment the stat by the given value. * @param val The new value. * @param p The paramters of this storage type. */ - void inc(T val, const Params &p) { data += val; } + void inc(Counter val, const Params &p) { data += val; } /** * Decrement the stat by the given value. * @param val The new value. * @param p The paramters of this storage type. */ - void dec(T val, const Params &p) { data -= val; } + void dec(Counter val, const Params &p) { data -= val; } /** - * Return the value of this stat as a result type. - * @param p The parameters of this storage type. + * Return the value of this stat as its base type. + * @param p The params of this storage type. * @return The value of this stat. */ - result_t val(const Params &p) const { return (result_t)data; } + Counter value(const Params &p) const { return data; } /** - * Return the value of this stat as its base type. - * @param p The params of this storage type. + * Return the value of this stat as a result type. + * @param p The parameters of this storage type. * @return The value of this stat. */ - T value(const Params &p) const { return data; } + Result result(const Params &p) const { return (Result)data; } /** * Reset stat value to default */ - void reset() { data = Null(); } + void reset() { data = Counter(); } /** * @return true if zero value */ - bool zero() const { return data == Null(); } + bool zero() const { return data == Counter(); } }; /** @@ -657,7 +615,6 @@ struct StatStor * among other things. * @todo add lateny to the stat and fix binning. */ -template struct AvgStor { public: @@ -668,12 +625,12 @@ struct AvgStor * The current count. We stash this here because the current * value is not a binned value. */ - T current; + Counter current; }; private: /** The total count for all cycles. */ - mutable result_t total; + mutable Result total; /** The cycle that current last changed. */ mutable Tick last; @@ -681,7 +638,7 @@ struct AvgStor /** * Build and initializes this stat storage. */ - AvgStor(Params &p) : total(0), last(0) { p.current = T(); } + AvgStor(Params &p) : total(0), last(0) { p.current = Counter(); } /** * Set the current count to the one provided, update the total and last @@ -689,7 +646,7 @@ struct AvgStor * @param val The new count. * @param p The parameters for this storage. */ - void set(T val, Params &p) { + void set(Counter val, Params &p) { total += p.current * (curTick - last); last = curTick; p.current = val; @@ -700,33 +657,34 @@ struct AvgStor * @param val The amount to increment. * @param p The parameters for this storage. */ - void inc(T val, Params &p) { set(p.current + val, p); } + void inc(Counter val, Params &p) { set(p.current + val, p); } /** * Deccrement the current count by the provided value, calls set. * @param val The amount to decrement. * @param p The parameters for this storage. */ - void dec(T val, Params &p) { set(p.current - val, p); } + void dec(Counter val, Params &p) { set(p.current - val, p); } + + /** + * Return the current count. + * @param p The parameters for this storage. + * @return The current count. + */ + Counter value(const Params &p) const { return p.current; } /** * Return the current average. * @param p The parameters for this storage. * @return The current average. */ - result_t val(const Params &p) const { + Result result(const Params &p) const + { total += p.current * (curTick - last); last = curTick; - return (result_t)(total + p.current) / (result_t)(curTick + 1); + return (Result)(total + p.current) / (Result)(curTick + 1); } - /** - * Return the current count. - * @param p The parameters for this storage. - * @return The current count. - */ - T value(const Params &p) const { return p.current; } - /** * Reset stat value to default */ @@ -747,16 +705,14 @@ struct AvgStor * Storage template. The storage for this stat is held within the Bin class. * This allows for breaking down statistics across multiple bins easily. */ -template class Storage, class Bin> +template class ScalarBase : public DataAccess { - protected: - /** Define the type of the storage class. */ - typedef Storage storage_t; + public: /** Define the params of the storage class. */ - typedef typename storage_t::Params params_t; + typedef typename Storage::Params params_t; /** Define the bin type. */ - typedef typename Bin::Bin bin_t; + typedef typename Bin::template Bin bin_t; protected: /** The bin of this stat. */ @@ -769,34 +725,24 @@ class ScalarBase : public DataAccess * Retrieve the storage from the bin. * @return The storage object for this stat. */ - storage_t *data() { return bin.data(params); } + Storage *data() { return bin.data(params); } /** * Retrieve a const pointer to the storage from the bin. * @return A const pointer to the storage object for this stat. */ - const storage_t *data() const + const Storage *data() const { bin_t *_bin = const_cast(&bin); params_t *_params = const_cast(¶ms); return _bin->data(*_params); } - protected: - /** - * Copy constructor, copies are not allowed. - */ - ScalarBase(const ScalarBase &stat); - /** - * Can't copy stats. - */ - const ScalarBase &operator=(const ScalarBase &); - public: /** * Return the current value of this stat as its base type. * @return The current value. */ - T value() const { return data()->value(params); } + Counter value() const { return data()->value(params); } public: /** @@ -831,7 +777,7 @@ class ScalarBase : public DataAccess * @param v The new value. */ template - void operator=(const U& v) { data()->set(v, params); } + void operator=(const U &v) { data()->set(v, params); } /** * Increment the stat by the given value. This calls the associated @@ -839,7 +785,7 @@ class ScalarBase : public DataAccess * @param v The value to add. */ template - void operator+=(const U& v) { data()->inc(v, params); } + void operator+=(const U &v) { data()->inc(v, params); } /** * Decrement the stat by the given value. This calls the associated @@ -847,7 +793,7 @@ class ScalarBase : public DataAccess * @param v The value to substract. */ template - void operator-=(const U& v) { data()->dec(v, params); } + void operator-=(const U &v) { data()->dec(v, params); } /** * Return the number of elements, always 1 for a scalar. @@ -867,11 +813,87 @@ class ScalarBase : public DataAccess */ void reset() { bin.reset(); } - result_t val() { return data()->val(params); } + Counter value() { return data()->value(params); } + + Result result() { return data()->result(params); } + + Result total() { return result(); } + + bool zero() { return result() == 0.0; } + +}; + +class ProxyData : public ScalarData +{ + public: + virtual void visit(Visit &visitor) { visitor.visit(*this); } + virtual bool binned() const { return false; } + virtual std::string str() const { return to_string(value()); } + virtual size_t size() const { return 1; } + virtual bool zero() const { return value() == 0; } + virtual bool check() const { return true; } + virtual void reset() { } +}; + +template +class ValueProxy : public ProxyData +{ + private: + T *scalar; + + public: + ValueProxy(T &val) : scalar(&val) {} + virtual Counter value() const { return *scalar; } + virtual Result result() const { return *scalar; } + virtual Result total() const { return *scalar; } +}; + +template +class FunctorProxy : public ProxyData +{ + private: + T *functor; + + public: + FunctorProxy(T &func) : functor(&func) {} + virtual Counter value() const { return (*functor)(); } + virtual Result result() const { return (*functor)(); } + virtual Result total() const { return (*functor)(); } +}; + +class ValueBase : public DataAccess +{ + private: + ProxyData *proxy; + + public: + ValueBase() : proxy(NULL) { } + ~ValueBase() { if (proxy) delete proxy; } - result_t total() { return val(); } + template + void scalar(T &value) + { + proxy = new ValueProxy(value); + setInit(); + } - bool zero() { return val() == 0.0; } + template + void functor(T &func) + { + proxy = new FunctorProxy(func); + setInit(); + } + + Counter value() { return proxy->value(); } + Result result() const { return proxy->result(); } + Result total() const { return proxy->total(); }; + size_t size() const { return proxy->size(); } + + bool binned() const { return proxy->binned(); } + std::string str() const { return proxy->str(); } + bool zero() const { return proxy->zero(); } + bool check() const { return proxy != NULL; } + void reset() { } }; ////////////////////////////////////////////////////////////////////// @@ -879,23 +901,21 @@ class ScalarBase : public DataAccess // Vector Statistics // ////////////////////////////////////////////////////////////////////// -template class Storage, class Bin> +template class ScalarProxy; /** * Implementation of a vector of stats. The type of stat is determined by the * Storage class. @sa ScalarBase */ -template class Storage, class Bin> +template class VectorBase : public DataAccess { - protected: - /** Define the type of the storage class. */ - typedef Storage storage_t; + public: /** Define the params of the storage class. */ - typedef typename storage_t::Params params_t; + typedef typename Storage::Params params_t; /** Define the bin type. */ - typedef typename Bin::VectorBin bin_t; + typedef typename Bin::template VectorBin bin_t; protected: /** The bin of this stat. */ @@ -909,37 +929,37 @@ class VectorBase : public DataAccess * @param index The vector index to access. * @return The storage object at the given index. */ - storage_t *data(int index) { return bin.data(index, params); } + Storage *data(int index) { return bin.data(index, params); } /** * Retrieve a const pointer to the storage from the bin * for the given index. * @param index The vector index to access. * @return A const pointer to the storage object at the given index. */ - const storage_t *data(int index) const + const Storage *data(int index) const { bin_t *_bin = const_cast(&bin); params_t *_params = const_cast(¶ms); return _bin->data(index, *_params); } - protected: - // Copying stats is not allowed - /** Copying stats isn't allowed. */ - VectorBase(const VectorBase &stat); - /** Copying stats isn't allowed. */ - const VectorBase &operator=(const VectorBase &); - public: + void value(VCounter &vec) const + { + vec.resize(size()); + for (int i = 0; i < size(); ++i) + vec[i] = data(i)->value(params); + } + /** * Copy the values to a local vector and return a reference to it. * @return A reference to a vector of the stat values. */ - void val(rvec_t &vec) const + void result(VResult &vec) const { vec.resize(size()); for (int i = 0; i < size(); ++i) - vec[i] = data(i)->val(params); + vec[i] = data(i)->result(params); } /** @@ -951,10 +971,10 @@ class VectorBase : public DataAccess * Return a total of all entries in this vector. * @return The total of all vector entries. */ - result_t total() const { - result_t total = 0.0; + Result total() const { + Result total = 0.0; for (int i = 0; i < size(); ++i) - total += data(i)->val(params); + total += data(i)->result(params); return total; } @@ -978,32 +998,32 @@ class VectorBase : public DataAccess VectorBase() {} /** Friend this class with the associated scalar proxy. */ - friend class ScalarProxy; + friend class ScalarProxy; /** * Return a reference (ScalarProxy) to the stat at the given index. * @param index The vector index to access. * @return A reference of the stat. */ - ScalarProxy operator[](int index); + ScalarProxy operator[](int index); void update(StatData *data) {} }; +const StatData * getStatData(const void *stat); + /** * A proxy class to access the stat at a given index in a VectorBase stat. * Behaves like a ScalarBase. */ -template class Storage, class Bin> +template class ScalarProxy { - protected: - /** Define the type of the storage class. */ - typedef Storage storage_t; + public: /** Define the params of the storage class. */ - typedef typename storage_t::Params params_t; + typedef typename Storage::Params params_t; /** Define the bin type. */ - typedef typename Bin::VectorBin bin_t; + typedef typename Bin::template VectorBin bin_t; private: /** Pointer to the bin in the parent VectorBase. */ @@ -1012,18 +1032,20 @@ class ScalarProxy params_t *params; /** The index to access in the parent VectorBase. */ int index; + /** Keep a pointer to the original stat so was can get data */ + void *stat; protected: /** * Retrieve the storage from the bin. * @return The storage from the bin for this stat. */ - storage_t *data() { return bin->data(index, *params); } + Storage *data() { return bin->data(index, *params); } /** * Retrieve a const pointer to the storage from the bin. * @return A const pointer to the storage for this stat. */ - const storage_t *data() const + const Storage *data() const { bin_t *_bin = const_cast(bin); params_t *_params = const_cast(params); @@ -1032,15 +1054,16 @@ class ScalarProxy public: /** - * Return the current value of this statas a result type. + * Return the current value of this stat as its base type. * @return The current value. */ - result_t val() const { return data()->val(*params); } + Counter value() const { return data()->value(*params); } + /** - * Return the current value of this stat as its base type. + * Return the current value of this statas a result type. * @return The current value. */ - T value() const { return data()->value(*params); } + Result result() const { return data()->result(*params); } public: /** @@ -1049,14 +1072,14 @@ class ScalarProxy * @param p The params to use. * @param i The index to access. */ - ScalarProxy(bin_t &b, params_t &p, int i) - : bin(&b), params(&p), index(i) {} + ScalarProxy(bin_t &b, params_t &p, int i, void *s) + : bin(&b), params(&p), index(i), stat(s) {} /** * Create a copy of the provided ScalarProxy. * @param sp The proxy to copy. */ ScalarProxy(const ScalarProxy &sp) - : bin(sp.bin), params(sp.params), index(sp.index) {} + : bin(sp.bin), params(sp.params), index(sp.index), stat(sp.stat) {} /** * Set this proxy equal to the provided one. * @param sp The proxy to copy. @@ -1066,6 +1089,7 @@ class ScalarProxy bin = sp.bin; params = sp.params; index = sp.index; + stat = sp.stat; return *this; } @@ -1093,7 +1117,7 @@ class ScalarProxy * @param v The new value. */ template - void operator=(const U& v) { data()->set(v, *params); } + void operator=(const U &v) { data()->set(v, *params); } /** * Increment the stat by the given value. This calls the associated @@ -1101,7 +1125,7 @@ class ScalarProxy * @param v The value to add. */ template - void operator+=(const U& v) { data()->inc(v, *params); } + void operator+=(const U &v) { data()->inc(v, *params); } /** * Decrement the stat by the given value. This calls the associated @@ -1109,7 +1133,7 @@ class ScalarProxy * @param v The value to substract. */ template - void operator-=(const U& v) { data()->dec(v, *params); } + void operator-=(const U &v) { data()->dec(v, *params); } /** * Return the number of elements, always 1 for a scalar. @@ -1127,28 +1151,33 @@ class ScalarProxy * This stat has no state. Nothing to reset */ void reset() { } + + public: + const StatData *statData() const { return getStatData(stat); } + std::string str() const + { + return csprintf("%s[%d]", this->statData()->name, index); + + } }; -template class Storage, class Bin> -inline ScalarProxy -VectorBase::operator[](int index) +template +inline ScalarProxy +VectorBase::operator[](int index) { assert (index >= 0 && index < size()); - return ScalarProxy(bin, params, index); + return ScalarProxy(bin, params, index, this); } -template class Storage, class Bin> +template class VectorProxy; -template class Storage, class Bin> +template class Vector2dBase : public DataAccess { - protected: - typedef Storage storage_t; - typedef typename storage_t::Params params_t; - public: - typedef typename Bin::VectorBin bin_t; + typedef typename Storage::Params params_t; + typedef typename Bin::template VectorBin bin_t; protected: size_t x; @@ -1157,34 +1186,29 @@ class Vector2dBase : public DataAccess params_t params; protected: - storage_t *data(int index) { return bin.data(index, params); } - const storage_t *data(int index) const + Storage *data(int index) { return bin.data(index, params); } + const Storage *data(int index) const { bin_t *_bin = const_cast(&bin); params_t *_params = const_cast(¶ms); return _bin->data(index, *_params); } - protected: - // Copying stats is not allowed - Vector2dBase(const Vector2dBase &stat); - const Vector2dBase &operator=(const Vector2dBase &); - public: Vector2dBase() {} - void update(Vector2dDataBase *data) + void update(Vector2dData *data) { int size = this->size(); - data->vec.resize(size); + data->cvec.resize(size); for (int i = 0; i < size; ++i) - data->vec[i] = this->data(i)->val(params); + data->cvec[i] = this->data(i)->value(params); } - std::string ysubname(int i) const { return (*y_subnames)[i]; } + std::string ysubname(int i) const { return (*this->y_subnames)[i]; } - friend class VectorProxy; - VectorProxy operator[](int index); + friend class VectorProxy; + VectorProxy operator[](int index); size_t size() const { return bin.size(); } bool zero() const { return data(0)->value(params) == 0.0; } @@ -1197,63 +1221,68 @@ class Vector2dBase : public DataAccess bool check() { return bin.initialized(); } }; -template class Storage, class Bin> +template class VectorProxy { - protected: - typedef Storage storage_t; - typedef typename storage_t::Params params_t; - typedef typename Bin::VectorBin bin_t; + public: + typedef typename Storage::Params params_t; + typedef typename Bin::template VectorBin bin_t; private: bin_t *bin; params_t *params; int offset; int len; + void *stat; private: - mutable rvec_t *vec; + mutable VResult *vec; - storage_t *data(int index) { + Storage *data(int index) { assert(index < len); return bin->data(offset + index, *params); } - const storage_t *data(int index) const { + const Storage *data(int index) const { bin_t *_bin = const_cast(bin); params_t *_params = const_cast(params); return _bin->data(offset + index, *_params); } public: - const rvec_t &val() const { + const VResult &result() const { if (vec) vec->resize(size()); else - vec = new rvec_t(size()); + vec = new VResult(size()); for (int i = 0; i < size(); ++i) - (*vec)[i] = data(i)->val(*params); + (*vec)[i] = data(i)->result(*params); return *vec; } - result_t total() const { - result_t total = 0.0; + Result total() const { + Result total = 0.0; for (int i = 0; i < size(); ++i) - total += data(i)->val(*params); + total += data(i)->result(*params); return total; } public: - VectorProxy(bin_t &b, params_t &p, int o, int l) - : bin(&b), params(&p), offset(o), len(l), vec(NULL) - { } + VectorProxy(bin_t &b, params_t &p, int o, int l, void *s) + : bin(&b), params(&p), offset(o), len(l), stat(s), vec(NULL) + { + } + VectorProxy(const VectorProxy &sp) : bin(sp.bin), params(sp.params), offset(sp.offset), len(sp.len), - vec(NULL) - { } - ~VectorProxy() { + stat(sp.stat), vec(NULL) + { + } + + ~VectorProxy() + { if (vec) delete vec; } @@ -1264,16 +1293,17 @@ class VectorProxy params = sp.params; offset = sp.offset; len = sp.len; + stat = sp.stat; if (vec) delete vec; vec = NULL; return *this; } - ScalarProxy operator[](int index) + ScalarProxy operator[](int index) { assert (index >= 0 && index < size()); - return ScalarProxy(*bin, *params, offset + index); + return ScalarProxy(*bin, *params, offset + index, stat); } size_t size() const { return len; } @@ -1290,13 +1320,13 @@ class VectorProxy void reset() { } }; -template class Storage, class Bin> -inline VectorProxy -Vector2dBase::operator[](int index) +template +inline VectorProxy +Vector2dBase::operator[](int index) { int offset = index * y; assert (index >= 0 && offset < size()); - return VectorProxy(bin, params, offset, y); + return VectorProxy(bin, params, offset, y, this); } ////////////////////////////////////////////////////////////////////// @@ -1308,7 +1338,6 @@ Vector2dBase::operator[](int index) /** * Templatized storage and interface for a distrbution stat. */ -template struct DistStor { public: @@ -1316,11 +1345,11 @@ struct DistStor struct Params { /** The minimum value to track. */ - int min; + Counter min; /** The maximum value to track. */ - int max; + Counter max; /** The number of entries in each bucket. */ - int bucket_size; + Counter bucket_size; /** The number of buckets. Equal to (max-min)/bucket_size. */ int size; }; @@ -1328,21 +1357,21 @@ struct DistStor private: /** The smallest value sampled. */ - T min_val; + Counter min_val; /** The largest value sampled. */ - T max_val; + Counter max_val; /** The number of values sampled less than min. */ - T underflow; + Counter underflow; /** The number of values sampled more than max. */ - T overflow; + Counter overflow; /** The current sum. */ - T sum; + Counter sum; /** The sum of squares. */ - T squares; + Counter squares; /** The number of samples. */ - int samples; + Counter samples; /** Counter for each bucket. */ - std::vector vec; + VCounter cvec; public: /** @@ -1350,8 +1379,9 @@ struct DistStor * @param params The parameters. */ DistStor(const Params ¶ms) - : min_val(INT_MAX), max_val(INT_MIN), underflow(0), overflow(0), - sum(T()), squares(T()), samples(0), vec(params.size) + : min_val(INT_MAX), max_val(INT_MIN), underflow(Counter()), + overflow(Counter()), sum(Counter()), squares(Counter()), + samples(Counter()), cvec(params.size) { reset(); } @@ -1362,16 +1392,16 @@ struct DistStor * @param number The number of times to add the value. * @param params The paramters of the distribution. */ - void sample(T val, int number, const Params ¶ms) + void sample(Counter val, int number, const Params ¶ms) { if (val < params.min) underflow += number; else if (val > params.max) overflow += number; else { - int index = (val - params.min) / params.bucket_size; + int index = (int)floor((val - params.min) / params.bucket_size); assert(index < size(params)); - vec[index] += number; + cvec[index] += number; } if (val < min_val) @@ -1380,7 +1410,7 @@ struct DistStor if (val > max_val) max_val = val; - T sample = val * number; + Counter sample = val * number; sum += sample; squares += sample * sample; samples += number; @@ -1391,7 +1421,7 @@ struct DistStor * @return the number of buckets. * @todo Is it faster to return the size from the parameters? */ - size_t size(const Params &) const { return vec.size(); } + size_t size(const Params &) const { return cvec.size(); } /** * Returns true if any calls to sample have been made. @@ -1400,27 +1430,23 @@ struct DistStor */ bool zero(const Params ¶ms) const { - return samples == 0; + return samples == Counter(); } - void update(DistDataData *data, DisplayMode mode, const Params ¶ms) + void update(DistDataData *data, const Params ¶ms) { data->min = params.min; data->max = params.max; data->bucket_size = params.bucket_size; data->size = params.size; - if (mode == mode_m5) - data->min_val = (min_val == INT_MAX) ? params.min : min_val; - else - data->min_val = params.min; - + data->min_val = (min_val == INT_MAX) ? 0 : min_val; data->max_val = (max_val == INT_MIN) ? 0 : max_val; data->underflow = underflow; data->overflow = overflow; - data->vec.resize(params.size); + data->cvec.resize(params.size); for (int i = 0; i < params.size; ++i) - data->vec[i] = vec[i]; + data->cvec[i] = cvec[i]; data->sum = sum; data->squares = squares; @@ -1437,13 +1463,13 @@ struct DistStor underflow = 0; overflow = 0; - int size = vec.size(); + int size = cvec.size(); for (int i = 0; i < size; ++i) - vec[i] = T(); + cvec[i] = Counter(); - sum = T(); - squares = T(); - samples = T(); + sum = Counter(); + squares = Counter(); + samples = Counter(); } }; @@ -1451,7 +1477,6 @@ struct DistStor * Templatized storage and interface for a distribution that calculates mean * and variance. */ -template struct FancyStor { public: @@ -1463,17 +1488,19 @@ struct FancyStor private: /** The current sum. */ - T sum; + Counter sum; /** The sum of squares. */ - T squares; + Counter squares; /** The number of samples. */ - int samples; + Counter samples; public: /** * Create and initialize this storage. */ - FancyStor(const Params &) : sum(T()), squares(T()), samples(0) {} + FancyStor(const Params &) + : sum(Counter()), squares(Counter()), samples(Counter()) + { } /** * Add a value the given number of times to this running average. @@ -1483,15 +1510,15 @@ struct FancyStor * @param number The number of times to add the value. * @param p The parameters of this stat. */ - void sample(T val, int number, const Params &p) + void sample(Counter val, int number, const Params &p) { - T value = val * number; + Counter value = val * number; sum += value; squares += value * value; samples += number; } - void update(DistDataData *data, DisplayMode mode, const Params ¶ms) + void update(DistDataData *data, const Params ¶ms) { data->sum = sum; data->squares = squares; @@ -1508,16 +1535,16 @@ struct FancyStor * Return true if no samples have been added. * @return True if no samples have been added. */ - bool zero(const Params &) const { return samples == 0; } + bool zero(const Params &) const { return samples == Counter(); } /** * Reset stat value to default */ void reset() { - sum = T(); - squares = T(); - samples = 0; + sum = Counter(); + squares = Counter(); + samples = Counter(); } }; @@ -1525,7 +1552,6 @@ struct FancyStor * Templatized storage for distribution that calculates per cycle mean and * variance. */ -template struct AvgFancy { public: @@ -1535,15 +1561,15 @@ struct AvgFancy private: /** Current total. */ - T sum; + Counter sum; /** Current sum of squares. */ - T squares; + Counter squares; public: /** * Create and initialize this storage. */ - AvgFancy(const Params &) : sum(T()), squares(T()) {} + AvgFancy(const Params &) : sum(Counter()), squares(Counter()) {} /** * Add a value to the distribution for the given number of times. @@ -1552,14 +1578,14 @@ struct AvgFancy * @param number The number of times to add the value. * @param p The paramters of the distribution. */ - void sample(T val, int number, const Params& p) + void sample(Counter val, int number, const Params &p) { - T value = val * number; + Counter value = val * number; sum += value; squares += value * value; } - void update(DistDataData *data, DisplayMode mode, const Params ¶ms) + void update(DistDataData *data, const Params ¶ms) { data->sum = sum; data->squares = squares; @@ -1575,14 +1601,14 @@ struct AvgFancy * Return true if no samples have been added. * @return True if the sum is zero. */ - bool zero(const Params ¶ms) const { return sum == 0; } + bool zero(const Params ¶ms) const { return sum == Counter(); } /** * Reset stat value to default */ void reset() { - sum = T(); - squares = T(); + sum = Counter(); + squares = Counter(); } }; @@ -1590,16 +1616,14 @@ struct AvgFancy * Implementation of a distribution stat. The type of distribution is * determined by the Storage template. @sa ScalarBase */ -template class Storage, class Bin> +template class DistBase : public DataAccess { - protected: - /** Define the type of the storage class. */ - typedef Storage storage_t; + public: /** Define the params of the storage class. */ - typedef typename storage_t::Params params_t; + typedef typename Storage::Params params_t; /** Define the bin type. */ - typedef typename Bin::Bin bin_t; + typedef typename Bin::template Bin bin_t; protected: /** The bin of this stat. */ @@ -1612,25 +1636,18 @@ class DistBase : public DataAccess * Retrieve the storage from the bin. * @return The storage object for this stat. */ - storage_t *data() { return bin.data(params); } + Storage *data() { return bin.data(params); } /** * Retrieve a const pointer to the storage from the bin. * @return A const pointer to the storage object for this stat. */ - const storage_t *data() const + const Storage *data() const { bin_t *_bin = const_cast(&bin); params_t *_params = const_cast(¶ms); return _bin->data(*_params); } - protected: - // Copying stats is not allowed - /** Copies are not allowed. */ - DistBase(const DistBase &stat); - /** Copies are not allowed. */ - const DistBase &operator=(const DistBase &); - public: DistBase() { } @@ -1641,7 +1658,7 @@ class DistBase : public DataAccess * @param n The number of times to add it, defaults to 1. */ template - void sample(const U& v, int n = 1) { data()->sample(v, n, params); } + void sample(const U &v, int n = 1) { data()->sample(v, n, params); } /** * Return the number of entries in this stat. @@ -1654,10 +1671,10 @@ class DistBase : public DataAccess */ bool zero() const { return data()->zero(params); } - void update(DistDataBase *base) + void update(DistData *base) { - base->data.fancy = storage_t::fancy; - data()->update(&(base->data), base->mode, params); + base->data.fancy = Storage::fancy; + data()->update(&(base->data), params); } /** * @return True is stat is binned. @@ -1674,43 +1691,35 @@ class DistBase : public DataAccess bool check() { return bin.initialized(); } }; -template class Storage, class Bin> +template class DistProxy; -template class Storage, class Bin> +template class VectorDistBase : public DataAccess { - protected: - typedef Storage storage_t; - typedef typename storage_t::Params params_t; - public: - typedef typename Bin::VectorBin bin_t; + typedef typename Storage::Params params_t; + typedef typename Bin::template VectorBin bin_t; protected: bin_t bin; params_t params; protected: - storage_t *data(int index) { return bin.data(index, params); } - const storage_t *data(int index) const + Storage *data(int index) { return bin.data(index, params); } + const Storage *data(int index) const { bin_t *_bin = const_cast(&bin); params_t *_params = const_cast(¶ms); return _bin->data(index, *_params); } - protected: - // Copying stats is not allowed - VectorDistBase(const VectorDistBase &stat); - const VectorDistBase &operator=(const VectorDistBase &); - public: VectorDistBase() {} - friend class DistProxy; - DistProxy operator[](int index); - const DistProxy operator[](int index) const; + friend class DistProxy; + DistProxy operator[](int index); + const DistProxy operator[](int index) const; size_t size() const { return bin.size(); } bool zero() const { return false; } @@ -1725,25 +1734,24 @@ class VectorDistBase : public DataAccess void reset() { bin.reset(); } bool check() { return bin.initialized(); } - void update(VectorDistDataBase *base) + void update(VectorDistData *base) { int size = this->size(); base->data.resize(size); for (int i = 0; i < size; ++i) { - base->data[i].fancy = storage_t::fancy; - data(i)->update(&(base->data[i]), base->mode, params); + base->data[i].fancy = Storage::fancy; + data(i)->update(&(base->data[i]), params); } } }; -template class Storage, class Bin> +template class DistProxy { - protected: - typedef Storage storage_t; - typedef typename storage_t::Params params_t; - typedef typename Bin::Bin bin_t; - typedef VectorDistBase base_t; + public: + typedef typename Storage::Params params_t; + typedef typename Bin::template Bin bin_t; + typedef VectorDistBase base_t; private: union { @@ -1753,11 +1761,11 @@ class DistProxy int index; protected: - storage_t *data() { return stat->data(index); } - const storage_t *data() const { return cstat->data(index); } + Storage *data() { return stat->data(index); } + const Storage *data() const { return cstat->data(index); } public: - DistProxy(const VectorDistBase &s, int i) + DistProxy(const VectorDistBase &s, int i) : cstat(&s), index(i) {} DistProxy(const DistProxy &sp) : cstat(sp.cstat), index(sp.index) {} @@ -1767,7 +1775,7 @@ class DistProxy public: template - void sample(const U& v, int n = 1) { data()->sample(v, n, cstat->params); } + void sample(const U &v, int n = 1) { data()->sample(v, n, cstat->params); } size_t size() const { return 1; } bool zero() const { return data()->zero(cstat->params); } @@ -1782,30 +1790,30 @@ class DistProxy void reset() { } }; -template class Storage, class Bin> -inline DistProxy -VectorDistBase::operator[](int index) +template +inline DistProxy +VectorDistBase::operator[](int index) { assert (index >= 0 && index < size()); - return DistProxy(*this, index); + return DistProxy(*this, index); } -template class Storage, class Bin> -inline const DistProxy -VectorDistBase::operator[](int index) const +template +inline const DistProxy +VectorDistBase::operator[](int index) const { assert (index >= 0 && index < size()); - return DistProxy(*this, index); + return DistProxy(*this, index); } #if 0 -template class Storage, class Bin> -result_t -VectorDistBase::total(int index) const +template +Result +VectorDistBase::total(int index) const { int total = 0; for (int i=0; i < x_size(); ++i) { - total += data(i)->val(*params); + total += data(i)->result(*params); } } #endif @@ -1832,17 +1840,22 @@ class Node : public RefCounted * Return the result vector of this subtree. * @return The result vector of this subtree. */ - virtual const rvec_t &val() const = 0; + virtual const VResult &result() const = 0; /** * Return the total of the result vector. * @return The total of the result vector. */ - virtual result_t total() const = 0; + virtual Result total() const = 0; /** * Return true if stat is binned. *@return True is stat is binned. */ virtual bool binned() const = 0; + + /** + * + */ + virtual std::string str() const = 0; }; /** Reference counting pointer to a function Node. */ @@ -1851,17 +1864,17 @@ typedef RefCountingPtr NodePtr; class ScalarStatNode : public Node { private: - const ScalarDataBase *data; - mutable rvec_t result; + const ScalarData *data; + mutable VResult vresult; public: - ScalarStatNode(const ScalarDataBase *d) : data(d), result(1) {} - virtual const rvec_t &val() const + ScalarStatNode(const ScalarData *d) : data(d), vresult(1) {} + virtual const VResult &result() const { - result[0] = data->val(); - return result; + vresult[0] = data->result(); + return vresult; } - virtual result_t total() const { return data->val(); }; + virtual Result total() const { return data->result(); }; virtual size_t size() const { return 1; } /** @@ -1869,24 +1882,29 @@ class ScalarStatNode : public Node *@return True is stat is binned. */ virtual bool binned() const { return data->binned(); } + + /** + * + */ + virtual std::string str() const { return data->name; } }; -template class Storage, class Bin> +template class ScalarProxyNode : public Node { private: - const ScalarProxy proxy; - mutable rvec_t result; + const ScalarProxy proxy; + mutable VResult vresult; public: - ScalarProxyNode(const ScalarProxy &p) - : proxy(p), result(1) { } - virtual const rvec_t &val() const + ScalarProxyNode(const ScalarProxy &p) + : proxy(p), vresult(1) { } + virtual const VResult &result() const { - result[0] = proxy.val(); - return result; + vresult[0] = proxy.result(); + return vresult; } - virtual result_t total() const { return proxy.val(); }; + virtual Result total() const { return proxy.result(); }; virtual size_t size() const { return 1; } /** @@ -1894,17 +1912,22 @@ class ScalarProxyNode : public Node *@return True is stat is binned. */ virtual bool binned() const { return proxy.binned(); } + + /** + * + */ + virtual std::string str() const { return proxy.str(); } }; class VectorStatNode : public Node { private: - const VectorDataBase *data; + const VectorData *data; public: - VectorStatNode(const VectorDataBase *d) : data(d) { } - virtual const rvec_t &val() const { return data->val(); } - virtual result_t total() const { return data->total(); }; + VectorStatNode(const VectorData *d) : data(d) { } + virtual const VResult &result() const { return data->result(); } + virtual Result total() const { return data->total(); }; virtual size_t size() const { return data->size(); } /** @@ -1912,71 +1935,68 @@ class VectorStatNode : public Node *@return True is stat is binned. */ virtual bool binned() const { return data->binned(); } + + virtual std::string str() const { return data->name; } }; -template +template class ConstNode : public Node { private: - rvec_t data; + VResult vresult; public: - ConstNode(T s) : data(1, (result_t)s) {} - const rvec_t &val() const { return data; } - virtual result_t total() const { return data[0]; }; - + ConstNode(T s) : vresult(1, (Result)s) {} + const VResult &result() const { return vresult; } + virtual Result total() const { return vresult[0]; }; virtual size_t size() const { return 1; } + /** * Return true if stat is binned. *@return False since constants aren't binned. */ virtual bool binned() const { return false; } + + virtual std::string str() const { return to_string(vresult[0]); } }; -template -class FunctorNode : public Node +template +struct OpString; + +template<> +struct OpString > { - private: - T &functor; - mutable rvec_t result; + static std::string str() { return "+"; } +}; - public: - FunctorNode(T &f) : functor(f) { result.resize(1); } - const rvec_t &val() const { - result[0] = (result_t)functor(); - return result; - } - virtual result_t total() const { return (result_t)functor(); }; +template<> +struct OpString > +{ + static std::string str() { return "-"; } +}; - virtual size_t size() const { return 1; } - /** - * Return true if stat is binned. - *@return False since Functors aren't binned - */ - virtual bool binned() const { return false; } +template<> +struct OpString > +{ + static std::string str() { return "*"; } }; -template -class ScalarNode : public Node +template<> +struct OpString > { - private: - T &scalar; - mutable rvec_t result; + static std::string str() { return "/"; } +}; - public: - ScalarNode(T &s) : scalar(s) { result.resize(1); } - const rvec_t &val() const { - result[0] = (result_t)scalar; - return result; - } - virtual result_t total() const { return (result_t)scalar; }; +template<> +struct OpString > +{ + static std::string str() { return "%"; } +}; - virtual size_t size() const { return 1; } - /** - * Return true if stat is binned. - *@return False since Scalar's aren't binned - */ - virtual bool binned() const { return false; } +template<> +struct OpString > +{ + static std::string str() { return "-"; } }; template @@ -1984,26 +2004,27 @@ class UnaryNode : public Node { public: NodePtr l; - mutable rvec_t result; + mutable VResult vresult; public: - UnaryNode(NodePtr p) : l(p) {} + UnaryNode(NodePtr &p) : l(p) {} - const rvec_t &val() const { - const rvec_t &lvec = l->val(); + const VResult &result() const + { + const VResult &lvec = l->result(); int size = lvec.size(); assert(size > 0); - result.resize(size); + vresult.resize(size); Op op; for (int i = 0; i < size; ++i) - result[i] = op(lvec[i]); + vresult[i] = op(lvec[i]); - return result; + return vresult; } - result_t total() const { + Result total() const { Op op; return op(l->total()); } @@ -2014,6 +2035,11 @@ class UnaryNode : public Node *@return True if child of node is binned. */ virtual bool binned() const { return l->binned(); } + + virtual std::string str() const + { + return OpString::str() + l->str(); + } }; template @@ -2022,42 +2048,43 @@ class BinaryNode : public Node public: NodePtr l; NodePtr r; - mutable rvec_t result; + mutable VResult vresult; public: - BinaryNode(NodePtr a, NodePtr b) : l(a), r(b) {} + BinaryNode(NodePtr &a, NodePtr &b) : l(a), r(b) {} - const rvec_t &val() const { + const VResult &result() const + { Op op; - const rvec_t &lvec = l->val(); - const rvec_t &rvec = r->val(); + const VResult &lvec = l->result(); + const VResult &rvec = r->result(); assert(lvec.size() > 0 && rvec.size() > 0); if (lvec.size() == 1 && rvec.size() == 1) { - result.resize(1); - result[0] = op(lvec[0], rvec[0]); + vresult.resize(1); + vresult[0] = op(lvec[0], rvec[0]); } else if (lvec.size() == 1) { int size = rvec.size(); - result.resize(size); + vresult.resize(size); for (int i = 0; i < size; ++i) - result[i] = op(lvec[0], rvec[i]); + vresult[i] = op(lvec[0], rvec[i]); } else if (rvec.size() == 1) { int size = lvec.size(); - result.resize(size); + vresult.resize(size); for (int i = 0; i < size; ++i) - result[i] = op(lvec[i], rvec[0]); + vresult[i] = op(lvec[i], rvec[0]); } else if (rvec.size() == lvec.size()) { int size = rvec.size(); - result.resize(size); + vresult.resize(size); for (int i = 0; i < size; ++i) - result[i] = op(lvec[i], rvec[i]); + vresult[i] = op(lvec[i], rvec[i]); } - return result; + return vresult; } - result_t total() const { + Result total() const { Op op; return op(l->total(), r->total()); } @@ -2079,6 +2106,11 @@ class BinaryNode : public Node *@return True if either child of node is binned. */ virtual bool binned() const { return (l->binned() || r->binned()); } + + virtual std::string str() const + { + return csprintf("(%s %s %s)", l->str(), OpString::str(), r->str()); + } }; template @@ -2086,37 +2118,39 @@ class SumNode : public Node { public: NodePtr l; - mutable rvec_t result; + mutable VResult vresult; public: - SumNode(NodePtr p) : l(p), result(1) {} + SumNode(NodePtr &p) : l(p), vresult(1) {} - const rvec_t &val() const { - const rvec_t &lvec = l->val(); + const VResult &result() const + { + const VResult &lvec = l->result(); int size = lvec.size(); assert(size > 0); - result[0] = 0.0; + vresult[0] = 0.0; Op op; for (int i = 0; i < size; ++i) - result[0] = op(result[0], lvec[i]); + vresult[0] = op(vresult[0], lvec[i]); - return result; + return vresult; } - result_t total() const { - const rvec_t &lvec = l->val(); + Result total() const + { + const VResult &lvec = l->result(); int size = lvec.size(); assert(size > 0); - result_t result = 0.0; + Result vresult = 0.0; Op op; for (int i = 0; i < size; ++i) - result = op(result, lvec[i]); + vresult = op(vresult, lvec[i]); - return result; + return vresult; } virtual size_t size() const { return 1; } @@ -2125,270 +2159,13 @@ class SumNode : public Node *@return True if child of node is binned. */ virtual bool binned() const { return l->binned(); } -}; - -////////////////////////////////////////////////////////////////////// -// -// Binning Interface -// -////////////////////////////////////////////////////////////////////// -struct MainBin -{ - private: - std::string _name; - char *mem; - - protected: - off_t memsize; - off_t size() const { return memsize; } - char *memory(off_t off); - public: - static MainBin *&curBin() + virtual std::string str() const { - static MainBin *current = NULL; - return current; + return csprintf("total(%s)", l->str()); } - - static void setCurBin(MainBin *bin) { curBin() = bin; } - static MainBin *current() { assert(curBin()); return curBin(); } - - static off_t &offset() - { - static off_t offset = 0; - return offset; - } - - static off_t new_offset(size_t size) - { - size_t mask = sizeof(u_int64_t) - 1; - off_t off = offset(); - - // That one is for the last trailing flags byte. - offset() += (size + 1 + mask) & ~mask; - return off; - } - - public: - MainBin(const std::string &name); - ~MainBin(); - - const std::string & - name() const - { - return _name; - } - - void - activate() - { - setCurBin(this); -#ifdef FS_MEASURE - DPRINTF(TCPIP, "activating %s Bin\n", name()); -#endif - } - - class BinBase - { - private: - int offset; - - public: - BinBase() : offset(-1) {} - void allocate(size_t size) - { - offset = new_offset(size); - } - char *access() - { - assert(offset != -1); - return current()->memory(offset); - } - }; - - template - class Bin : public BinBase - { - public: - typedef typename Storage::Params Params; - - public: - enum { binned = true }; - Bin() { allocate(sizeof(Storage)); } - bool initialized() const { return true; } - void init(Params ¶ms) { } - - int size() const { return 1; } - - Storage * - data(Params ¶ms) - { - assert(initialized()); - char *ptr = access(); - char *flags = ptr + sizeof(Storage); - if (!(*flags & 0x1)) { - *flags |= 0x1; - new (ptr) Storage(params); - } - return reinterpret_cast(ptr); - } - - void - reset() - { - char *ptr = access(); - char *flags = ptr + size() * sizeof(Storage); - if (!(*flags & 0x1)) - return; - - Storage *s = reinterpret_cast(ptr); - s->reset(); - } - }; - - template - class VectorBin : public BinBase - { - public: - typedef typename Storage::Params Params; - - private: - int _size; - - public: - enum { binned = true }; - VectorBin() : _size(0) {} - - bool initialized() const { return _size > 0; } - void init(int s, Params ¶ms) - { - assert(!initialized()); - assert(s > 0); - _size = s; - allocate(_size * sizeof(Storage)); - } - - int size() const { return _size; } - - Storage *data(int index, Params ¶ms) - { - assert(initialized()); - assert(index >= 0 && index < size()); - char *ptr = access(); - char *flags = ptr + size() * sizeof(Storage); - if (!(*flags & 0x1)) { - *flags |= 0x1; - for (int i = 0; i < size(); ++i) - new (ptr + i * sizeof(Storage)) Storage(params); - } - return reinterpret_cast(ptr + index * sizeof(Storage)); - } - void reset() - { - char *ptr = access(); - char *flags = ptr + size() * sizeof(Storage); - if (!(*flags & 0x1)) - return; - - for (int i = 0; i < _size; ++i) { - char *p = ptr + i * sizeof(Storage); - Storage *s = reinterpret_cast(p); - s->reset(); - } - } - }; }; -struct NoBin -{ - template - struct Bin - { - public: - typedef typename Storage::Params Params; - enum { binned = false }; - - private: - char ptr[sizeof(Storage)]; - - public: - ~Bin() - { - reinterpret_cast(ptr)->~Storage(); - } - - bool initialized() const { return true; } - void init(Params ¶ms) - { - new (ptr) Storage(params); - } - int size() const{ return 1; } - Storage *data(Params ¶ms) - { - assert(initialized()); - return reinterpret_cast(ptr); - } - void reset() - { - Storage *s = reinterpret_cast(ptr); - s->reset(); - } - }; - - template - struct VectorBin - { - public: - typedef typename Storage::Params Params; - enum { binned = false }; - - private: - char *ptr; - int _size; - - public: - VectorBin() : ptr(NULL) { } - ~VectorBin() - { - if (!initialized()) - return; - - for (int i = 0; i < _size; ++i) { - char *p = ptr + i * sizeof(Storage); - reinterpret_cast(p)->~Storage(); - } - delete [] ptr; - } - - bool initialized() const { return ptr != NULL; } - void init(int s, Params ¶ms) - { - assert(s > 0 && "size must be positive!"); - assert(!initialized()); - _size = s; - ptr = new char[_size * sizeof(Storage)]; - for (int i = 0; i < _size; ++i) - new (ptr + i * sizeof(Storage)) Storage(params); - } - - int size() const { return _size; } - - Storage *data(int index, Params ¶ms) - { - assert(initialized()); - assert(index >= 0 && index < size()); - return reinterpret_cast(ptr + index * sizeof(Storage)); - } - void reset() - { - for (int i = 0; i < _size; ++i) { - char *p = ptr + i * sizeof(Storage); - Storage *s = reinterpret_cast(p); - s->reset(); - } - } - }; -}; ////////////////////////////////////////////////////////////////////// // @@ -2408,7 +2185,7 @@ struct NoBin * binned. If the typedef is NoBin, nothing is binned. If it is * MainBin, then all stats are binned under that Bin. */ -#ifdef FS_MEASURE +#if STATS_BINNING typedef MainBin DefaultBin; #else typedef NoBin DefaultBin; @@ -2418,16 +2195,19 @@ typedef NoBin DefaultBin; * This is a simple scalar statistic, like a counter. * @sa Stat, ScalarBase, StatStor */ -template -class Scalar : public Wrap, ScalarBase, ScalarData> +template +class Scalar + : public Wrap, + ScalarBase, + ScalarStatData> { public: /** The base implementation. */ - typedef ScalarBase Base; + typedef ScalarBase Base; Scalar() { - setInit(); + this->setInit(); } /** @@ -2436,23 +2216,50 @@ class Scalar : public Wrap, ScalarBase, ScalarD * @param v The new value. */ template - void operator=(const U& v) { Base::operator=(v); } + void operator=(const U &v) { Base::operator=(v); } +}; + +class Value + : public Wrap +{ + public: + /** The base implementation. */ + typedef ValueBase Base; + + template + Value &scalar(T &value) + { + Base::scalar(value); + return *this; + } + + template + Value &functor(T &func) + { + Base::functor(func); + return *this; + } }; /** * A stat that calculates the per cycle average of a value. * @sa Stat, ScalarBase, AvgStor */ -template -class Average : public Wrap, ScalarBase, ScalarData> +template +class Average + : public Wrap, + ScalarBase, + ScalarStatData> { public: /** The base implementation. */ - typedef ScalarBase Base; + typedef ScalarBase Base; Average() { - setInit(); + this->setInit(); } /** @@ -2461,25 +2268,31 @@ class Average : public Wrap, ScalarBase, Scalar * @param v The new value. */ template - void operator=(const U& v) { Base::operator=(v); } + void operator=(const U &v) { Base::operator=(v); } }; /** * A vector of scalar stats. * @sa Stat, VectorBase, StatStor */ -template -class Vector : public WrapVec, VectorBase, VectorData> +template +class Vector + : public WrapVec, + VectorBase, + VectorStatData> { public: + /** The base implementation. */ + typedef ScalarBase Base; + /** * Set this vector to have the given size. * @param size The new size. * @return A reference to this stat. */ Vector &init(size_t size) { - bin.init(size, params); - setInit(); + this->bin.init(size, this->params); + this->setInit(); return *this; } @@ -2489,8 +2302,11 @@ class Vector : public WrapVec, VectorBase, Vect * A vector of Average stats. * @sa Stat, VectorBase, AvgStor */ -template -class AverageVector : public WrapVec, VectorBase, VectorData> +template +class AverageVector + : public WrapVec, + VectorBase, + VectorStatData> { public: /** @@ -2499,8 +2315,8 @@ class AverageVector : public WrapVec, VectorBasebin.init(size, this->params); + this->setInit(); return *this; } @@ -2510,15 +2326,18 @@ class AverageVector : public WrapVec, VectorBase -class Vector2d : public WrapVec2d, Vector2dBase, Vector2dData> +template +class Vector2d + : public WrapVec2d, + Vector2dBase, + Vector2dStatData> { public: Vector2d &init(size_t _x, size_t _y) { - statData()->x = x = _x; - statData()->y = y = _y; - bin.init(x * y, params); - setInit(); + this->statData()->x = this->x = _x; + this->statData()->y = this->y = _y; + this->bin.init(this->x * this->y, this->params); + this->setInit(); return *this; } @@ -2528,14 +2347,17 @@ class Vector2d : public WrapVec2d, Vector2dBase -class Distribution : public Wrap, DistBase, DistData> +template +class Distribution + : public Wrap, + DistBase, + DistStatData> { - private: + public: /** Base implementation. */ - typedef DistBase Base; + typedef DistBase Base; /** The Parameter type. */ - typedef typename DistStor::Params Params; + typedef typename DistStor::Params Params; public: /** @@ -2545,13 +2367,13 @@ class Distribution : public Wrap, DistBaseparams.min = min; + this->params.max = max; + this->params.bucket_size = bkt; + this->params.size = (int)rint((max - min) / bkt + 1.0); + this->bin.init(this->params); + this->setInit(); return *this; } @@ -2561,22 +2383,25 @@ class Distribution : public Wrap, DistBase -class StandardDeviation : public Wrap, DistBase, DistData> +template +class StandardDeviation + : public Wrap, + DistBase, + DistStatData> { - private: + public: /** The base implementation */ - typedef DistBase Base; + typedef DistBase Base; /** The parameter type. */ - typedef typename DistStor::Params Params; + typedef typename DistStor::Params Params; public: /** * Construct and initialize this distribution. */ StandardDeviation() { - bin.init(params); - setInit(); + this->bin.init(this->params); + this->setInit(); } }; @@ -2584,14 +2409,17 @@ class StandardDeviation : public Wrap, DistBase -class AverageDeviation : public Wrap, DistBase, DistData> +template +class AverageDeviation + : public Wrap, + DistBase, + DistStatData> { - private: + public: /** The base implementation */ - typedef DistBase Base; + typedef DistBase Base; /** The parameter type. */ - typedef typename DistStor::Params Params; + typedef typename DistStor::Params Params; public: /** @@ -2599,8 +2427,8 @@ class AverageDeviation : public Wrap, DistBasebin.init(this->params); + this->setInit(); } }; @@ -2608,14 +2436,17 @@ class AverageDeviation : public Wrap, DistBase -class VectorDistribution : public WrapVec, VectorDistBase, VectorDistData> +template +class VectorDistribution + : public WrapVec, + VectorDistBase, + VectorDistStatData> { - private: + public: /** The base implementation */ - typedef VectorDistBase Base; + typedef VectorDistBase Base; /** The parameter type. */ - typedef typename DistStor::Params Params; + typedef typename DistStor::Params Params; public: /** @@ -2626,13 +2457,13 @@ class VectorDistribution : public WrapVec, VectorDist * @param bkt The number of values in each bucket. * @return A reference to this distribution. */ - VectorDistribution &init(int size, T min, T max, int bkt) { - params.min = min; - params.max = max; - params.bucket_size = bkt; - params.size = (max - min) / bkt + 1; - bin.init(size, params); - setInit(); + VectorDistribution &init(int size, Counter min, Counter max, Counter bkt) { + this->params.min = min; + this->params.max = max; + this->params.bucket_size = bkt; + this->params.size = (int)rint((max - min) / bkt + 1.0); + this->bin.init(size, this->params); + this->setInit(); return *this; } @@ -2642,14 +2473,17 @@ class VectorDistribution : public WrapVec, VectorDist * This is a vector of StandardDeviation stats. * @sa Stat, VectorDistBase, FancyStor */ -template -class VectorStandardDeviation : public WrapVec, VectorDistBase, VectorDistData> +template +class VectorStandardDeviation + : public WrapVec, + VectorDistBase, + VectorDistStatData> { - private: + public: /** The base implementation */ - typedef VectorDistBase Base; + typedef VectorDistBase Base; /** The parameter type. */ - typedef typename DistStor::Params Params; + typedef typename DistStor::Params Params; public: /** @@ -2658,8 +2492,8 @@ class VectorStandardDeviation : public WrapVec, * @return A reference to this distribution. */ VectorStandardDeviation &init(int size) { - bin.init(size, params); - setInit(); + this->bin.init(size, this->params); + this->setInit(); return *this; } @@ -2669,14 +2503,17 @@ class VectorStandardDeviation : public WrapVec, * This is a vector of AverageDeviation stats. * @sa Stat, VectorDistBase, AvgFancy */ -template -class VectorAverageDeviation : public WrapVec, VectorDistBase, VectorDistData> +template +class VectorAverageDeviation + : public WrapVec, + VectorDistBase, + VectorDistStatData> { - private: + public: /** The base implementation */ - typedef VectorDistBase Base; + typedef VectorDistBase Base; /** The parameter type. */ - typedef typename DistStor::Params Params; + typedef typename DistStor::Params Params; public: /** @@ -2685,8 +2522,8 @@ class VectorAverageDeviation : public WrapVec, Ve * @return A reference to this distribution. */ VectorAverageDeviation &init(int size) { - bin.init(size, params); - setInit(); + this->bin.init(size, this->params); + this->setInit(); return *this; } @@ -2712,7 +2549,7 @@ class FormulaBase : public DataAccess * be x[0]/y, x[1]/y, x[2]/y, respectively. * @return The result vector. */ - void val(rvec_t &vec) const; + void result(VResult &vec) const; /** * Return the total Formula result. If there is a Vector @@ -2721,10 +2558,10 @@ class FormulaBase : public DataAccess * components of the Vector. For example, if Formula is x/y where * x is size 3, then total() will return (x[1]+x[2]+x[3])/y. If * there is no Vector component, total() returns the same value as - * the first entry in the rvec_t val() returns. + * the first entry in the VResult val() returns. * @return The total of the result vector. */ - result_t total() const; + Result total() const; /** * Return the number of elements in the tree. @@ -2754,10 +2591,54 @@ class FormulaBase : public DataAccess * */ void update(StatData *); + + std::string str() const; +}; + +class FormulaData : public VectorData +{ + public: + virtual std::string str() const = 0; + virtual bool check() const { return true; } +}; + +template +class FormulaStatData : public FormulaData +{ + protected: + Stat &s; + mutable VResult vec; + mutable VCounter cvec; + + public: + FormulaStatData(Stat &stat) : s(stat) {} + + virtual bool binned() const { return s.binned(); } + virtual bool zero() const { return s.zero(); } + virtual void reset() { s.reset(); } + + virtual size_t size() const { return s.size(); } + virtual const VResult &result() const + { + s.result(vec); + return vec; + } + virtual Result total() const { return s.total(); } + virtual VCounter &value() const { return cvec; } + virtual void visit(Visit &visitor) + { + update(); + s.update(this); + visitor.visit(*this); + } + virtual std::string str() const { return s.str(); } }; class Temp; -class Formula : public WrapVec +class Formula + : public WrapVec { public: /** @@ -2791,15 +2672,17 @@ class FormulaNode : public Node { private: const Formula &formula; - mutable rvec_t vec; + mutable VResult vec; public: FormulaNode(const Formula &f) : formula(f) {} virtual size_t size() const { return formula.size(); } - virtual const rvec_t &val() const { formula.val(vec); return vec; } - virtual result_t total() const { return formula.total(); } + virtual const VResult &result() const { formula.result(vec); return vec; } + virtual Result total() const { return formula.total(); } virtual bool binned() const { return formula.binned(); } + + virtual std::string str() const { return formula.str(); } }; /** @@ -2824,31 +2707,38 @@ class Temp * Return the node pointer. * @return the node pointer. */ - operator NodePtr() { return node;} + operator NodePtr&() { return node;} public: /** * Create a new ScalarStatNode. * @param s The ScalarStat to place in a node. */ - template - Temp(const Scalar &s) + template + Temp(const Scalar &s) : node(new ScalarStatNode(s.statData())) { } /** * Create a new ScalarStatNode. * @param s The ScalarStat to place in a node. */ - template - Temp(const Average &s) + Temp(const Value &s) + : node(new ScalarStatNode(s.statData())) { } + + /** + * Create a new ScalarStatNode. + * @param s The ScalarStat to place in a node. + */ + template + Temp(const Average &s) : node(new ScalarStatNode(s.statData())) { } /** * Create a new VectorStatNode. * @param s The VectorStat to place in a node. */ - template - Temp(const Vector &s) + template + Temp(const Vector &s) : node(new VectorStatNode(s.statData())) { } /** @@ -2861,9 +2751,9 @@ class Temp * Create a new ScalarProxyNode. * @param p The ScalarProxy to place in a node. */ - template class Storage, class Bin> - Temp(const ScalarProxy &p) - : node(new ScalarProxyNode(p)) { } + template + Temp(const ScalarProxy &p) + : node(new ScalarProxyNode(p)) { } /** * Create a ConstNode @@ -2956,44 +2846,37 @@ class Temp */ void check(); -void dump(std::ostream &stream); void reset(); void registerResetCallback(Callback *cb); inline Temp operator+(Temp l, Temp r) { - return NodePtr(new BinaryNode >(l, r)); + return NodePtr(new BinaryNode >(l, r)); } inline Temp operator-(Temp l, Temp r) { - return NodePtr(new BinaryNode >(l, r)); + return NodePtr(new BinaryNode >(l, r)); } inline Temp operator*(Temp l, Temp r) { - return NodePtr(new BinaryNode >(l, r)); + return NodePtr(new BinaryNode >(l, r)); } inline Temp operator/(Temp l, Temp r) { - return NodePtr(new BinaryNode >(l, r)); -} - -inline Temp -operator%(Temp l, Temp r) -{ - return NodePtr(new BinaryNode >(l, r)); + return NodePtr(new BinaryNode >(l, r)); } inline Temp operator-(Temp l) { - return NodePtr(new UnaryNode >(l)); + return NodePtr(new UnaryNode >(l)); } template @@ -3003,27 +2886,12 @@ constant(T val) return NodePtr(new ConstNode(val)); } -template -inline Temp -functor(T &val) -{ - return NodePtr(new FunctorNode(val)); -} - -template -inline Temp -scalar(T &val) -{ - return NodePtr(new ScalarNode(val)); -} - inline Temp sum(Temp val) { - return NodePtr(new SumNode >(val)); + return NodePtr(new SumNode >(val)); } -extern bool PrintDescriptions; -} // namespace statistics +/* namespace Stats */ } -#endif // __STATISTICS_HH__ +#endif // __BASE_STATISTICS_HH__