/*
 * Copyright (c) 2019 Arm Limited
 * All rights reserved.
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2003-2005 The Regents of The University of Michigan
 * Copyright (c) 2017, Centre National de la Recherche Scientifique
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Nathan Binkert
 *          Pierre-Yves Peneau
 */

/** @file
 * Declaration of Statistics objects.
 */

/**
* @todo
*
* Generalized N-dimensinal vector
* documentation
* key stats
* interval stats
*   -- these both can use the same function that prints out a
*   specific set of stats
* VectorStandardDeviation totals
* Document Namespaces
*/
#ifndef __BASE_STATISTICS_HH__
#define __BASE_STATISTICS_HH__

#include <algorithm>
#include <cassert>
#ifdef __SUNPRO_CC
#include <math.h>
#endif
#include <cmath>
#include <functional>
#include <iosfwd>
#include <list>
#include <map>
#include <memory>
#include <string>
#include <vector>

#include "base/stats/group.hh"
#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/str.hh"
#include "base/types.hh"

class Callback;

/** The current simulated tick. */
extern Tick curTick();

/* A namespace for all of the Statistics */
namespace Stats {

template <class Stat, class Base>
class InfoProxy : public Base
{
  protected:
    Stat &s;

  public:
    InfoProxy(Stat &stat) : s(stat) {}

    bool check() const { return s.check(); }
    void prepare() { s.prepare(); }
    void reset() { s.reset(); }
    void
    visit(Output &visitor)
    {
        visitor.visit(*static_cast<Base *>(this));
    }
    bool zero() const { return s.zero(); }
};

template <class Stat>
class ScalarInfoProxy : public InfoProxy<Stat, ScalarInfo>
{
  public:
    ScalarInfoProxy(Stat &stat) : InfoProxy<Stat, ScalarInfo>(stat) {}

    Counter value() const { return this->s.value(); }
    Result result() const { return this->s.result(); }
    Result total() const { return this->s.total(); }
};

template <class Stat>
class VectorInfoProxy : public InfoProxy<Stat, VectorInfo>
{
  protected:
    mutable VCounter cvec;
    mutable VResult rvec;

  public:
    VectorInfoProxy(Stat &stat) : InfoProxy<Stat, VectorInfo>(stat) {}

    size_type size() const { return this->s.size(); }

    VCounter &
    value() const
    {
        this->s.value(cvec);
        return cvec;
    }

    const VResult &
    result() const
    {
        this->s.result(rvec);
        return rvec;
    }

    Result total() const { return this->s.total(); }
};

template <class Stat>
class DistInfoProxy : public InfoProxy<Stat, DistInfo>
{
  public:
    DistInfoProxy(Stat &stat) : InfoProxy<Stat, DistInfo>(stat) {}
};

template <class Stat>
class VectorDistInfoProxy : public InfoProxy<Stat, VectorDistInfo>
{
  public:
    VectorDistInfoProxy(Stat &stat) : InfoProxy<Stat, VectorDistInfo>(stat) {}

    size_type size() const { return this->s.size(); }
};

template <class Stat>
class Vector2dInfoProxy : public InfoProxy<Stat, Vector2dInfo>
{
  public:
    Vector2dInfoProxy(Stat &stat) : InfoProxy<Stat, Vector2dInfo>(stat) {}

    Result total() const { return this->s.total(); }
};

struct StorageParams
{
    virtual ~StorageParams();
};

class InfoAccess
{
  private:
    Info *_info;

  protected:
    /** Set up an info class for this statistic */
    void setInfo(Group *parent, Info *info);
    /** Save Storage class parameters if any */
    void setParams(const StorageParams *params);
    /** Save Storage class parameters if any */
    void setInit();

    /** Grab the information class for this statistic */
    Info *info();
    /** Grab the information class for this statistic */
    const Info *info() const;

  public:
    InfoAccess()
        : _info(nullptr) {};

    /**
     * Reset the stat to the default state.
     */
    void reset() { }

    /**
     * @return true if this stat has a value and satisfies its
     * requirement as a prereq
     */
    bool zero() const { return true; }

    /**
     * Check that this stat has been set up properly and is ready for
     * use
     * @return true for success
     */
    bool check() const { return true; }
};

template <class Derived, template <class> class InfoProxyType>
class DataWrap : public InfoAccess
{
  public:
    typedef InfoProxyType<Derived> Info;

  protected:
    Derived &self() { return *static_cast<Derived *>(this); }

  protected:
    Info *
    info()
    {
        return safe_cast<Info *>(InfoAccess::info());
    }

  public:
    const Info *
    info() const
    {
        return safe_cast<const Info *>(InfoAccess::info());
    }

  public:
    DataWrap() = delete;
    DataWrap(const DataWrap &) = delete;
    DataWrap &operator=(const DataWrap &) = delete;


    DataWrap(Group *parent, const char *name, const char *desc)
    {
        auto info = new Info(self());
        this->setInfo(parent, info);

        if (parent)
            parent->addStat(info);

        if (name) {
            info->setName(name);
            info->flags.set(display);
        }

        if (desc)
            info->desc = desc;
    }

    /**
     * Set the name and marks this stat to print at the end of simulation.
     * @param name The new name.
     * @return A reference to this stat.
     */
    Derived &
    name(const std::string &name)
    {
        Info *info = this->info();
        info->setName(name);
        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.
     * @param desc The new description.
     * @return A reference to this stat.
     */
    Derived &
    desc(const std::string &_desc)
    {
        this->info()->desc = _desc;
        return this->self();
    }

    /**
     * Set the precision and marks this stat to print at the end of simulation.
     * @param _precision The new precision
     * @return A reference to this stat.
     */
    Derived &
    precision(int _precision)
    {
        this->info()->precision = _precision;
        return this->self();
    }

    /**
     * Set the flags and marks this stat to print at the end of simulation.
     * @param f The new flags.
     * @return A reference to this stat.
     */
    Derived &
    flags(Flags _flags)
    {
        this->info()->flags.set(_flags);
        return this->self();
    }

    /**
     * Set the prerequisite stat and marks this stat to print at the end of
     * simulation.
     * @param prereq The prerequisite stat.
     * @return A reference to this stat.
     */
    template <class Stat>
    Derived &
    prereq(const Stat &prereq)
    {
        this->info()->prereq = prereq.info();
        return this->self();
    }
};

template <class Derived, template <class> class InfoProxyType>
class DataWrapVec : public DataWrap<Derived, InfoProxyType>
{
  public:
    typedef InfoProxyType<Derived> Info;

    DataWrapVec(Group *parent = nullptr, const char *name = nullptr,
                const char *desc = nullptr)
        : DataWrap<Derived, InfoProxyType>(parent, name, desc)
    {}

    // The following functions are specific to vectors.  If you use them
    // in a non vector context, you will get a nice compiler error!

    /**
     * Set the subfield name for the given index, and marks this stat to print
     * at the end of simulation.
     * @param index The subfield index.
     * @param name The new name of the subfield.
     * @return A reference to this stat.
     */
    Derived &
    subname(off_type index, const std::string &name)
    {
        Derived &self = this->self();
        Info *info = self.info();

        std::vector<std::string> &subn = info->subnames;
        if (subn.size() <= index)
            subn.resize(index + 1);
        subn[index] = name;
        return self;
    }

