#include <functional>
#include <iosfwd>
#include <list>
+#include <map>
+#include <memory>
#include <string>
#include <vector>
+#include "base/stats/info.hh"
+#include "base/stats/output.hh"
+#include "base/stats/types.hh"
#include "base/cast.hh"
#include "base/cprintf.hh"
#include "base/intmath.hh"
-#include "base/refcnt.hh"
-#include "base/stats/info.hh"
-#include "base/stats/types.hh"
-#include "base/stats/visit.hh"
#include "base/str.hh"
#include "base/types.hh"
class Callback;
/** The current simulated tick. */
-extern Tick curTick;
+extern Tick curTick();
/* A namespace for all of the Statistics */
namespace Stats {
void prepare() { s.prepare(); }
void reset() { s.reset(); }
void
- visit(Visit &visitor)
+ visit(Output &visitor)
{
visitor.visit(*static_cast<Base *>(this));
}
Vector2dInfoProxy(Stat &stat) : InfoProxy<Stat, Vector2dInfo>(stat) {}
};
+struct StorageParams
+{
+ virtual ~StorageParams();
+};
+
class InfoAccess
{
protected:
/**
* Copy constructor, copies are not allowed.
*/
- DataWrap(const DataWrap &stat);
+ DataWrap(const DataWrap &stat) {}
/**
* Can't copy stats.
*/
- void operator=(const DataWrap &);
+ void operator=(const DataWrap &) {}
public:
DataWrap()
{
Info *info = this->info();
info->setName(name);
- info->flags.set(print);
+ info->flags.set(display);
return this->self();
}
const std::string &name() const { return this->info()->name; }
+ /**
+ * Set the character(s) used between the name and vector number
+ * on vectors, dist, etc.
+ * @param _sep The new separator string
+ * @return A reference to this stat.
+ */
+ Derived &
+ setSeparator(const std::string &_sep)
+ {
+ this->info()->setSeparator(_sep);
+ return this->self();
+ }
+ const std::string &setSeparator() const
+ {
+ return this->info()->separatorString;
+ }
+
/**
* Set the description and marks this stat to print at the end of
* simulation.
public:
typedef InfoProxyType<Derived> Info;
+ DataWrapVec()
+ {}
+
+ DataWrapVec(const DataWrapVec &ref)
+ {}
+
+ void operator=(const DataWrapVec &)
+ {}
+
// The following functions are specific to vectors. If you use them
// in a non vector context, you will get a nice compiler error!
}
Derived &
- ysubname(off_type index, const std::string subname)
+ ysubname(off_type index, const std::string &subname)
{
Derived &self = this->self();
Info *info = this->info();
info->y_subnames[index] = subname.c_str();
return self;
}
+
+ std::string
+ ysubname(off_type i) const
+ {
+ return this->info()->y_subnames[i];
+ }
+
};
//////////////////////////////////////////////////////////////////////
void
set(Counter val)
{
- total += current * (curTick - last);
- last = curTick;
+ total += current * (curTick() - last);
+ last = curTick();
current = val;
}
Result
result() const
{
- assert(last == curTick);
- return (Result)(total + current) / (Result)(curTick - lastReset + 1);
+ assert(last == curTick());
+ return (Result)(total + current) / (Result)(curTick() - lastReset + 1);
}
/**
void
prepare(Info *info)
{
- total += current * (curTick - last);
- last = curTick;
+ total += current * (curTick() - last);
+ last = curTick();
}
/**
reset(Info *info)
{
total = 0.0;
- last = curTick;
- lastReset = curTick;
+ last = curTick();
+ lastReset = curTick();
}
};
class ProxyInfo : public ScalarInfo
{
public:
- std::string str() const { return to_string(value()); }
+ std::string str() const { return std::to_string(value()); }
size_type size() const { return 1; }
bool check() const { return true; }
void prepare() { }
void reset() { }
bool zero() const { return value() == 0; }
- void visit(Visit &visitor) { visitor.visit(*this); }
+ void visit(Output &visitor) { visitor.visit(*this); }
};
template <class T>
Result total() const { return (*functor)(); }
};
+/**
+ * A proxy similar to the FunctorProxy, but allows calling a method of a bound
+ * object, instead of a global free-standing function.
+ */
+template <class T, class V>
+class MethodProxy : public ProxyInfo
+{
+ private:
+ T *object;
+ typedef V (T::*MethodPointer) () const;
+ MethodPointer method;
+
+ public:
+ MethodProxy(T *obj, MethodPointer meth) : object(obj), method(meth) {}
+ Counter value() const { return (object->*method)(); }
+ Result result() const { return (object->*method)(); }
+ Result total() const { return (object->*method)(); }
+};
+
template <class Derived>
class ValueBase : public DataWrap<Derived, ScalarInfoProxy>
{
return this->self();
}
+ /**
+ * Extended functor that calls the specified method of the provided object.
+ *
+ * @param obj Pointer to the object whose method should be called.
+ * @param method Pointer of the function / method of the object.
+ * @return Updated stats item.
+ */
+ template <class T, class V>
+ Derived &
+ method(T *obj, V (T::*method)() const)
+ {
+ proxy = new MethodProxy<T,V>(obj, method);
+ this->setInit();
+ return this->self();
+ }
+
Counter value() { return proxy->value(); }
Result result() const { return proxy->result(); }
Result total() const { return proxy->total(); };
public:
VectorBase()
- : storage(NULL)
+ : storage(nullptr), _size(0)
{}
~VectorBase()
public:
Vector2dBase()
- : storage(NULL)
+ : x(0), y(0), _size(0), storage(nullptr)
{}
~Vector2dBase()
return self;
}
- std::string ysubname(off_type i) const { return (*this->y_subnames)[i]; }
-
Proxy
operator[](off_type index)
{
off_type offset = index * y;
- assert (index >= 0 && offset + index < size());
+ assert (index >= 0 && offset + y <= size());
return Proxy(this->self(), offset, y);
}
// Non formula statistics
//
//////////////////////////////////////////////////////////////////////
+/** The parameters for a distribution stat. */
+struct DistParams : public StorageParams
+{
+ const DistType type;
+ DistParams(DistType t) : type(t) {}
+};
/**
* Templatized storage and interface for a distrbution stat.
/** The parameters for a distribution stat. */
struct Params : public DistParams
{
- Params() : DistParams(Dist) {}
+ /** The minimum value to track. */
+ Counter min;
+ /** The maximum value to track. */
+ Counter max;
+ /** The number of entries in each bucket. */
+ Counter bucket_size;
+ /** The number of buckets. Equal to (max-min)/bucket_size. */
+ size_type buckets;
+
+ Params() : DistParams(Dist), min(0), max(0), bucket_size(0),
+ buckets(0) {}
};
private:
Counter max_track;
/** The number of entries in each bucket. */
Counter bucket_size;
- /** The number of buckets. Equal to (max-min)/bucket_size. */
- size_type buckets;
/** The smallest value sampled. */
Counter min_val;
if (val > max_val)
max_val = val;
- Counter sample = val * number;
- sum += sample;
- squares += sample * sample;
+ sum += val * number;
+ squares += val * val * number;
samples += number;
}
{
const Params *params = safe_cast<const Params *>(info->storageParams);
+ assert(params->type == Dist);
+ data.type = params->type;
+ data.min = params->min;
+ data.max = params->max;
+ data.bucket_size = params->bucket_size;
+
data.min_val = (min_val == CounterLimits::max()) ? 0 : min_val;
data.max_val = (max_val == CounterLimits::min()) ? 0 : max_val;
data.underflow = underflow;
data.overflow = overflow;
- size_type buckets = params->buckets;
- data.cvec.resize(buckets);
- for (off_type i = 0; i < buckets; ++i)
+ data.cvec.resize(params->buckets);
+ for (off_type i = 0; i < params->buckets; ++i)
data.cvec[i] = cvec[i];
data.sum = sum;
}
};
+/**
+ * Templatized storage and interface for a histogram stat.
+ */
+class HistStor
+{
+ public:
+ /** The parameters for a distribution stat. */
+ struct Params : public DistParams
+ {
+ /** The number of buckets.. */
+ size_type buckets;
+
+ Params() : DistParams(Hist), buckets(0) {}
+ };
+
+ private:
+ /** The minimum value to track. */
+ Counter min_bucket;
+ /** The maximum value to track. */
+ Counter max_bucket;
+ /** The number of entries in each bucket. */
+ Counter bucket_size;
+
+ /** The current sum. */
+ Counter sum;
+ /** The sum of logarithm of each sample, used to compute geometric mean. */
+ Counter logs;
+ /** The sum of squares. */
+ Counter squares;
+ /** The number of samples. */
+ Counter samples;
+ /** Counter for each bucket. */
+ VCounter cvec;
+
+ public:
+ HistStor(Info *info)
+ : cvec(safe_cast<const Params *>(info->storageParams)->buckets)
+ {
+ reset(info);
+ }
+
+ void grow_up();
+ void grow_out();
+ void grow_convert();
+ void add(HistStor *);
+
+ /**
+ * Add a value to the distribution for the given number of times.
+ * @param val The value to add.
+ * @param number The number of times to add the value.
+ */
+ void
+ sample(Counter val, int number)
+ {
+ assert(min_bucket < max_bucket);
+ if (val < min_bucket) {
+ if (min_bucket == 0)
+ grow_convert();
+
+ while (val < min_bucket)
+ grow_out();
+ } else if (val >= max_bucket + bucket_size) {
+ if (min_bucket == 0) {
+ while (val >= max_bucket + bucket_size)
+ grow_up();
+ } else {
+ while (val >= max_bucket + bucket_size)
+ grow_out();
+ }
+ }
+
+ size_type index =
+ (int64_t)std::floor((val - min_bucket) / bucket_size);
+
+ assert(index < size());
+ cvec[index] += number;
+
+ sum += val * number;
+ squares += val * val * number;
+ logs += log(val) * number;
+ samples += number;
+ }
+
+ /**
+ * Return the number of buckets in this distribution.
+ * @return the number of buckets.
+ */
+ size_type size() const { return cvec.size(); }
+
+ /**
+ * Returns true if any calls to sample have been made.
+ * @return True if any values have been sampled.
+ */
+ bool
+ zero() const
+ {
+ return samples == Counter();
+ }
+
+ void
+ prepare(Info *info, DistData &data)
+ {
+ const Params *params = safe_cast<const Params *>(info->storageParams);
+
+ assert(params->type == Hist);
+ data.type = params->type;
+ data.min = min_bucket;
+ data.max = max_bucket + bucket_size - 1;
+ data.bucket_size = bucket_size;
+
+ data.min_val = min_bucket;
+ data.max_val = max_bucket;
+
+ int buckets = params->buckets;
+ data.cvec.resize(buckets);
+ for (off_type i = 0; i < buckets; ++i)
+ data.cvec[i] = cvec[i];
+
+ data.sum = sum;
+ data.logs = logs;
+ data.squares = squares;
+ data.samples = samples;
+ }
+
+ /**
+ * Reset stat value to default
+ */
+ void
+ reset(Info *info)
+ {
+ const Params *params = safe_cast<const Params *>(info->storageParams);
+ min_bucket = 0;
+ max_bucket = params->buckets - 1;
+ bucket_size = 1;
+
+ size_type size = cvec.size();
+ for (off_type i = 0; i < size; ++i)
+ cvec[i] = Counter();
+
+ sum = Counter();
+ squares = Counter();
+ samples = Counter();
+ logs = Counter();
+ }
+};
+
/**
* Templatized storage and interface for a distribution that calculates mean
* and variance.
void
prepare(Info *info, DistData &data)
{
+ const Params *params = safe_cast<const Params *>(info->storageParams);
+
+ assert(params->type == Deviation);
+ data.type = params->type;
data.sum = sum;
data.squares = squares;
data.samples = samples;
void
prepare(Info *info, DistData &data)
{
+ const Params *params = safe_cast<const Params *>(info->storageParams);
+
+ assert(params->type == Deviation);
+ data.type = params->type;
data.sum = sum;
data.squares = squares;
- data.samples = curTick;
+ data.samples = curTick();
}
/**
{
data()->reset(this->info());
}
+
+ /**
+ * Add the argument distribution to the this distibution.
+ */
+ void add(DistBase &d) { data()->add(d.data()); }
+
};
template <class Stat>
bool
zero() const
{
- return false;
-#if 0
for (off_type i = 0; i < size(); ++i)
if (!data(i)->zero())
return false;
return true;
-#endif
}
void
*/
void reset() { }
};
-/*
-template <class Derived, class Stor>
-inline typename VectorDistBase<Derived, Stor>::Proxy
-VectorDistBase<Derived, Stor>::operator[](off_type index)
-{
- assert (index >= 0 && index < size());
- typedef typename VectorDistBase<Derived, Stor>::Proxy Proxy;
- return Proxy(this->self(), index);
-}
-*/
-
-#if 0
-template <class Storage>
-Result
-VectorDistBase<Storage>::total(off_type index) const
-{
- Result total = 0.0;
- for (off_type i = 0; i < x_size(); ++i)
- total += data(i)->result();
-}
-#endif
//////////////////////////////////////////////////////////////////////
//
* Base class for formula statistic node. These nodes are used to build a tree
* that represents the formula.
*/
-class Node : public RefCounted
+class Node
{
public:
/**
virtual std::string str() const = 0;
};
-/** Reference counting pointer to a function Node. */
-typedef RefCountingPtr<Node> NodePtr;
+/** Shared pointer to a function Node. */
+typedef std::shared_ptr<Node> NodePtr;
class ScalarStatNode : public Node
{
const VResult &result() const { return vresult; }
Result total() const { return vresult[0]; };
size_type size() const { return 1; }
- std::string str() const { return to_string(vresult[0]); }
+ std::string str() const { return std::to_string(vresult[0]); }
};
template <class T>
size_type size = this->size();
std::string tmp = "(";
for (off_type i = 0; i < size; i++)
- tmp += csprintf("%s ",to_string(vresult[i]));
+ tmp += csprintf("%s ", std::to_string(vresult[i]));
tmp += ")";
return tmp;
}
total() const
{
const VResult &vec = this->result();
+ const VResult &lvec = l->result();
+ const VResult &rvec = r->result();
Result total = 0.0;
- for (off_type i = 0; i < size(); i++)
+ Result lsum = 0.0;
+ Result rsum = 0.0;
+ Op op;
+
+ assert(lvec.size() > 0 && rvec.size() > 0);
+ assert(lvec.size() == rvec.size() ||
+ lvec.size() == 1 || rvec.size() == 1);
+
+ /** If vectors are the same divide their sums (x0+x1)/(y0+y1) */
+ if (lvec.size() == rvec.size() && lvec.size() > 1) {
+ for (off_type i = 0; i < size(); ++i) {
+ lsum += lvec[i];
+ rsum += rvec[i];
+ }
+ return op(lsum, rsum);
+ }
+
+ /** Otherwise divide each item by the divisor */
+ for (off_type i = 0; i < size(); ++i) {
total += vec[i];
+ }
+
return total;
}
size_type size = lvec.size();
assert(size > 0);
- Result vresult = 0.0;
+ Result result = 0.0;
Op op;
for (off_type i = 0; i < size; ++i)
- vresult = op(vresult, lvec[i]);
+ result = op(result, lvec[i]);
- return vresult;
+ return result;
}
size_type size() const { return 1; }
params->min = min;
params->max = max;
params->bucket_size = bkt;
- params->buckets = (size_type)rint((max - min + 1.0) / bkt );
+ params->buckets = (size_type)ceil((max - min + 1.0) / bkt);
+ this->setParams(params);
+ this->doInit();
+ return this->self();
+ }
+};
+
+/**
+ * A simple histogram stat.
+ * @sa Stat, DistBase, HistStor
+ */
+class Histogram : public DistBase<Histogram, HistStor>
+{
+ public:
+ /**
+ * Set the parameters of this histogram. @sa HistStor::Params
+ * @param size The number of buckets in the histogram
+ * @return A reference to this histogram.
+ */
+ Histogram &
+ init(size_type size)
+ {
+ HistStor::Params *params = new HistStor::Params;
+ params->buckets = size;
this->setParams(params);
this->doInit();
return this->self();
*/
StandardDeviation()
{
+ SampleStor::Params *params = new SampleStor::Params;
this->doInit();
+ this->setParams(params);
}
};
*/
AverageDeviation()
{
+ AvgSampleStor::Params *params = new AvgSampleStor::Params;
this->doInit();
+ this->setParams(params);
}
};
params->min = min;
params->max = max;
params->bucket_size = bkt;
- params->buckets = (size_type)rint((max - min + 1.0) / bkt);
+ params->buckets = (size_type)ceil((max - min + 1.0) / bkt);
this->setParams(params);
this->doInit(size);
return this->self();
VectorStandardDeviation &
init(size_type size)
{
+ SampleStor::Params *params = new SampleStor::Params;
this->doInit(size);
+ this->setParams(params);
return this->self();
}
};
VectorAverageDeviation &
init(size_type size)
{
+ AvgSampleStor::Params *params = new AvgSampleStor::Params;
this->doInit(size);
+ this->setParams(params);
return this->self();
}
};
std::string str() const { return this->s.str(); }
};
+template <class Stat>
+class SparseHistInfoProxy : public InfoProxy<Stat, SparseHistInfo>
+{
+ public:
+ SparseHistInfoProxy(Stat &stat) : InfoProxy<Stat, SparseHistInfo>(stat) {}
+};
+
+/**
+ * Implementation of a sparse histogram stat. The storage class is
+ * determined by the Storage template.
+ */
+template <class Derived, class Stor>
+class SparseHistBase : public DataWrap<Derived, SparseHistInfoProxy>
+{
+ public:
+ typedef SparseHistInfoProxy<Derived> Info;
+ typedef Stor Storage;
+ typedef typename Stor::Params Params;
+
+ protected:
+ /** The storage for this stat. */
+ char storage[sizeof(Storage)];
+
+ protected:
+ /**
+ * Retrieve the storage.
+ * @return The storage object for this stat.
+ */
+ Storage *
+ data()
+ {
+ return reinterpret_cast<Storage *>(storage);
+ }
+
+ /**
+ * Retrieve a const pointer to the storage.
+ * @return A const pointer to the storage object for this stat.
+ */
+ const Storage *
+ data() const
+ {
+ return reinterpret_cast<const Storage *>(storage);
+ }
+
+ void
+ doInit()
+ {
+ new (storage) Storage(this->info());
+ this->setInit();
+ }
+
+ public:
+ SparseHistBase() { }
+
+ /**
+ * Add a value to the distribtion n times. Calls sample on the storage
+ * class.
+ * @param v The value to add.
+ * @param n The number of times to add it, defaults to 1.
+ */
+ template <typename U>
+ void sample(const U &v, int n = 1) { data()->sample(v, n); }
+
+ /**
+ * Return the number of entries in this stat.
+ * @return The number of entries.
+ */
+ size_type size() const { return data()->size(); }
+ /**
+ * Return true if no samples have been added.
+ * @return True if there haven't been any samples.
+ */
+ bool zero() const { return data()->zero(); }
+
+ void
+ prepare()
+ {
+ Info *info = this->info();
+ data()->prepare(info, info->data);
+ }
+
+ /**
+ * Reset stat value to default
+ */
+ void
+ reset()
+ {
+ data()->reset(this->info());
+ }
+};
+
+/**
+ * Templatized storage and interface for a sparse histogram stat.
+ */
+class SparseHistStor
+{
+ public:
+ /** The parameters for a sparse histogram stat. */
+ struct Params : public DistParams
+ {
+ Params() : DistParams(Hist) {}
+ };
+
+ private:
+ /** Counter for number of samples */
+ Counter samples;
+ /** Counter for each bucket. */
+ MCounter cmap;
+
+ public:
+ SparseHistStor(Info *info)
+ {
+ reset(info);
+ }
+
+ /**
+ * Add a value to the distribution for the given number of times.
+ * @param val The value to add.
+ * @param number The number of times to add the value.
+ */
+ void
+ sample(Counter val, int number)
+ {
+ cmap[val] += number;
+ samples += number;
+ }
+
+ /**
+ * Return the number of buckets in this distribution.
+ * @return the number of buckets.
+ */
+ size_type size() const { return cmap.size(); }
+
+ /**
+ * Returns true if any calls to sample have been made.
+ * @return True if any values have been sampled.
+ */
+ bool
+ zero() const
+ {
+ return samples == Counter();
+ }
+
+ void
+ prepare(Info *info, SparseHistData &data)
+ {
+ MCounter::iterator it;
+ data.cmap.clear();
+ for (it = cmap.begin(); it != cmap.end(); it++) {
+ data.cmap[(*it).first] = (*it).second;
+ }
+
+ data.samples = samples;
+ }
+
+ /**
+ * Reset stat value to default
+ */
+ void
+ reset(Info *info)
+ {
+ cmap.clear();
+ samples = 0;
+ }
+};
+
+class SparseHistogram : public SparseHistBase<SparseHistogram, SparseHistStor>
+{
+ public:
+ /**
+ * Set the parameters of this histogram. @sa HistStor::Params
+ * @param size The number of buckets in the histogram
+ * @return A reference to this histogram.
+ */
+ SparseHistogram &
+ init(size_type size)
+ {
+ SparseHistStor::Params *params = new SparseHistStor::Params;
+ this->setParams(params);
+ this->doInit();
+ return this->self();
+ }
+};
+
class Temp;
/**
* A formula for statistics that is calculated when printed. A formula is
* @return a reference to this formula.
*/
const Formula &operator+=(Temp r);
+
+ /**
+ * Divide the existing tree by the given one.
+ * @param r The root of the expression tree.
+ * @return a reference to this formula.
+ */
+ const Formula &operator/=(Temp r);
+
/**
* Return the result of the Fomula in a vector. If there were no Vector
* components to the Formula, then the vector is size 1. If there were,
* Copy the given pointer to this class.
* @param n A pointer to a Node object to copy.
*/
- Temp(NodePtr n) : node(n) { }
+ Temp(const NodePtr &n) : node(n) { }
+
+ Temp(NodePtr &&n) : node(std::move(n)) { }
/**
* Return the node pointer.
*/
operator NodePtr&() { return node; }
+ /**
+ * Makde gcc < 4.6.3 happy and explicitly get the underlying node.
+ */
+ NodePtr getNodePtr() const { return node; }
+
public:
/**
* Create a new ScalarStatNode.
inline Temp
operator+(Temp l, Temp r)
{
- return NodePtr(new BinaryNode<std::plus<Result> >(l, r));
+ return Temp(std::make_shared<BinaryNode<std::plus<Result> > >(l, r));
}
inline Temp
operator-(Temp l, Temp r)
{
- return NodePtr(new BinaryNode<std::minus<Result> >(l, r));
+ return Temp(std::make_shared<BinaryNode<std::minus<Result> > >(l, r));
}
inline Temp
operator*(Temp l, Temp r)
{
- return NodePtr(new BinaryNode<std::multiplies<Result> >(l, r));
+ return Temp(std::make_shared<BinaryNode<std::multiplies<Result> > >(l, r));
}
inline Temp
operator/(Temp l, Temp r)
{
- return NodePtr(new BinaryNode<std::divides<Result> >(l, r));
+ return Temp(std::make_shared<BinaryNode<std::divides<Result> > >(l, r));
}
inline Temp
operator-(Temp l)
{
- return NodePtr(new UnaryNode<std::negate<Result> >(l));
+ return Temp(std::make_shared<UnaryNode<std::negate<Result> > >(l));
}
template <typename T>
inline Temp
constant(T val)
{
- return NodePtr(new ConstNode<T>(val));
+ return Temp(std::make_shared<ConstNode<T> >(val));
}
template <typename T>
inline Temp
constantVector(T val)
{
- return NodePtr(new ConstVectorNode<T>(val));
+ return Temp(std::make_shared<ConstVectorNode<T> >(val));
}
inline Temp
sum(Temp val)
{
- return NodePtr(new SumNode<std::plus<Result> >(val));
+ return Temp(std::make_shared<SumNode<std::plus<Result> > >(val));
}
+/** Dump all statistics data to the registered outputs */
+void dump();
+void reset();
+void enable();
+bool enabled();
+
/**
- * Enable the statistics package. Before the statistics package is
- * enabled, all statistics must be created and initialized and once
- * the package is enabled, no more statistics can be created.
+ * Register reset and dump handlers. These are the functions which
+ * will actually perform the whole statistics reset/dump actions
+ * including processing the reset/dump callbacks
*/
-void enable();
+typedef void (*Handler)();
+
+void registerHandlers(Handler reset_handler, Handler dump_handler);
/**
- * Prepare all stats for data access. This must be done before
- * dumping and serialization.
+ * Register a callback that should be called whenever statistics are
+ * reset
*/
-void prepare();
+void registerResetCallback(Callback *cb);
/**
- * Dump all statistics data to the registered outputs
+ * Register a callback that should be called whenever statistics are
+ * about to be dumped
*/
-void dump();
+void registerDumpCallback(Callback *cb);
/**
- * Reset all statistics to the base state
+ * Process all the callbacks in the reset callbacks queue
*/
-void reset();
+void processResetQueue();
+
/**
- * Register a callback that should be called whenever statistics are
- * reset
+ * Process all the callbacks in the dump callbacks queue
*/
-void registerResetCallback(Callback *cb);
+void processDumpQueue();
std::list<Info *> &statsList();
-/* namespace Stats */ }
+typedef std::map<const void *, Info *> MapType;
+MapType &statsMap();
+
+typedef std::map<std::string, Info *> NameMapType;
+NameMapType &nameMap();
+
+bool validateStatName(const std::string &name);
+
+} // namespace Stats
+
+void debugDumpStats();
#endif // __BASE_STATISTICS_HH__