    // The following functions are specific to 2d vectors.  If you use
    // them in a non vector context, you will get a nice compiler
    // error because info doesn't have the right variables.

    /**
     * Set the subfield description for the given index and marks this stat to
     * print at the end of simulation.
     * @param index The subfield index.
     * @param desc The new description of the subfield
     * @return A reference to this stat.
     */
    Derived &
    subdesc(off_type index, const std::string &desc)
    {
        Info *info = this->info();

        std::vector<std::string> &subd = info->subdescs;
        if (subd.size() <= index)
            subd.resize(index + 1);
        subd[index] = desc;

        return this->self();
    }

    void
    prepare()
    {
        Derived &self = this->self();
        Info *info = this->info();

        size_t size = self.size();
        for (off_type i = 0; i < size; ++i)
            self.data(i)->prepare(info);
    }

    void
    reset()
    {
        Derived &self = this->self();
        Info *info = this->info();

        size_t size = self.size();
        for (off_type i = 0; i < size; ++i)
            self.data(i)->reset(info);
    }
};

template <class Derived, template <class> class InfoProxyType>
class DataWrapVec2d : public DataWrapVec<Derived, InfoProxyType>
{
  public:
    typedef InfoProxyType<Derived> Info;

    DataWrapVec2d(Group *parent, const char *name, const char *desc)
        : DataWrapVec<Derived, InfoProxyType>(parent, name, desc)
    {
    }

    /**
     * @warning This makes the assumption that if you're gonna subnames a 2d
     * vector, you're subnaming across all y
     */
    Derived &
    ysubnames(const char **names)
    {
        Derived &self = this->self();
        Info *info = this->info();

        info->y_subnames.resize(self.y);
        for (off_type i = 0; i < self.y; ++i)
            info->y_subnames[i] = names[i];
        return self;
    }

    Derived &
    ysubname(off_type index, const std::string &subname)
    {
        Derived &self = this->self();
        Info *info = this->info();

        assert(index < self.y);
        info->y_subnames.resize(self.y);
        info->y_subnames[index] = subname.c_str();
        return self;
    }

    std::string
    ysubname(off_type i) const
    {
        return this->info()->y_subnames[i];
    }

};

//////////////////////////////////////////////////////////////////////
//
// Simple Statistics
//
//////////////////////////////////////////////////////////////////////

/**
 * Templatized storage and interface for a simple scalar stat.
 */
class StatStor
{
  private:
    /** The statistic value. */
    Counter data;

  public:
    struct Params : public StorageParams {};

  public:
    /**
     * Builds this storage element and calls the base constructor of the
     * datatype.
     */
    StatStor(Info *info)
        : data(Counter())
    { }

    /**
     * The the stat to the given value.
     * @param val The new value.
     */
    void set(Counter val) { data = val; }
    /**
     * Increment the stat by the given value.
     * @param val The new value.
     */
    void inc(Counter val) { data += val; }
    /**
     * Decrement the stat by the given value.
     * @param val The new value.
     */
    void dec(Counter val) { data -= val; }
    /**
     * Return the value of this stat as its base type.
     * @return The value of this stat.
     */
    Counter value() const { return data; }
    /**
     * Return the value of this stat as a result type.
     * @return The value of this stat.
     */
    Result result() const { return (Result)data; }
    /**
     * Prepare stat data for dumping or serialization
     */
    void prepare(Info *info) { }
    /**
     * Reset stat value to default
     */
    void reset(Info *info) { data = Counter(); }

    /**
     * @return true if zero value
     */
    bool zero() const { return data == Counter(); }
};

/**
 * Templatized storage and interface to a per-tick average stat. This keeps
 * a current count and updates a total (count * ticks) when this count
 * changes. This allows the quick calculation of a per tick count of the item
 * being watched. This is good for keeping track of residencies in structures
 * among other things.
 */
class AvgStor
{
  private:
    /** The current count. */
    Counter current;
    /** The tick of the last reset */
    Tick lastReset;
    /** The total count for all tick. */
    mutable Result total;
    /** The tick that current last changed. */
    mutable Tick last;

  public:
    struct Params : public StorageParams {};

  public:
    /**
     * Build and initializes this stat storage.
     */
    AvgStor(Info *info)
        : current(0), lastReset(0), total(0), last(0)
    { }

    /**
     * Set the current count to the one provided, update the total and last
     * set values.
     * @param val The new count.
     */
    void
    set(Counter val)
    {
        total += current * (curTick() - last);
        last = curTick();
        current = val;
    }

    /**
     * Increment the current count by the provided value, calls set.
     * @param val The amount to increment.
     */
    void inc(Counter val) { set(current + val); }

    /**
     * Deccrement the current count by the provided value, calls set.
     * @param val The amount to decrement.
     */
    void dec(Counter val) { set(current - val); }

    /**
     * Return the current count.
     * @return The current count.
     */
    Counter value() const { return current; }

    /**
     * Return the current average.
     * @return The current average.
     */
    Result
    result() const
    {
        assert(last == curTick());
        return (Result)(total + current) / (Result)(curTick() - lastReset + 1);
    }

    /**
     * @return true if zero value
     */
    bool zero() const { return total == 0.0; }

    /**
     * Prepare stat data for dumping or serialization
     */
    void
    prepare(Info *info)
    {
        total += current * (curTick() - last);
        last = curTick();
    }

    /**
     * Reset stat value to default
     */
    void
    reset(Info *info)
    {
        total = 0.0;
        last = curTick();
        lastReset = curTick();
    }

};

/**
 * Implementation of a scalar stat. The type of stat is determined by the
 * Storage template.
 */
template <class Derived, class Stor>
class ScalarBase : public DataWrap<Derived, ScalarInfoProxy>
{
  public:
    typedef Stor Storage;
    typedef typename Stor::Params Params;

  protected:
    /** The storage of this stat. */
    char storage[sizeof(Storage)] __attribute__ ((aligned (8)));

  protected:
    /**
     * Retrieve the storage.
     * @param index The vector index to access.
     * @return The storage object at the given index.
     */
    Storage *
    data()
    {
        return reinterpret_cast<Storage *>(storage);
    }

    /**
     * Retrieve a const pointer to the storage.
     * 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 *
    data() const
    {
        return reinterpret_cast<const Storage *>(storage);
    }

    void
    doInit()
    {
        new (storage) Storage(this->info());
        this->setInit();
    }

  public:
    /**
     * Return the current value of this stat as its base type.
     * @return The current value.
     */
    Counter value() const { return data()->value(); }

  public:
    ScalarBase(Group *parent = nullptr, const char *name = nullptr,
               const char *desc = nullptr)
        : DataWrap<Derived, ScalarInfoProxy>(parent, name, desc)
    {
        this->doInit();
    }

  public:
    // Common operators for stats
    /**
     * Increment the stat by 1. This calls the associated storage object inc
     * function.
     */
    void operator++() { data()->inc(1); }
    /**
     * Decrement the stat by 1. This calls the associated storage object dec
     * function.
     */
    void operator--() { data()->dec(1); }

    /** Increment the stat by 1. */
    void operator++(int) { ++*this; }
    /** Decrement the stat by 1. */
    void operator--(int) { --*this; }

    /**
     * Set the data value to the given value. This calls the associated storage
     * object set function.
     * @param v The new value.
     */
    template <typename U>
    void operator=(const U &v) { data()->set(v); }

    /**
     * Increment the stat by the given value. This calls the associated
     * storage object inc function.
     * @param v The value to add.
     */
    template <typename U>
    void operator+=(const U &v) { data()->inc(v); }

    /**
     * Decrement the stat by the given value. This calls the associated
     * storage object dec function.
     * @param v The value to substract.
     */
    template <typename U>
    void operator-=(const U &v) { data()->dec(v); }

    /**
     * Return the number of elements, always 1 for a scalar.
     * @return 1.
     */
    size_type size() const { return 1; }

    Counter value() { return data()->value(); }

    Result result() { return data()->result(); }

    Result total() { return result(); }

    bool zero() { return result() == 0.0; }

    void reset() { data()->reset(this->info()); }
    void prepare() { data()->prepare(this->info()); }
};

class ProxyInfo : public ScalarInfo
{
  public:
    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(Output &visitor) { visitor.visit(*this); }
};

template <class T>
class ValueProxy : public ProxyInfo
{
  private:
    T *scalar;

  public:
    ValueProxy(T &val) : scalar(&val) {}
    Counter value() const { return *scalar; }
    Result result() const { return *scalar; }
    Result total() const { return *scalar; }
};

template <class T>
class FunctorProxy : public ProxyInfo
{
  private:
    T *functor;

  public:
    FunctorProxy(T &func) : functor(&func) {}
    Counter value() const { return (*functor)(); }
    Result result() const { return (*functor)(); }
    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>
{
  private:
    ProxyInfo *proxy;

  public:
    ValueBase(Group *parent, const char *name, const char *desc)
        : DataWrap<Derived, ScalarInfoProxy>(parent, name, desc),
          proxy(NULL)
    {
    }

    ~ValueBase() { if (proxy) delete proxy; }

    template <class T>
    Derived &
    scalar(T &value)
    {
        proxy = new ValueProxy<T>(value);
        this->setInit();
        return this->self();
    }

    template <class T>
    Derived &
    functor(T &func)
    {
        proxy = new FunctorProxy<T>(func);
        this->setInit();
        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(); };
    size_type size() const { return proxy->size(); }

    std::string str() const { return proxy->str(); }
    bool zero() const { return proxy->zero(); }
    bool check() const { return proxy != NULL; }
    void prepare() { }
    void reset() { }
};

//////////////////////////////////////////////////////////////////////
//
// Vector Statistics
//
//////////////////////////////////////////////////////////////////////

/**
 * A proxy class to access the stat at a given index in a VectorBase stat.
 * Behaves like a ScalarBase.
 */
template <class Stat>
class ScalarProxy
{
  private:
    /** Pointer to the parent Vector. */
    Stat &stat;

    /** The index to access in the parent VectorBase. */
    off_type index;

  public:
    /**
     * Return the current value of this stat as its base type.
     * @return The current value.
     */
    Counter value() const { return stat.data(index)->value(); }

    /**
     * Return the current value of this statas a result type.
     * @return The current value.
     */
    Result result() const { return stat.data(index)->result(); }

  public:
    /**
     * Create and initialize this proxy, do not register it with the database.
     * @param i The index to access.
     */
    ScalarProxy(Stat &s, off_type i)
        : stat(s), index(i)
    {
    }

    /**
     * Create a copy of the provided ScalarProxy.
     * @param sp The proxy to copy.
     */
    ScalarProxy(const ScalarProxy &sp)
        : stat(sp.stat), index(sp.index)
    {}

    /**
     * Set this proxy equal to the provided one.
     * @param sp The proxy to copy.
     * @return A reference to this proxy.
     */
    const ScalarProxy &
    operator=(const ScalarProxy &sp)
    {
        stat = sp.stat;
        index = sp.index;
        return *this;
    }

  public:
    // Common operators for stats
    /**
     * Increment the stat by 1. This calls the associated storage object inc
     * function.
     */
    void operator++() { stat.data(index)->inc(1); }
    /**
     * Decrement the stat by 1. This calls the associated storage object dec
     * function.
     */
    void operator--() { stat.data(index)->dec(1); }

    /** Increment the stat by 1. */
    void operator++(int) { ++*this; }
    /** Decrement the stat by 1. */
    void operator--(int) { --*this; }

    /**
     * Set the data value to the given value. This calls the associated storage
     * object set function.
     * @param v The new value.
     */
    template <typename U>
    void
    operator=(const U &v)
    {
        stat.data(index)->set(v);
    }

    /**
     * Increment the stat by the given value. This calls the associated
     * storage object inc function.
     * @param v The value to add.
     */
    template <typename U>
    void
    operator+=(const U &v)
    {
        stat.data(index)->inc(v);
    }

    /**
     * Decrement the stat by the given value. This calls the associated
     * storage object dec function.
     * @param v The value to substract.
     */
    template <typename U>
    void
    operator-=(const U &v)
    {
        stat.data(index)->dec(v);
    }

    /**
     * Return the number of elements, always 1 for a scalar.
     * @return 1.
     */
    size_type size() const { return 1; }

  public:
    std::string
    str() const
    {
        return csprintf("%s[%d]", stat.info()->name, index);
    }
};

/**
 * Implementation of a vector of stats. The type of stat is determined by the
 * Storage class. @sa ScalarBase
 */
template <class Derived, class Stor>
class VectorBase : public DataWrapVec<Derived, VectorInfoProxy>
{
  public:
    typedef Stor Storage;
    typedef typename Stor::Params Params;

    /** Proxy type */
    typedef ScalarProxy<Derived> Proxy;
    friend class ScalarProxy<Derived>;
    friend class DataWrapVec<Derived, VectorInfoProxy>;

  protected:
    /** The storage of this stat. */
    Storage *storage;
    size_type _size;

  protected:
    /**
     * Retrieve the storage.
     * @param index The vector index to access.
     * @return The storage object at the given index.
     */
    Storage *data(off_type index) { return &storage[index]; }

    /**
     * Retrieve a const pointer to the storage.
     * @param index The vector index to access.
     * @return A const pointer to the storage object at the given index.
     */
    const Storage *data(off_type index) const { return &storage[index]; }

    void
    doInit(size_type s)
    {
        assert(s > 0 && "size must be positive!");
        assert(!storage && "already initialized");
        _size = s;

        char *ptr = new char[_size * sizeof(Storage)];
        storage = reinterpret_cast<Storage *>(ptr);

        for (off_type i = 0; i < _size; ++i)
            new (&storage[i]) Storage(this->info());

        this->setInit();
    }

  public:
    void
    value(VCounter &vec) const
    {
        vec.resize(size());
        for (off_type i = 0; i < size(); ++i)
            vec[i] = data(i)->value();
    }

    /**
     * Copy the values to a local vector and return a reference to it.
     * @return A reference to a vector of the stat values.
     */
    void
    result(VResult &vec) const
    {
        vec.resize(size());
        for (off_type i = 0; i < size(); ++i)
            vec[i] = data(i)->result();
    }

    /**
     * Return a total of all entries in this vector.
     * @return The total of all vector entries.
     */
    Result
    total() const
    {
        Result total = 0.0;
        for (off_type i = 0; i < size(); ++i)
            total += data(i)->result();
        return total;
    }

    /**
     * @return the number of elements in this vector.
     */
    size_type size() const { return _size; }

    bool
    zero() const
    {
        for (off_type i = 0; i < size(); ++i)
            if (data(i)->zero())
                return false;
        return true;
    }

    bool
    check() const
    {
        return storage != NULL;
    }

  public:
    VectorBase(Group *parent, const char *name, const char *desc)
        : DataWrapVec<Derived, VectorInfoProxy>(parent, name, desc),
          storage(nullptr), _size(0)
    {}

    ~VectorBase()
    {
        if (!storage)
            return;

        for (off_type i = 0; i < _size; ++i)
            data(i)->~Storage();
        delete [] reinterpret_cast<char *>(storage);
    }

    /**
     * Set this vector to have the given size.
     * @param size The new size.
     * @return A reference to this stat.
     */
    Derived &
    init(size_type size)
    {
        Derived &self = this->self();
        self.doInit(size);
        return self;
    }

    /**
     * Return a reference (ScalarProxy) to the stat at the given index.
     * @param index The vector index to access.
     * @return A reference of the stat.
     */
    Proxy
    operator[](off_type index)
    {
        assert (index >= 0 && index < size());
        return Proxy(this->self(), index);
    }
};

template <class Stat>
class VectorProxy
{
  private:
    Stat &stat;
    off_type offset;
    size_type len;

  private:
    mutable VResult vec;

    typename Stat::Storage *
    data(off_type index)
    {
        assert(index < len);
        return stat.data(offset + index);
    }

    const typename Stat::Storage *
    data(off_type index) const
    {
        assert(index < len);
        return stat.data(offset + index);
    }

  public:
    const VResult &
    result() const
    {
        vec.resize(size());

        for (off_type i = 0; i < size(); ++i)
            vec[i] = data(i)->result();

        return vec;
    }

    Result
    total() const
    {
        Result total = 0.0;
        for (off_type i = 0; i < size(); ++i)
            total += data(i)->result();
        return total;
    }

  public:
    VectorProxy(Stat &s, off_type o, size_type l)
        : stat(s), offset(o), len(l)
    {
    }

    VectorProxy(const VectorProxy &sp)
        : stat(sp.stat), offset(sp.offset), len(sp.len)
    {
    }

    const VectorProxy &
    operator=(const VectorProxy &sp)
    {
        stat = sp.stat;
        offset = sp.offset;
        len = sp.len;
        return *this;
    }

    ScalarProxy<Stat>
    operator[](off_type index)
    {
        assert (index >= 0 && index < size());
        return ScalarProxy<Stat>(stat, offset + index);
    }

    size_type size() const { return len; }
};

template <class Derived, class Stor>
class Vector2dBase : public DataWrapVec2d<Derived, Vector2dInfoProxy>
{
  public:
    typedef Vector2dInfoProxy<Derived> Info;
    typedef Stor Storage;
    typedef typename Stor::Params Params;
    typedef VectorProxy<Derived> Proxy;
    friend class ScalarProxy<Derived>;
    friend class VectorProxy<Derived>;
    friend class DataWrapVec<Derived, Vector2dInfoProxy>;
    friend class DataWrapVec2d<Derived, Vector2dInfoProxy>;

  protected:
    size_type x;
    size_type y;
    size_type _size;
    Storage *storage;

  protected:
    Storage *data(off_type index) { return &storage[index]; }
    const Storage *data(off_type index) const { return &storage[index]; }

  public:
    Vector2dBase(Group *parent, const char *name, const char *desc)
        : DataWrapVec2d<Derived, Vector2dInfoProxy>(parent, name, desc),
          x(0), y(0), _size(0), storage(nullptr)
    {}

    ~Vector2dBase()
    {
        if (!storage)
            return;

        for (off_type i = 0; i < _size; ++i)
            data(i)->~Storage();
        delete [] reinterpret_cast<char *>(storage);
    }

    Derived &
    init(size_type _x, size_type _y)
    {
        assert(_x > 0 && _y > 0 && "sizes must be positive!");
        assert(!storage && "already initialized");

        Derived &self = this->self();
        Info *info = this->info();

        x = _x;
        y = _y;
        info->x = _x;
        info->y = _y;
        _size = x * y;

        char *ptr = new char[_size * sizeof(Storage)];
        storage = reinterpret_cast<Storage *>(ptr);

        for (off_type i = 0; i < _size; ++i)
            new (&storage[i]) Storage(info);

        this->setInit();

        return self;
    }

    Proxy
    operator[](off_type index)
    {
        off_type offset = index * y;
        assert (index >= 0 && offset + y <= size());
        return Proxy(this->self(), offset, y);
    }


    size_type
    size() const
    {
        return _size;
    }

    bool
    zero() const
    {
        return data(0)->zero();
    }

    /**
     * Return a total of all entries in this vector.
     * @return The total of all vector entries.
     */
    Result
    total() const
    {
        Result total = 0.0;
        for (off_type i = 0; i < size(); ++i)
            total += data(i)->result();
        return total;
    }

    void
    prepare()
    {
        Info *info = this->info();
        size_type size = this->size();

        for (off_type i = 0; i < size; ++i)
            data(i)->prepare(info);

        info->cvec.resize(size);
        for (off_type i = 0; i < size; ++i)
            info->cvec[i] = data(i)->value();
    }

    /**
     * Reset stat value to default
     */
    void
    reset()
    {
        Info *info = this->info();
        size_type size = this->size();
        for (off_type i = 0; i < size; ++i)
            data(i)->reset(info);
    }

    bool
    check() const
    {
        return storage != NULL;
    }
};

//////////////////////////////////////////////////////////////////////
//
// 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 distribution stat.
 */
class DistStor
{
  public:
    /** The parameters for a distribution stat. */
    struct Params : public DistParams
    {
        /** 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:
    /** The minimum value to track. */
    Counter min_track;
    /** The maximum value to track. */
    Counter max_track;
    /** The number of entries in each bucket. */
    Counter bucket_size;

    /** The smallest value sampled. */
    Counter min_val;
    /** The largest value sampled. */
    Counter max_val;
    /** The number of values sampled less than min. */
    Counter underflow;
    /** The number of values sampled more than max. */
    Counter overflow;
    /** The current sum. */
    Counter sum;
    /** The sum of squares. */
    Counter squares;
    /** The number of samples. */
    Counter samples;
    /** Counter for each bucket. */
    VCounter cvec;

  public:
    DistStor(Info *info)
        : cvec(safe_cast<const Params *>(info->storageParams)->buckets)
    {
        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)
    {
        if (val < min_track)
            underflow += number;
        else if (val > max_track)
            overflow += number;
        else {
            size_type index =
                (size_type)std::floor((val - min_track) / bucket_size);
            assert(index < size());
            cvec[index] += number;
        }

        if (val < min_val)
            min_val = val;

        if (val > max_val)
            max_val = val;

        sum += val * number;
        squares += val * 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 == 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;

        data.cvec.resize(params->buckets);
        for (off_type i = 0; i < params->buckets; ++i)
            data.cvec[i] = cvec[i];

        data.sum = sum;
        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_track = params->min;
        max_track = params->max;
        bucket_size = params->bucket_size;

        min_val = CounterLimits::max();
        max_val = CounterLimits::min();
        underflow = Counter();
        overflow = Counter();

        size_type size = cvec.size();
        for (off_type i = 0; i < size; ++i)
            cvec[i] = Counter();

        sum = Counter();
        squares = Counter();
        samples = Counter();
    }
};

/**
 * 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.
 */
class SampleStor
{
  public:
    struct Params : public DistParams
    {
        Params() : DistParams(Deviation) {}
    };

  private:
    /** The current sum. */
    Counter sum;
    /** The sum of squares. */
    Counter squares;
    /** The number of samples. */
    Counter samples;

  public:
    /**
     * Create and initialize this storage.
     */
    SampleStor(Info *info)
        : sum(Counter()), squares(Counter()), samples(Counter())
    { }

    /**
     * Add a value the given number of times to this running average.
     * Update the running sum and sum of squares, increment the number of
     * values seen by the given number.
     * @param val The value to add.
     * @param number The number of times to add the value.
     */
    void
    sample(Counter val, int number)
    {
        Counter value = val * number;
        sum += value;
        squares += value * value;
        samples += number;
    }

    /**
     * Return the number of entries in this stat, 1
     * @return 1.
     */
    size_type size() const { return 1; }

    /**
     * Return true if no samples have been added.
     * @return True if no samples have been added.
     */
    bool zero() const { return samples == Counter(); }

    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;
    }

    /**
     * Reset stat value to default
     */
    void
    reset(Info *info)
    {
        sum = Counter();
        squares = Counter();
        samples = Counter();
    }
};

/**
 * Templatized storage for distribution that calculates per tick mean and
 * variance.
 */
class AvgSampleStor
{
  public:
    struct Params : public DistParams
    {
        Params() : DistParams(Deviation) {}
    };

  private:
    /** Current total. */
    Counter sum;
    /** Current sum of squares. */
    Counter squares;

  public:
    /**
     * Create and initialize this storage.
     */
    AvgSampleStor(Info *info)
        : sum(Counter()), squares(Counter())
    {}

    /**
     * Add a value to the distribution for the given number of times.
     * Update the running sum and sum of squares.
     * @param val The value to add.
     * @param number The number of times to add the value.
     */
    void
    sample(Counter val, int number)
    {
        Counter value = val * number;
        sum += value;
        squares += value * value;
    }

    /**
     * Return the number of entries, in this case 1.
     * @return 1.
     */
    size_type size() const { return 1; }

    /**
     * Return true if no samples have been added.
     * @return True if the sum is zero.
     */
    bool zero() const { return sum == Counter(); }

    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();
    }

    /**
     * Reset stat value to default
     */
    void
    reset(Info *info)
    {
        sum = Counter();
        squares = Counter();
    }
};

/**
 * Implementation of a distribution stat. The type of distribution is
 * determined by the Storage template. @sa ScalarBase
 */
template <class Derived, class Stor>
class DistBase : public DataWrap<Derived, DistInfoProxy>
{
  public:
    typedef DistInfoProxy<Derived> Info;
    typedef Stor Storage;
    typedef typename Stor::Params Params;

  protected:
    /** The storage for this stat. */
    char storage[sizeof(Storage)] __attribute__ ((aligned (8)));

  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:
    DistBase(Group *parent, const char *name, const char *desc)
        : DataWrap<Derived, DistInfoProxy>(parent, name, desc)
    {
    }

    /**
     * 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());
    }

    /**
     *  Add the argument distribution to the this distribution.
     */
    void add(DistBase &d) { data()->add(d.data()); }

};

template <class Stat>
class DistProxy;

template <class Derived, class Stor>
class VectorDistBase : public DataWrapVec<Derived, VectorDistInfoProxy>
{
  public:
    typedef VectorDistInfoProxy<Derived> Info;
    typedef Stor Storage;
    typedef typename Stor::Params Params;
    typedef DistProxy<Derived> Proxy;
    friend class DistProxy<Derived>;
    friend class DataWrapVec<Derived, VectorDistInfoProxy>;

  protected:
    Storage *storage;
    size_type _size;

  protected:
    Storage *
    data(off_type index)
    {
        return &storage[index];
    }

    const Storage *
    data(off_type index) const
    {
        return &storage[index];
    }

    void
    doInit(size_type s)
    {
        assert(s > 0 && "size must be positive!");
        assert(!storage && "already initialized");
        _size = s;

        char *ptr = new char[_size * sizeof(Storage)];
        storage = reinterpret_cast<Storage *>(ptr);

        Info *info = this->info();
        for (off_type i = 0; i < _size; ++i)
            new (&storage[i]) Storage(info);

        this->setInit();
    }

  public:
    VectorDistBase(Group *parent, const char *name, const char *desc)
        : DataWrapVec<Derived, VectorDistInfoProxy>(parent, name, desc),
          storage(NULL)
    {}

    ~VectorDistBase()
    {
        if (!storage)
            return ;

        for (off_type i = 0; i < _size; ++i)
            data(i)->~Storage();
        delete [] reinterpret_cast<char *>(storage);
    }

    Proxy operator[](off_type index)
    {
        assert(index >= 0 && index < size());
        return Proxy(this->self(), index);
    }

    size_type
    size() const
    {
        return _size;
    }

    bool
    zero() const
    {
        for (off_type i = 0; i < size(); ++i)
            if (!data(i)->zero())
                return false;
        return true;
    }

    void
    prepare()
    {
        Info *info = this->info();
        size_type size = this->size();
        info->data.resize(size);
        for (off_type i = 0; i < size; ++i)
            data(i)->prepare(info, info->data[i]);
    }

    bool
    check() const
    {
        return storage != NULL;
    }
};

template <class Stat>
class DistProxy
{
  private:
    Stat &stat;
    off_type index;

  protected:
    typename Stat::Storage *data() { return stat.data(index); }
    const typename Stat::Storage *data() const { return stat.data(index); }

  public:
    DistProxy(Stat &s, off_type i)
        : stat(s), index(i)
    {}

    DistProxy(const DistProxy &sp)
        : stat(sp.stat), index(sp.index)
    {}

    const DistProxy &
    operator=(const DistProxy &sp)
    {
        stat = sp.stat;
        index = sp.index;
        return *this;
    }

  public:
    template <typename U>
    void
    sample(const U &v, int n = 1)
    {
        data()->sample(v, n);
    }

    size_type
    size() const
    {
        return 1;
    }

    bool
    zero() const
    {
        return data()->zero();
    }

    /**
     * Proxy has no state.  Nothing to reset.
     */
    void reset() { }
};

//////////////////////////////////////////////////////////////////////
//
//  Formula Details
//
//////////////////////////////////////////////////////////////////////

/**
 * Base class for formula statistic node. These nodes are used to build a tree
 * that represents the formula.
 */
class Node
{
  public:
    /**
     * Return the number of nodes in the subtree starting at this node.
     * @return the number of nodes in this subtree.
     */
    virtual size_type size() const = 0;
    /**
     * Return the result vector of this subtree.
     * @return The result vector of this subtree.
     */
    virtual const VResult &result() const = 0;
    /**
     * Return the total of the result vector.
     * @return The total of the result vector.
     */
    virtual Result total() const = 0;

    /**
     *
     */
    virtual std::string str() const = 0;

    virtual ~Node() {};
};

/** Shared pointer to a function Node. */
typedef std::shared_ptr<Node> NodePtr;

class ScalarStatNode : public Node
{
  private:
    const ScalarInfo *data;
    mutable VResult vresult;

  public:
    ScalarStatNode(const ScalarInfo *d) : data(d), vresult(1) {}

    const VResult &
    result() const
    {
        vresult[0] = data->result();
        return vresult;
    }

    Result total() const { return data->result(); };

    size_type size() const { return 1; }

    /**
     *
     */
    std::string str() const { return data->name; }
};

template <class Stat>
class ScalarProxyNode : public Node
{
  private:
    const ScalarProxy<Stat> proxy;
    mutable VResult vresult;

  public:
    ScalarProxyNode(const ScalarProxy<Stat> &p)
        : proxy(p), vresult(1)
    { }

    const VResult &
    result() const
    {
        vresult[0] = proxy.result();
        return vresult;
    }

    Result
    total() const
    {
        return proxy.result();
    }

    size_type
    size() const
    {
        return 1;
    }

    /**
     *
     */
    std::string
    str() const
    {
        return proxy.str();
    }
};

class VectorStatNode : public Node
{
  private:
    const VectorInfo *data;

  public:
    VectorStatNode(const VectorInfo *d) : data(d) { }
    const VResult &result() const { return data->result(); }
    Result total() const { return data->total(); };

    size_type size() const { return data->size(); }

    std::string str() const { return data->name; }
};

template <class T>
class ConstNode : public Node
{
  private:
    VResult vresult;

  public:
    ConstNode(T s) : vresult(1, (Result)s) {}
    const VResult &result() const { return vresult; }
    Result total() const { return vresult[0]; };
    size_type size() const { return 1; }
    std::string str() const { return std::to_string(vresult[0]); }
};

template <class T>
class ConstVectorNode : public Node
{
  private:
    VResult vresult;

  public:
    ConstVectorNode(const T &s) : vresult(s.begin(), s.end()) {}
    const VResult &result() const { return vresult; }

    Result
    total() const
    {
        size_type size = this->size();
        Result tmp = 0;
        for (off_type i = 0; i < size; i++)
            tmp += vresult[i];
        return tmp;
    }

    size_type size() const { return vresult.size(); }
    std::string
    str() const
    {
        size_type size = this->size();
        std::string tmp = "(";
        for (off_type i = 0; i < size; i++)
            tmp += csprintf("%s ", std::to_string(vresult[i]));
        tmp += ")";
        return tmp;
    }
};

template <class Op>
struct OpString;

template<>
struct OpString<std::plus<Result> >
{
    static std::string str() { return "+"; }
};

template<>
struct OpString<std::minus<Result> >
{
    static std::string str() { return "-"; }
};

template<>
struct OpString<std::multiplies<Result> >
{
    static std::string str() { return "*"; }
};

template<>
struct OpString<std::divides<Result> >
{
    static std::string str() { return "/"; }
};

template<>
struct OpString<std::modulus<Result> >
{
    static std::string str() { return "%"; }
};

template<>
struct OpString<std::negate<Result> >
{
    static std::string str() { return "-"; }
};

template <class Op>
class UnaryNode : public Node
{
  public:
    NodePtr l;
    mutable VResult vresult;

  public:
    UnaryNode(NodePtr &p) : l(p) {}

    const VResult &
    result() const
    {
        const VResult &lvec = l->result();
        size_type size = lvec.size();

        assert(size > 0);

        vresult.resize(size);
        Op op;
        for (off_type i = 0; i < size; ++i)
            vresult[i] = op(lvec[i]);

        return vresult;
    }

    Result
    total() const
    {
        const VResult &vec = this->result();
        Result total = 0.0;
        for (off_type i = 0; i < size(); i++)
            total += vec[i];
        return total;
    }

    size_type size() const { return l->size(); }

    std::string
    str() const
    {
        return OpString<Op>::str() + l->str();
    }
};

template <class Op>
class BinaryNode : public Node
{
  public:
    NodePtr l;
    NodePtr r;
    mutable VResult vresult;

  public:
    BinaryNode(NodePtr &a, NodePtr &b) : l(a), r(b) {}

    const VResult &
    result() const override
    {
        Op op;
        const VResult &lvec = l->result();
        const VResult &rvec = r->result();

        assert(lvec.size() > 0 && rvec.size() > 0);

        if (lvec.size() == 1 && rvec.size() == 1) {
            vresult.resize(1);
            vresult[0] = op(lvec[0], rvec[0]);
        } else if (lvec.size() == 1) {
            size_type size = rvec.size();
            vresult.resize(size);
            for (off_type i = 0; i < size; ++i)
                vresult[i] = op(lvec[0], rvec[i]);
        } else if (rvec.size() == 1) {
            size_type size = lvec.size();
            vresult.resize(size);
            for (off_type i = 0; i < size; ++i)
                vresult[i] = op(lvec[i], rvec[0]);
        } else if (rvec.size() == lvec.size()) {
            size_type size = rvec.size();
            vresult.resize(size);
            for (off_type i = 0; i < size; ++i)
                vresult[i] = op(lvec[i], rvec[i]);
        }

        return vresult;
    }

    Result
    total() const override
    {
        const VResult &vec = this->result();
        const VResult &lvec = l->result();
        const VResult &rvec = r->result();
        Result total = 0.0;
        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() const override
    {
        size_type ls = l->size();
        size_type rs = r->size();
        if (ls == 1) {
            return rs;
        } else if (rs == 1) {
            return ls;
        } else {
            assert(ls == rs && "Node vector sizes are not equal");
            return ls;
        }
    }

    std::string
    str() const override
    {
        return csprintf("(%s %s %s)", l->str(), OpString<Op>::str(), r->str());
    }
};

template <class Op>
class SumNode : public Node
{
  public:
    NodePtr l;
    mutable VResult vresult;

  public:
    SumNode(NodePtr &p) : l(p), vresult(1) {}

    const VResult &
    result() const
    {
        const VResult &lvec = l->result();
        size_type size = lvec.size();
        assert(size > 0);

        vresult[0] = 0.0;

        Op op;
        for (off_type i = 0; i < size; ++i)
            vresult[0] = op(vresult[0], lvec[i]);

        return vresult;
    }

    Result
    total() const
    {
        const VResult &lvec = l->result();
        size_type size = lvec.size();
        assert(size > 0);

        Result result = 0.0;

        Op op;
        for (off_type i = 0; i < size; ++i)
            result = op(result, lvec[i]);

        return result;
    }

    size_type size() const { return 1; }

    std::string
    str() const
    {
        return csprintf("total(%s)", l->str());
    }
};


//////////////////////////////////////////////////////////////////////
//
// Visible Statistics Types
//
//////////////////////////////////////////////////////////////////////
/**
 * @defgroup VisibleStats "Statistic Types"
 * These are the statistics that are used in the simulator.
 * @{
 */

/**
 * This is a simple scalar statistic, like a counter.
 * @sa Stat, ScalarBase, StatStor
 */
class Scalar : public ScalarBase<Scalar, StatStor>
{
  public:
    using ScalarBase<Scalar, StatStor>::operator=;

    Scalar(Group *parent = nullptr, const char *name = nullptr,
           const char *desc = nullptr)
        : ScalarBase<Scalar, StatStor>(parent, name, desc)
    {
    }
};

/**
 * A stat that calculates the per tick average of a value.
 * @sa Stat, ScalarBase, AvgStor
 */
class Average : public ScalarBase<Average, AvgStor>
{
  public:
    using ScalarBase<Average, AvgStor>::operator=;

    Average(Group *parent = nullptr, const char *name = nullptr,
            const char *desc = nullptr)
        : ScalarBase<Average, AvgStor>(parent, name, desc)
    {
    }
};

class Value : public ValueBase<Value>
{
  public:
    Value(Group *parent = nullptr, const char *name = nullptr,
          const char *desc = nullptr)
        : ValueBase<Value>(parent, name, desc)
    {
    }
};

/**
 * A vector of scalar stats.
 * @sa Stat, VectorBase, StatStor
 */
class Vector : public VectorBase<Vector, StatStor>
{
  public:
    Vector(Group *parent = nullptr, const char *name = nullptr,
           const char *desc = nullptr)
        : VectorBase<Vector, StatStor>(parent, name, desc)
    {
    }
};

/**
 * A vector of Average stats.
 * @sa Stat, VectorBase, AvgStor
 */
class AverageVector : public VectorBase<AverageVector, AvgStor>
{
  public:
    AverageVector(Group *parent = nullptr, const char *name = nullptr,
                  const char *desc = nullptr)
        : VectorBase<AverageVector, AvgStor>(parent, name, desc)
    {
    }
};

/**
 * A 2-Dimensional vecto of scalar stats.
 * @sa Stat, Vector2dBase, StatStor
 */
class Vector2d : public Vector2dBase<Vector2d, StatStor>
{
  public:
    Vector2d(Group *parent = nullptr, const char *name = nullptr,
             const char *desc = nullptr)
        : Vector2dBase<Vector2d, StatStor>(parent, name, desc)
    {
    }
};

/**
 * A simple distribution stat.
 * @sa Stat, DistBase, DistStor
 */
class Distribution : public DistBase<Distribution, DistStor>
{
  public:
    Distribution(Group *parent = nullptr, const char *name = nullptr,
                 const char *desc = nullptr)
        : DistBase<Distribution, DistStor>(parent, name, desc)
    {
    }

    /**
     * Set the parameters of this distribution. @sa DistStor::Params
     * @param min The minimum value of the distribution.
     * @param max The maximum value of the distribution.
     * @param bkt The number of values in each bucket.
     * @return A reference to this distribution.
     */
    Distribution &
    init(Counter min, Counter max, Counter bkt)
    {
        DistStor::Params *params = new DistStor::Params;
        params->min = min;
        params->max = max;
        params->bucket_size = bkt;
        // Division by zero is especially serious in an Aarch64 host,
        // where it gets rounded to allocate 32GiB RAM.
        assert(bkt > 0);
        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:
    Histogram(Group *parent = nullptr, const char *name = nullptr,
              const char *desc = nullptr)
        : DistBase<Histogram, HistStor>(parent, name, desc)
    {
    }

    /**
     * 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();
    }
};

/**
 * Calculates the mean and variance of all the samples.
 * @sa DistBase, SampleStor
 */
class StandardDeviation : public DistBase<StandardDeviation, SampleStor>
{
  public:
    /**
     * Construct and initialize this distribution.
     */
    StandardDeviation(Group *parent = nullptr, const char *name = nullptr,
                      const char *desc = nullptr)
        : DistBase<StandardDeviation, SampleStor>(parent, name, desc)
    {
        SampleStor::Params *params = new SampleStor::Params;
        this->doInit();
        this->setParams(params);
    }
};

/**
 * Calculates the per tick mean and variance of the samples.
 * @sa DistBase, AvgSampleStor
 */
class AverageDeviation : public DistBase<AverageDeviation, AvgSampleStor>
{
  public:
    /**
     * Construct and initialize this distribution.
     */
    AverageDeviation(Group *parent = nullptr, const char *name = nullptr,
                     const char *desc = nullptr)
        : DistBase<AverageDeviation, AvgSampleStor>(parent, name, desc)
    {
        AvgSampleStor::Params *params = new AvgSampleStor::Params;
        this->doInit();
        this->setParams(params);
    }
};

/**
 * A vector of distributions.
 * @sa VectorDistBase, DistStor
 */
class VectorDistribution : public VectorDistBase<VectorDistribution, DistStor>
{
  public:
    VectorDistribution(Group *parent = nullptr, const char *name = nullptr,
                       const char *desc = nullptr)
        : VectorDistBase<VectorDistribution, DistStor>(parent, name, desc)
    {
    }

    /**
     * Initialize storage and parameters for this distribution.
     * @param size The size of the vector (the number of distributions).
     * @param min The minimum value of the distribution.
     * @param max The maximum value of the distribution.
     * @param bkt The number of values in each bucket.
     * @return A reference to this distribution.
     */
    VectorDistribution &
    init(size_type size, Counter min, Counter max, Counter bkt)
    {
        DistStor::Params *params = new DistStor::Params;
        params->min = min;
        params->max = max;
        params->bucket_size = bkt;
        params->buckets = (size_type)ceil((max - min + 1.0) / bkt);
        this->setParams(params);
        this->doInit(size);
        return this->self();
    }
};

/**
 * This is a vector of StandardDeviation stats.
 * @sa VectorDistBase, SampleStor
 */
class VectorStandardDeviation
    : public VectorDistBase<VectorStandardDeviation, SampleStor>
{
  public:
    VectorStandardDeviation(Group *parent = nullptr, const char *name = nullptr,
                            const char *desc = nullptr)
        : VectorDistBase<VectorStandardDeviation, SampleStor>(parent, name,
                                                              desc)
    {
    }

    /**
     * Initialize storage for this distribution.
     * @param size The size of the vector.
     * @return A reference to this distribution.
     */
    VectorStandardDeviation &
    init(size_type size)
    {
        SampleStor::Params *params = new SampleStor::Params;
        this->doInit(size);
        this->setParams(params);
        return this->self();
    }
};

/**
 * This is a vector of AverageDeviation stats.
 * @sa VectorDistBase, AvgSampleStor
 */
class VectorAverageDeviation
    : public VectorDistBase<VectorAverageDeviation, AvgSampleStor>
{
  public:
    VectorAverageDeviation(Group *parent = nullptr, const char *name = nullptr,
                           const char *desc = nullptr)
        : VectorDistBase<VectorAverageDeviation, AvgSampleStor>(parent, name,
                                                                desc)
    {
    }

    /**
     * Initialize storage for this distribution.
     * @param size The size of the vector.
     * @return A reference to this distribution.
     */
    VectorAverageDeviation &
    init(size_type size)
    {
        AvgSampleStor::Params *params = new AvgSampleStor::Params;
        this->doInit(size);
        this->setParams(params);
        return this->self();
    }
};

template <class Stat>
class FormulaInfoProxy : public InfoProxy<Stat, FormulaInfo>
{
  protected:
    mutable VResult vec;
    mutable VCounter cvec;

  public:
    FormulaInfoProxy(Stat &stat) : InfoProxy<Stat, FormulaInfo>(stat) {}

    size_type size() const { return this->s.size(); }

    const VResult &
    result() const
    {
        this->s.result(vec);
        return vec;
    }
    Result total() const { return this->s.total(); }
    VCounter &value() const { return cvec; }

    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(Group *parent, const char *name, const char *desc)
        : DataWrap<Derived, SparseHistInfoProxy>(parent, name, desc)
    {
    }

    /**
     * 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:
    SparseHistogram(Group *parent = nullptr, const char *name = nullptr,
                    const char *desc = nullptr)
        : SparseHistBase<SparseHistogram, SparseHistStor>(parent, name, desc)
    {
    }

    /**
     * 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
 * stored as a tree of Nodes that represent the equation to calculate.
 * @sa Stat, ScalarStat, VectorStat, Node, Temp
 */
class Formula : public DataWrapVec<Formula, FormulaInfoProxy>
{
  protected:
    /** The root of the tree which represents the Formula */
    NodePtr root;
    friend class Temp;

  public:
    /**
     * Create and initialize thie formula, and register it with the database.
     */
    Formula(Group *parent = nullptr, const char *name = nullptr,
            const char *desc = nullptr);

    Formula(Group *parent, const char *name, const char *desc,
            const Temp &r);

    /**
     * Set an unitialized Formula to the given root.
     * @param r The root of the expression tree.
     * @return a reference to this formula.
     */
    const Formula &operator=(const Temp &r);

    template<typename T>
    const Formula &operator=(const T &v)
    {
        *this = Temp(v);
        return *this;
    }

    /**
     * Add the given tree to the existing one.
     * @param r The root of the expression tree.
     * @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,
     * like x/y with x being a vector of size 3, then the result returned will
     * be x[0]/y, x[1]/y, x[2]/y, respectively.
     * @return The result vector.
     */
    void result(VResult &vec) const;

    /**
     * Return the total Formula result.  If there is a Vector
     * component to this Formula, then this is the result of the
     * Formula if the formula is applied after summing all the
     * 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 VResult val() returns.
     * @return The total of the result vector.
     */
    Result total() const;

    /**
     * Return the number of elements in the tree.
     */
    size_type size() const;

    void prepare() { }

    /**
     * Formulas don't need to be reset
     */
    void reset();

    /**
     *
     */
    bool zero() const;

    std::string str() const;
};

class FormulaNode : public Node
{
  private:
    const Formula &formula;
    mutable VResult vec;

  public:
    FormulaNode(const Formula &f) : formula(f) {}

    size_type size() const { return formula.size(); }
    const VResult &result() const { formula.result(vec); return vec; }
    Result total() const { return formula.total(); }

    std::string str() const { return formula.str(); }
};

/**
 * Helper class to construct formula node trees.
 */
class Temp
{
  protected:
    /**
     * Pointer to a Node object.
     */
    NodePtr node;

  public:
    /**
     * Copy the given pointer to this class.
     * @param n A pointer to a Node object to copy.
     */
    Temp(const NodePtr &n) : node(n) { }

    Temp(NodePtr &&n) : node(std::move(n)) { }

    /**
     * Return the node pointer.
     * @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.
     * @param s The ScalarStat to place in a node.
     */
    Temp(const Scalar &s)
        : node(new ScalarStatNode(s.info()))
    { }

    /**
     * Create a new ScalarStatNode.
     * @param s The ScalarStat to place in a node.
     */
    Temp(const Value &s)
        : node(new ScalarStatNode(s.info()))
    { }

    /**
     * Create a new ScalarStatNode.
     * @param s The ScalarStat to place in a node.
     */
    Temp(const Average &s)
        : node(new ScalarStatNode(s.info()))
    { }

    /**
     * Create a new VectorStatNode.
     * @param s The VectorStat to place in a node.
     */
    Temp(const Vector &s)
        : node(new VectorStatNode(s.info()))
    { }

    Temp(const AverageVector &s)
        : node(new VectorStatNode(s.info()))
    { }

    /**
     *
     */
    Temp(const Formula &f)
        : node(new FormulaNode(f))
    { }

    /**
     * Create a new ScalarProxyNode.
     * @param p The ScalarProxy to place in a node.
     */
    template <class Stat>
    Temp(const ScalarProxy<Stat> &p)
        : node(new ScalarProxyNode<Stat>(p))
    { }

    /**
     * Create a ConstNode
     * @param value The value of the const node.
     */
    Temp(signed char value)
        : node(new ConstNode<signed char>(value))
    { }

    /**
     * Create a ConstNode
     * @param value The value of the const node.
     */
    Temp(unsigned char value)
        : node(new ConstNode<unsigned char>(value))
    { }

    /**
     * Create a ConstNode
     * @param value The value of the const node.
     */
    Temp(signed short value)
        : node(new ConstNode<signed short>(value))
    { }

    /**
     * Create a ConstNode
     * @param value The value of the const node.
     */
    Temp(unsigned short value)
        : node(new ConstNode<unsigned short>(value))
    { }

    /**
     * Create a ConstNode
     * @param value The value of the const node.
     */
    Temp(signed int value)
        : node(new ConstNode<signed int>(value))
    { }

    /**
     * Create a ConstNode
     * @param value The value of the const node.
     */
    Temp(unsigned int value)
        : node(new ConstNode<unsigned int>(value))
    { }

    /**
     * Create a ConstNode
     * @param value The value of the const node.
     */
    Temp(signed long value)
        : node(new ConstNode<signed long>(value))
    { }

    /**
     * Create a ConstNode
     * @param value The value of the const node.
     */
    Temp(unsigned long value)
        : node(new ConstNode<unsigned long>(value))
    { }

    /**
     * Create a ConstNode
     * @param value The value of the const node.
     */
    Temp(signed long long value)
        : node(new ConstNode<signed long long>(value))
    { }

    /**
     * Create a ConstNode
     * @param value The value of the const node.
     */
    Temp(unsigned long long value)
        : node(new ConstNode<unsigned long long>(value))
    { }

    /**
     * Create a ConstNode
     * @param value The value of the const node.
     */
    Temp(float value)
        : node(new ConstNode<float>(value))
    { }

    /**
     * Create a ConstNode
     * @param value The value of the const node.
     */
    Temp(double value)
        : node(new ConstNode<double>(value))
    { }
};


/**
 * @}
 */

inline Temp
operator+(Temp l, Temp r)
{
    return Temp(std::make_shared<BinaryNode<std::plus<Result> > >(l, r));
}

inline Temp
operator-(Temp l, Temp r)
{
    return Temp(std::make_shared<BinaryNode<std::minus<Result> > >(l, r));
}

inline Temp
operator*(Temp l, Temp r)
{
    return Temp(std::make_shared<BinaryNode<std::multiplies<Result> > >(l, r));
}

inline Temp
operator/(Temp l, Temp r)
{
    return Temp(std::make_shared<BinaryNode<std::divides<Result> > >(l, r));
}

inline Temp
operator-(Temp l)
{
    return Temp(std::make_shared<UnaryNode<std::negate<Result> > >(l));
}

template <typename T>
inline Temp
constant(T val)
{
    return Temp(std::make_shared<ConstNode<T> >(val));
}

template <typename T>
inline Temp
constantVector(T val)
{
    return Temp(std::make_shared<ConstVectorNode<T> >(val));
}

inline Temp
sum(Temp 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();

/**
 * 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
 */
typedef void (*Handler)();

void registerHandlers(Handler reset_handler, Handler dump_handler);

/**
 * Register a callback that should be called whenever statistics are
 * reset
 */
void registerResetCallback(Callback *cb);

/**
 * Register a callback that should be called whenever statistics are
 * about to be dumped
 */
void registerDumpCallback(Callback *cb);

/**
 * Process all the callbacks in the reset callbacks queue
 */
void processResetQueue();

/**
 * Process all the callbacks in the dump callbacks queue
 */
void processDumpQueue();

std::list<Info *> &statsList();

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__
