/*
 * Copyright (c) 2003-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * 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.
 */

/** @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>
#include <cmath>
#include <functional>
#include <iosfwd>
#include <sstream>
#include <string>
#include <vector>

#include "base/cprintf.hh"
#include "base/intmath.hh"
#include "base/refcnt.hh"
#include "base/str.hh"
#include "base/stats/bin.hh"
#include "base/stats/flags.hh"
#include "base/stats/visit.hh"
#include "base/stats/types.hh"
#include "sim/host.hh"

class Callback;

/** The current simulated cycle. */
extern Tick curTick;

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

/* Contains the statistic implementation details */
//////////////////////////////////////////////////////////////////////
//
// Statistics Framework Base classes
//
//////////////////////////////////////////////////////////////////////
struct StatData
{
    /** The name of the stat. */
    std::string name;
    /** The description of the stat. */
    std::string desc;
    /** The formatting flags. */
    StatFlags flags;
    /** The display precision. */
    int precision;
    /** A pointer to a prerequisite Stat. */
    const StatData *prereq;
    /**
     * A unique stat ID for each stat in the simulator.
     * Can be used externally for lookups as well as for debugging.
     */
    int id;

    StatData();
    virtual ~StatData();

    /**
     * @return true if the stat is binned.
     */
    virtual bool binned() const = 0;

    /**
     * Reset the corresponding stat to the default state.
     */
    virtual void reset() = 0;

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

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

    /**
     * Visitor entry for outputing statistics data
     */
    virtual void visit(Visit &visitor) = 0;

    /**
     * Checks if the first stat's name is alphabetically less than the second.
     * This function breaks names up at periods and considers each subname
     * separately.
     * @param stat1 The first stat.
     * @param stat2 The second stat.
     * @return stat1's name is alphabetically before stat2's
     */
    static bool less(StatData *stat1, StatData *stat2);
};

class ScalarData : public StatData
{
  public:
    virtual Counter value() const = 0;
    virtual Result result() const = 0;
    virtual Result total() const = 0;
    virtual void visit(Visit &visitor) { visitor.visit(*this); }
};

template <class Stat>
class ScalarStatData : public ScalarData
{
  protected:
    Stat &s;

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

    virtual bool binned() const { return s.binned(); }
    virtual bool check() const { return s.check(); }
    virtual Counter value() const { return s.value(); }
    virtual Result result() const { return s.result(); }
    virtual Result total() const { return s.total(); }
    virtual void reset() { s.reset(); }
    virtual bool zero() const { return s.zero(); }
};

struct VectorData : public StatData
{
    /** Names and descriptions of subfields. */
    mutable std::vector<std::string> subnames;
    mutable std::vector<std::string> subdescs;

    virtual size_t size() const  = 0;
    virtual const VCounter &value() const = 0;
    virtual const VResult &result() const = 0;
    virtual Result total() const  = 0;
    void update()
    {
        if (!subnames.empty()) {
            int s = size();
            if (subnames.size() < s)
                subnames.resize(s);

            if (subdescs.size() < s)
                subdescs.resize(s);
        }
    }
};

template <class Stat>
class VectorStatData : public VectorData
{
  protected:
    Stat &s;
    mutable VCounter cvec;
    mutable VResult rvec;

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

    virtual bool binned() const { return s.binned(); }
    virtual bool check() const { return s.check(); }
    virtual bool zero() const { return s.zero(); }
    virtual void reset() { s.reset(); }

    virtual size_t size() const { return s.size(); }
    virtual VCounter &value() const
    {
        s.value(cvec);
        return cvec;
    }
    virtual const VResult &result() const
    {
        s.result(rvec);
        return rvec;
    }
    virtual Result total() const { return s.total(); }
    virtual void visit(Visit &visitor)
    {
        update();
        s.update(this);
        visitor.visit(*this);
    }
};

struct DistDataData
{
    Counter min_val;
    Counter max_val;
    Counter underflow;
    Counter overflow;
    VCounter cvec;
    Counter sum;
    Counter squares;
    Counter samples;

    Counter min;
    Counter max;
    Counter bucket_size;
    int size;
    bool fancy;
};

struct DistData : public StatData
{
    /** Local storage for the entry values, used for printing. */
    DistDataData data;
};

template <class Stat>
class DistStatData : public DistData
{
  protected:
    Stat &s;

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

    virtual bool binned() const { return s.binned(); }
    virtual bool check() const { return s.check(); }
    virtual void reset() { s.reset(); }
    virtual bool zero() const { return s.zero(); }
    virtual void visit(Visit &visitor)
    {
        s.update(this);
        visitor.visit(*this);
    }
};

struct VectorDistData : public StatData
{
    std::vector<DistDataData> data;

   /** Names and descriptions of subfields. */
    mutable std::vector<std::string> subnames;
    mutable std::vector<std::string> subdescs;

    /** Local storage for the entry values, used for printing. */
    mutable VResult rvec;

    virtual size_t size() const = 0;
    void update()
    {
        int s = size();
        if (subnames.size() < s)
            subnames.resize(s);

        if (subdescs.size() < s)
            subdescs.resize(s);
    }
};

template <class Stat>
class VectorDistStatData : public VectorDistData
{
  protected:
    Stat &s;
    typedef typename Stat::bin_t bin_t;

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

    virtual bool binned() const { return bin_t::binned; }
    virtual bool check() const { return s.check(); }
    virtual void reset() { s.reset(); }
    virtual size_t size() const { return s.size(); }
    virtual bool zero() const { return s.zero(); }
    virtual void visit(Visit &visitor)
    {
        update();
        s.update(this);
        visitor.visit(*this);
    }
};

struct Vector2dData : public StatData
{
    /** Names and descriptions of subfields. */
    std::vector<std::string> subnames;
    std::vector<std::string> subdescs;
    std::vector<std::string> y_subnames;

    /** Local storage for the entry values, used for printing. */
    mutable VCounter cvec;
    mutable int x;
    mutable int y;

    void update()
    {
        if (subnames.size() < x)
            subnames.resize(x);
    }
};

template <class Stat>
class Vector2dStatData : public Vector2dData
{
  protected:
    Stat &s;
    typedef typename Stat::bin_t bin_t;

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

    virtual bool binned() const { return bin_t::binned; }
    virtual bool check() const { return s.check(); }
    virtual void reset() { s.reset(); }
    virtual bool zero() const { return s.zero(); }
    virtual void visit(Visit &visitor)
    {
        update();
        s.update(this);
        visitor.visit(*this);
    }
};


class DataAccess
{
  protected:
    StatData *find() const;
    void map(StatData *data);

    StatData *statData();
    const StatData *statData() const;

    void setInit();
    void setPrint();
};

template <class Parent, class Child, template <class> class Data>
class Wrap : public Child
{
  protected:
    Parent &self() { return *reinterpret_cast<Parent *>(this); }

  protected:
    Data<Child> *statData()
    {
        StatData *__data = DataAccess::statData();
        Data<Child> *ptr = dynamic_cast<Data<Child> *>(__data);
        assert(ptr);
        return ptr;
    }

  public:
    const Data<Child> *statData() const
    {
        const StatData *__data = DataAccess::statData();
        const Data<Child> *ptr = dynamic_cast<const Data<Child> *>(__data);
        assert(ptr);
        return ptr;
    }

  protected:
    /**
     * Copy constructor, copies are not allowed.
     */
    Wrap(const Wrap &stat);
    /**
     * Can't copy stats.
     */
    void operator=(const Wrap &);

  public:
    Wrap()
    {
      map(new Data<Child>(*this));
    }

    /**
     * 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.
     */
    Parent &name(const std::string &_name)
    {
        Data<Child> *data = this->statData();
        data->name = _name;
        this->setPrint();
        return this->self();
    }

    /**
     * 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.
     */
    Parent &desc(const std::string &_desc)
    {
        this->statData()->desc = _desc;
        return this->self();
    }

    /**
     * Set the precision and marks this stat to print at the end of simulation.
     * @param p The new precision
     * @return A reference to this stat.
     */
    Parent &precision(int _precision)
    {
        this->statData()->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.
     */
    Parent &flags(StatFlags _flags)
    {
        this->statData()->flags |= _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>
    Parent &prereq(const Stat &prereq)
    {
        this->statData()->prereq = prereq.statData();
        return this->self();
    }
};

template <class Parent, class Child, template <class Child> class Data>
class WrapVec : public Wrap<Parent, Child, Data>
{
  public:
    // 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.
     */
    Parent &subname(int index, const std::string &name)
    {
        std::vector<std::string> &subn = this->statData()->subnames;
        if (subn.size() <= index)
            subn.resize(index + 1);
        subn[index] = name;
        return this->self();
    }

    /**
     * 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.
     */
    Parent &subdesc(int index, const std::string &desc)
    {
        std::vector<std::string> &subd = this->statData()->subdescs;
        if (subd.size() <= index)
            subd.resize(index + 1);
        subd[index] = desc;

        return this->self();
    }

};

template <class Parent, class Child, template <class Child> class Data>
class WrapVec2d : public WrapVec<Parent, Child, Data>
{
  public:
    /**
     * @warning This makes the assumption that if you're gonna subnames a 2d
     * vector, you're subnaming across all y
     */
    Parent &ysubnames(const char **names)
    {
        Data<Child> *data = this->statData();
        data->y_subnames.resize(this->y);
        for (int i = 0; i < this->y; ++i)
            data->y_subnames[i] = names[i];
        return this->self();
    }
    Parent &ysubname(int index, const std::string subname)
    {
        Data<Child> *data = this->statData();
        assert(index < this->y);
        data->y_subnames.resize(this->y);
        data->y_subnames[index] = subname.c_str();
        return this->self();
    }
};

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

/**
 * Templatized storage and interface for a simple scalar stat.
 */
struct StatStor
{
  public:
    /** The paramaters for this storage type, none for a scalar. */
    struct Params { };

  private:
    /** The statistic value. */
    Counter data;

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

    /**
     * The the stat to the given value.
     * @param val The new value.
     * @param p The paramters of this storage type.
     */
    void set(Counter val, const Params &p) { data = val; }
    /**
     * Increment the stat by the given value.
     * @param val The new value.
     * @param p The paramters of this storage type.
     */
    void inc(Counter val, const Params &p) { data += val; }
    /**
     * Decrement the stat by the given value.
     * @param val The new value.
     * @param p The paramters of this storage type.
     */
    void dec(Counter val, const Params &p) { data -= val; }
    /**
     * Return the value of this stat as its base type.
     * @param p The params of this storage type.
     * @return The value of this stat.
     */
    Counter value(const Params &p) const { return data; }
    /**
     * Return the value of this stat as a result type.
     * @param p The parameters of this storage type.
     * @return The value of this stat.
     */
    Result result(const Params &p) const { return (Result)data; }
    /**
     * Reset stat value to default
     */
    void reset() { data = Counter(); }

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

/**
 * Templatized storage and interface to a per-cycle average stat. This keeps
 * a current count and updates a total (count * cycles) when this count
 * changes. This allows the quick calculation of a per cycle count of the item
 * being watched. This is good for keeping track of residencies in structures
 * among other things.
 * @todo add lateny to the stat and fix binning.
 */
struct AvgStor
{
  public:
    /** The paramaters for this storage type */
    struct Params
    {
        /**
         * The current count.  We stash this here because the current
         * value is not a binned value.
         */
        Counter current;
    };

  private:
    /** The total count for all cycles. */
    mutable Result total;
    /** The cycle that current last changed. */
    mutable Tick last;

  public:
    /**
     * Build and initializes this stat storage.
     */
    AvgStor(Params &p) : total(0), last(0) { p.current = Counter(); }

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

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

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

    /**
     * Return the current count.
     * @param p The parameters for this storage.
     * @return The current count.
     */
    Counter value(const Params &p) const { return p.current; }

    /**
     * Return the current average.
     * @param p The parameters for this storage.
     * @return The current average.
     */
    Result result(const Params &p) const
    {
        total += p.current * (curTick - last);
        last = curTick;
        return (Result)(total + p.current) / (Result)(curTick + 1);
    }

    /**
     * Reset stat value to default
     */
    void reset()
    {
        total = 0;
        last = curTick;
    }

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

/**
 * Implementation of a scalar stat. The type of stat is determined by the
 * Storage template. The storage for this stat is held within the Bin class.
 * This allows for breaking down statistics across multiple bins easily.
 */
template <class Storage, class Bin>
class ScalarBase : public DataAccess
{
  public:
    /** Define the params of the storage class. */
    typedef typename Storage::Params params_t;
    /** Define the bin type. */
    typedef typename Bin::template Bin<Storage> bin_t;

  protected:
    /** The bin of this stat. */
    bin_t bin;
    /** The parameters for this stat. */
    params_t params;

  protected:
    /**
     * Retrieve the storage from the bin.
     * @return The storage object for this stat.
     */
    Storage *data() { return bin.data(params); }
    /**
     * Retrieve a const pointer to the storage from the bin.
     * @return A const pointer to the storage object for this stat.
     */
    const Storage *data() const
    {
        bin_t *_bin = const_cast<bin_t *>(&bin);
        params_t *_params = const_cast<params_t *>(&params);
        return _bin->data(*_params);
    }

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

  public:
    /**
     * Create and initialize this stat, register it with the database.
     */
    ScalarBase()
    {
        bin.init(params);
    }

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

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

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

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

    /**
     * Return the number of elements, always 1 for a scalar.
     * @return 1.
     */
    size_t size() const { return 1; }
    /**
     * Return true if stat is binned.
     *@return True is stat is binned.
     */
    bool binned() const { return bin_t::binned; }

    bool check() const { return bin.initialized(); }

    /**
     * Reset stat value to default
     */
    void reset() { bin.reset(); }

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

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

    Result total() { return result(); }

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

};

class ProxyData : public ScalarData
{
  public:
    virtual void visit(Visit &visitor) { visitor.visit(*this); }
    virtual bool binned() const { return false; }
    virtual std::string str() const { return to_string(value()); }
    virtual size_t size() const { return 1; }
    virtual bool zero() const { return value() == 0; }
    virtual bool check() const { return true; }
    virtual void reset() { }
};

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

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

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

  public:
    FunctorProxy(T &func) : functor(&func) {}
    virtual Counter value() const { return (*functor)(); }
    virtual Result result() const { return (*functor)(); }
    virtual Result total() const { return (*functor)(); }
};

class ValueBase : public DataAccess
{
  private:
    ProxyData *proxy;

  public:
    ValueBase() : proxy(NULL) { }
    ~ValueBase() { if (proxy) delete proxy; }

    template <class T>
    void scalar(T &value)
    {
        proxy = new ValueProxy<T>(value);
        setInit();
    }

    template <class T>
    void functor(T &func)
    {
        proxy = new FunctorProxy<T>(func);
        setInit();
    }

    Counter value() { return proxy->value(); }
    Result result() const { return proxy->result(); }
    Result total() const { return proxy->total(); };
    size_t size() const { return proxy->size(); }

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

//////////////////////////////////////////////////////////////////////
//
// Vector Statistics
//
//////////////////////////////////////////////////////////////////////
template <class Storage, class Bin>
class ScalarProxy;

/**
 * Implementation of a vector of stats. The type of stat is determined by the
 * Storage class. @sa ScalarBase
 */
template <class Storage, class Bin>
class VectorBase : public DataAccess
{
  public:
    /** Define the params of the storage class. */
    typedef typename Storage::Params params_t;
    /** Define the bin type. */
    typedef typename Bin::template VectorBin<Storage> bin_t;

  protected:
    /** The bin of this stat. */
    bin_t bin;
    /** The parameters for this stat. */
    params_t params;

  protected:
    /**
     * Retrieve the storage from the bin  for the given index.
     * @param index The vector index to access.
     * @return The storage object at the given index.
     */
    Storage *data(int index) { return bin.data(index, params); }
    /**
     * Retrieve a const pointer to the storage from the bin
     * for the given index.
     * @param index The vector index to access.
     * @return A const pointer to the storage object at the given index.
     */
    const Storage *data(int index) const
    {
        bin_t *_bin = const_cast<bin_t *>(&bin);
        params_t *_params = const_cast<params_t *>(&params);
        return _bin->data(index, *_params);
    }

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

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

    /**
     * @return True is stat is binned.
     */
    bool binned() const { return bin_t::binned; }

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

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

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

    bool check() const { return bin.initialized(); }
    void reset() { bin.reset(); }

  public:
    VectorBase() {}

    /** Friend this class with the associated scalar proxy. */
    friend class ScalarProxy<Storage, Bin>;

    /**
     * Return a reference (ScalarProxy) to the stat at the given index.
     * @param index The vector index to access.
     * @return A reference of the stat.
     */
    ScalarProxy<Storage, Bin> operator[](int index);

    void update(StatData *data) {}
};

const StatData * getStatData(const void *stat);

/**
 * A proxy class to access the stat at a given index in a VectorBase stat.
 * Behaves like a ScalarBase.
 */
template <class Storage, class Bin>
class ScalarProxy
{
  public:
    /** Define the params of the storage class. */
    typedef typename Storage::Params params_t;
    /** Define the bin type. */
    typedef typename Bin::template VectorBin<Storage> bin_t;

  private:
    /** Pointer to the bin in the parent VectorBase. */
    bin_t *bin;
    /** Pointer to the params in the parent VectorBase. */
    params_t *params;
    /** The index to access in the parent VectorBase. */
    int index;
    /** Keep a pointer to the original stat so was can get data */
    void *stat;

  protected:
    /**
     * Retrieve the storage from the bin.
     * @return The storage from the bin for this stat.
     */
    Storage *data() { return bin->data(index, *params); }
    /**
     * Retrieve a const pointer to the storage from the bin.
     * @return A const pointer to the storage for this stat.
     */
    const Storage *data() const
    {
        bin_t *_bin = const_cast<bin_t *>(bin);
        params_t *_params = const_cast<params_t *>(params);
        return _bin->data(index, *_params);
    }

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

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

  public:
    /**
     * Create and initialize this proxy, do not register it with the database.
     * @param b The bin to use.
     * @param p The params to use.
     * @param i The index to access.
     */
    ScalarProxy(bin_t &b, params_t &p, int i, void *s)
        : bin(&b), params(&p), index(i), stat(s)  {}
    /**
     * Create a copy of the provided ScalarProxy.
     * @param sp The proxy to copy.
     */
    ScalarProxy(const ScalarProxy &sp)
        : bin(sp.bin), params(sp.params), index(sp.index), stat(sp.stat) {}
    /**
     * 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) {
        bin = sp.bin;
        params = sp.params;
        index = sp.index;
        stat = sp.stat;
        return *this;
    }

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

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

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

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

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

    /**
     * Return true if stat is binned.
     *@return false since Proxies aren't printed/binned
     */
    bool binned() const { return false; }

    /**
     * This stat has no state.  Nothing to reset
     */
    void reset() {  }

  public:
    const StatData *statData() const { return getStatData(stat); }
    std::string str() const
    {
        return csprintf("%s[%d]", this->statData()->name, index);

    }
};

template <class Storage, class Bin>
inline ScalarProxy<Storage, Bin>
VectorBase<Storage, Bin>::operator[](int index)
{
    assert (index >= 0 && index < size());
    return ScalarProxy<Storage, Bin>(bin, params, index, this);
}

template <class Storage, class Bin>
class VectorProxy;

template <class Storage, class Bin>
class Vector2dBase : public DataAccess
{
  public:
    typedef typename Storage::Params params_t;
    typedef typename Bin::template VectorBin<Storage> bin_t;

  protected:
    size_t x;
    size_t y;
    bin_t bin;
    params_t params;

  protected:
    Storage *data(int index) { return bin.data(index, params); }
    const Storage *data(int index) const
    {
        bin_t *_bin = const_cast<bin_t *>(&bin);
        params_t *_params = const_cast<params_t *>(&params);
        return _bin->data(index, *_params);
    }

  public:
    Vector2dBase() {}

    void update(Vector2dData *data)
    {
        int size = this->size();
        data->cvec.resize(size);
        for (int i = 0; i < size; ++i)
            data->cvec[i] = this->data(i)->value(params);
    }

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

    friend class VectorProxy<Storage, Bin>;
    VectorProxy<Storage, Bin> operator[](int index);

    size_t size() const { return bin.size(); }
    bool zero() const { return data(0)->value(params) == 0.0; }

    /**
     * Reset stat value to default
     */
    void reset() { bin.reset(); }

    bool check() { return bin.initialized(); }
};

template <class Storage, class Bin>
class VectorProxy
{
  public:
    typedef typename Storage::Params params_t;
    typedef typename Bin::template VectorBin<Storage> bin_t;

  private:
    bin_t *bin;
    params_t *params;
    int offset;
    int len;
    void *stat;

  private:
    mutable VResult *vec;

    Storage *data(int index) {
        assert(index < len);
        return bin->data(offset + index, *params);
    }

    const Storage *data(int index) const {
        bin_t *_bin = const_cast<bin_t *>(bin);
        params_t *_params = const_cast<params_t *>(params);
        return _bin->data(offset + index, *_params);
    }

  public:
    const VResult &result() const {
        if (vec)
            vec->resize(size());
        else
            vec = new VResult(size());

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

        return *vec;
    }

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

  public:
    VectorProxy(bin_t &b, params_t &p, int o, int l, void *s)
        : bin(&b), params(&p), offset(o), len(l), stat(s), vec(NULL)
    {
    }

    VectorProxy(const VectorProxy &sp)
        : bin(sp.bin), params(sp.params), offset(sp.offset), len(sp.len),
          stat(sp.stat), vec(NULL)
    {
    }

    ~VectorProxy()
    {
        if (vec)
            delete vec;
    }

    const VectorProxy &operator=(const VectorProxy &sp)
    {
        bin = sp.bin;
        params = sp.params;
        offset = sp.offset;
        len = sp.len;
        stat = sp.stat;
        if (vec)
            delete vec;
        vec = NULL;
        return *this;
    }

    ScalarProxy<Storage, Bin> operator[](int index)
    {
        assert (index >= 0 && index < size());
        return ScalarProxy<Storage, Bin>(*bin, *params, offset + index, stat);
    }

    size_t size() const { return len; }

    /**
     * Return true if stat is binned.
     *@return false since Proxies aren't printed/binned
     */
    bool binned() const { return false; }

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

template <class Storage, class Bin>
inline VectorProxy<Storage, Bin>
Vector2dBase<Storage, Bin>::operator[](int index)
{
    int offset = index * y;
    assert (index >= 0 && offset < size());
    return VectorProxy<Storage, Bin>(bin, params, offset, y, this);
}

//////////////////////////////////////////////////////////////////////
//
// Non formula statistics
//
//////////////////////////////////////////////////////////////////////

/**
 * Templatized storage and interface for a distrbution stat.
 */
struct DistStor
{
  public:
    /** The parameters for a distribution stat. */
    struct Params
    {
        /** 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. */
        int size;
    };
    enum { fancy = false };

  private:
    /** 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:
    /**
     * Construct this storage with the supplied params.
     * @param params The parameters.
     */
    DistStor(const Params &params)
        : min_val(INT_MAX), max_val(INT_MIN), underflow(Counter()),
          overflow(Counter()), sum(Counter()), squares(Counter()),
          samples(Counter()), cvec(params.size)
    {
        reset();
    }

    /**
     * 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.
     * @param params The paramters of the distribution.
     */
    void sample(Counter val, int number, const Params &params)
    {
        if (val < params.min)
            underflow += number;
        else if (val > params.max)
            overflow += number;
        else {
            int index = (int)floor((val - params.min) / params.bucket_size);
            assert(index < size(params));
            cvec[index] += number;
        }

        if (val < min_val)
            min_val = val;

        if (val > max_val)
            max_val = val;

        Counter sample = val * number;
        sum += sample;
        squares += sample * sample;
        samples += number;
    }

    /**
     * Return the number of buckets in this distribution.
     * @return the number of buckets.
     * @todo Is it faster to return the size from the parameters?
     */
    size_t size(const Params &) const { return cvec.size(); }

    /**
     * Returns true if any calls to sample have been made.
     * @param params The paramters of the distribution.
     * @return True if any values have been sampled.
     */
    bool zero(const Params &params) const
    {
        return samples == Counter();
    }

    void update(DistDataData *data, const Params &params)
    {
        data->min = params.min;
        data->max = params.max;
        data->bucket_size = params.bucket_size;
        data->size = params.size;

        data->min_val = (min_val == INT_MAX) ? 0 : min_val;
        data->max_val = (max_val == INT_MIN) ? 0 : max_val;
        data->underflow = underflow;
        data->overflow = overflow;
        data->cvec.resize(params.size);
        for (int i = 0; i < params.size; ++i)
            data->cvec[i] = cvec[i];

        data->sum = sum;
        data->squares = squares;
        data->samples = samples;
    }

    /**
     * Reset stat value to default
     */
    void reset()
    {
        min_val = INT_MAX;
        max_val = INT_MIN;
        underflow = 0;
        overflow = 0;

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

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

/**
 * Templatized storage and interface for a distribution that calculates mean
 * and variance.
 */
struct FancyStor
{
  public:
    /**
     * No paramters for this storage.
     */
    struct Params {};
    enum { fancy = true };

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

  public:
    /**
     * Create and initialize this storage.
     */
    FancyStor(const Params &)
        : 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.
     * @param p The parameters of this stat.
     */
    void sample(Counter val, int number, const Params &p)
    {
        Counter value = val * number;
        sum += value;
        squares += value * value;
        samples += number;
    }

    void update(DistDataData *data, const Params &params)
    {
        data->sum = sum;
        data->squares = squares;
        data->samples = samples;
    }

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

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

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

/**
 * Templatized storage for distribution that calculates per cycle mean and
 * variance.
 */
struct AvgFancy
{
  public:
    /** No parameters for this storage. */
    struct Params {};
    enum { fancy = true };

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

  public:
    /**
     * Create and initialize this storage.
     */
    AvgFancy(const Params &) : 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.
     * @param p The paramters of the distribution.
     */
    void sample(Counter val, int number, const Params &p)
    {
        Counter value = val * number;
        sum += value;
        squares += value * value;
    }

    void update(DistDataData *data, const Params &params)
    {
        data->sum = sum;
        data->squares = squares;
        data->samples = curTick;
    }

    /**
     * Return the number of entries, in this case 1.
     * @return 1.
     */
    size_t size(const Params &params) const { return 1; }
    /**
     * Return true if no samples have been added.
     * @return True if the sum is zero.
     */
    bool zero(const Params &params) const { return sum == Counter(); }
    /**
     * Reset stat value to default
     */
    void reset()
    {
        sum = Counter();
        squares = Counter();
    }
};

/**
 * Implementation of a distribution stat. The type of distribution is
 * determined by the Storage template. @sa ScalarBase
 */
template <class Storage, class Bin>
class DistBase : public DataAccess
{
  public:
    /** Define the params of the storage class. */
    typedef typename Storage::Params params_t;
    /** Define the bin type. */
    typedef typename Bin::template Bin<Storage> bin_t;

  protected:
    /** The bin of this stat. */
    bin_t bin;
    /** The parameters for this stat. */
    params_t params;

  protected:
    /**
     * Retrieve the storage from the bin.
     * @return The storage object for this stat.
     */
    Storage *data() { return bin.data(params); }
    /**
     * Retrieve a const pointer to the storage from the bin.
     * @return A const pointer to the storage object for this stat.
     */
    const Storage *data() const
    {
        bin_t *_bin = const_cast<bin_t *>(&bin);
        params_t *_params = const_cast<params_t *>(&params);
        return _bin->data(*_params);
    }

  public:
    DistBase() { }

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

    /**
     * Return the number of entries in this stat.
     * @return The number of entries.
     */
    size_t size() const { return data()->size(params); }
    /**
     * Return true if no samples have been added.
     * @return True if there haven't been any samples.
     */
    bool zero() const { return data()->zero(params); }

    void update(DistData *base)
    {
        base->data.fancy = Storage::fancy;
        data()->update(&(base->data), params);
    }
    /**
     * @return True is stat is binned.
     */
    bool binned() const { return bin_t::binned; }
    /**
     * Reset stat value to default
     */
    void reset()
    {
        bin.reset();
    }

    bool check() { return bin.initialized(); }
};

template <class Storage, class Bin>
class DistProxy;

template <class Storage, class Bin>
class VectorDistBase : public DataAccess
{
  public:
    typedef typename Storage::Params params_t;
    typedef typename Bin::template VectorBin<Storage> bin_t;

  protected:
    bin_t bin;
    params_t params;

  protected:
    Storage *data(int index) { return bin.data(index, params); }
    const Storage *data(int index) const
    {
        bin_t *_bin = const_cast<bin_t *>(&bin);
        params_t *_params = const_cast<params_t *>(&params);
        return _bin->data(index, *_params);
    }

  public:
    VectorDistBase() {}

    friend class DistProxy<Storage, Bin>;
    DistProxy<Storage, Bin> operator[](int index);
    const DistProxy<Storage, Bin> operator[](int index) const;

    size_t size() const { return bin.size(); }
    bool zero() const { return false; }
    /**
     * Return true if stat is binned.
     *@return True is stat is binned.
     */
    bool binned() const { return bin_t::binned; }
    /**
     * Reset stat value to default
     */
    void reset() { bin.reset(); }

    bool check() { return bin.initialized(); }
    void update(VectorDistData *base)
    {
        int size = this->size();
        base->data.resize(size);
        for (int i = 0; i < size; ++i) {
            base->data[i].fancy = Storage::fancy;
            data(i)->update(&(base->data[i]), params);
        }
    }
};

template <class Storage, class Bin>
class DistProxy
{
  public:
    typedef typename Storage::Params params_t;
    typedef typename Bin::template Bin<Storage> bin_t;
    typedef VectorDistBase<Storage, Bin> base_t;

  private:
    union {
        base_t *stat;
        const base_t *cstat;
    };
    int index;

  protected:
    Storage *data() { return stat->data(index); }
    const Storage *data() const { return cstat->data(index); }

  public:
    DistProxy(const VectorDistBase<Storage, Bin> &s, int i)
        : cstat(&s), index(i) {}
    DistProxy(const DistProxy &sp)
        : cstat(sp.cstat), index(sp.index) {}
    const DistProxy &operator=(const DistProxy &sp) {
        cstat = sp.cstat; index = sp.index; return *this;
    }

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

    size_t size() const { return 1; }
    bool zero() const { return data()->zero(cstat->params); }
    /**
     * Return true if stat is binned.
     *@return false since Proxies are not binned/printed.
     */
    bool binned() const { return false; }
    /**
     * Proxy has no state.  Nothing to reset.
     */
    void reset() { }
};

template <class Storage, class Bin>
inline DistProxy<Storage, Bin>
VectorDistBase<Storage, Bin>::operator[](int index)
{
    assert (index >= 0 && index < size());
    return DistProxy<Storage, Bin>(*this, index);
}

template <class Storage, class Bin>
inline const DistProxy<Storage, Bin>
VectorDistBase<Storage, Bin>::operator[](int index) const
{
    assert (index >= 0 && index < size());
    return DistProxy<Storage, Bin>(*this, index);
}

#if 0
template <class Storage, class Bin>
Result
VectorDistBase<Storage, Bin>::total(int index) const
{
    int total = 0;
    for (int i=0; i < x_size(); ++i) {
        total += data(i)->result(*params);
    }
}
#endif

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

/**
 * Base class for formula statistic node. These nodes are used to build a tree
 * that represents the formula.
 */
class Node : public RefCounted
{
  public:
    /**
     * Return the number of nodes in the subtree starting at this node.
     * @return the number of nodes in this subtree.
     */
    virtual size_t 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;
    /**
     * Return true if stat is binned.
     *@return True is stat is binned.
     */
    virtual bool binned() const = 0;

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

/** Reference counting pointer to a function Node. */
typedef RefCountingPtr<Node> NodePtr;

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

  public:
    ScalarStatNode(const ScalarData *d) : data(d), vresult(1) {}
    virtual const VResult &result() const
    {
        vresult[0] = data->result();
        return vresult;
    }
    virtual Result total() const { return data->result(); };

    virtual size_t size() const { return 1; }
    /**
     * Return true if stat is binned.
     *@return True is stat is binned.
     */
    virtual bool binned() const { return data->binned(); }

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

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

  public:
    ScalarProxyNode(const ScalarProxy<Storage, Bin> &p)
        : proxy(p), vresult(1) { }
    virtual const VResult &result() const
    {
        vresult[0] = proxy.result();
        return vresult;
    }
    virtual Result total() const { return proxy.result(); };

    virtual size_t size() const { return 1; }
    /**
     * Return true if stat is binned.
     *@return True is stat is binned.
     */
    virtual bool binned() const { return proxy.binned(); }

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

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

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

    virtual size_t size() const { return data->size(); }
    /**
     * Return true if stat is binned.
     *@return True is stat is binned.
     */
    virtual bool binned() const { return data->binned(); }

    virtual 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; }
    virtual Result total() const { return vresult[0]; };
    virtual size_t size() const { return 1; }

    /**
     * Return true if stat is binned.
     *@return False since constants aren't binned.
     */
    virtual bool binned() const { return false; }

    virtual std::string str() const { return to_string(vresult[0]); }
};

template <class 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();
        int size = lvec.size();

        assert(size > 0);

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

        return vresult;
    }

    Result total() const {
        Op op;
        return op(l->total());
    }

    virtual size_t size() const { return l->size(); }
    /**
     * Return true if child of node is binned.
     *@return True if child of node is binned.
     */
    virtual bool binned() const { return l->binned(); }

    virtual 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
    {
        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) {
            int size = rvec.size();
            vresult.resize(size);
            for (int i = 0; i < size; ++i)
                vresult[i] = op(lvec[0], rvec[i]);
        } else if (rvec.size() == 1) {
            int size = lvec.size();
            vresult.resize(size);
            for (int i = 0; i < size; ++i)
                vresult[i] = op(lvec[i], rvec[0]);
        } else if (rvec.size() == lvec.size()) {
            int size = rvec.size();
            vresult.resize(size);
            for (int i = 0; i < size; ++i)
                vresult[i] = op(lvec[i], rvec[i]);
        }

        return vresult;
    }

    Result total() const {
        Op op;
        return op(l->total(), r->total());
    }

    virtual size_t size() const {
        int ls = l->size();
        int 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;
        }
    }
    /**
     * Return true if any children of node are binned
     *@return True if either child of node is binned.
     */
    virtual bool binned() const { return (l->binned() || r->binned()); }

    virtual std::string str() const
    {
        return csprintf("(%s %s %s)", l->str(), OpString<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();
        int size = lvec.size();
        assert(size > 0);

        vresult[0] = 0.0;

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

        return vresult;
    }

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

        Result vresult = 0.0;

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

        return vresult;
    }

    virtual size_t size() const { return 1; }
    /**
     * Return true if child of node is binned.
     *@return True if child of node is binned.
     */
    virtual bool binned() const { return l->binned(); }

    virtual 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. By default these
 * store counters and don't use binning, but are templatized to accept any type
 * and any Bin class.
 * @{
 */

/**
 * This is an easy way to assign all your stats to be binned or not
 * binned.  If the typedef is NoBin, nothing is binned.  If it is
 * MainBin, then all stats are binned under that Bin.
 */
#if defined(STATS_BINNING)
typedef MainBin DefaultBin;
#else
typedef NoBin DefaultBin;
#endif

/**
 * This is a simple scalar statistic, like a counter.
 * @sa Stat, ScalarBase, StatStor
 */
template <class Bin = DefaultBin>
class Scalar
    : public Wrap<Scalar<Bin>,
                  ScalarBase<StatStor, Bin>,
                  ScalarStatData>
{
  public:
    /** The base implementation. */
    typedef ScalarBase<StatStor, Bin> Base;

    Scalar()
    {
        this->setInit();
    }

    /**
     * Sets the stat equal to the given value. Calls the base implementation
     * of operator=
     * @param v The new value.
     */
    template <typename U>
    void operator=(const U &v) { Base::operator=(v); }
};

class Value
    : public Wrap<Value,
                  ValueBase,
                  ScalarStatData>
{
  public:
    /** The base implementation. */
    typedef ValueBase Base;

    template <class T>
    Value &scalar(T &value)
    {
        Base::scalar(value);
        return *this;
    }

    template <class T>
    Value &functor(T &func)
    {
        Base::functor(func);
        return *this;
    }
};

/**
 * A stat that calculates the per cycle average of a value.
 * @sa Stat, ScalarBase, AvgStor
 */
template <class Bin = DefaultBin>
class Average
    : public Wrap<Average<Bin>,
                  ScalarBase<AvgStor, Bin>,
                  ScalarStatData>
{
  public:
    /** The base implementation. */
    typedef ScalarBase<AvgStor, Bin> Base;

    Average()
    {
        this->setInit();
    }

    /**
     * Sets the stat equal to the given value. Calls the base implementation
     * of operator=
     * @param v The new value.
     */
    template <typename U>
    void operator=(const U &v) { Base::operator=(v); }
};

/**
 * A vector of scalar stats.
 * @sa Stat, VectorBase, StatStor
 */
template <class Bin = DefaultBin>
class Vector
    : public WrapVec<Vector<Bin>,
                     VectorBase<StatStor, Bin>,
                     VectorStatData>
{
  public:
    /** The base implementation. */
    typedef ScalarBase<StatStor, Bin> Base;

    /**
     * Set this vector to have the given size.
     * @param size The new size.
     * @return A reference to this stat.
     */
    Vector &init(size_t size) {
        this->bin.init(size, this->params);
        this->setInit();

        return *this;
    }
};

/**
 * A vector of Average stats.
 * @sa Stat, VectorBase, AvgStor
 */
template <class Bin = DefaultBin>
class AverageVector
    : public WrapVec<AverageVector<Bin>,
                     VectorBase<AvgStor, Bin>,
                     VectorStatData>
{
  public:
    /**
     * Set this vector to have the given size.
     * @param size The new size.
     * @return A reference to this stat.
     */
    AverageVector &init(size_t size) {
        this->bin.init(size, this->params);
        this->setInit();

        return *this;
    }
};

/**
 * A 2-Dimensional vecto of scalar stats.
 * @sa Stat, Vector2dBase, StatStor
 */
template <class Bin = DefaultBin>
class Vector2d
    : public WrapVec2d<Vector2d<Bin>,
                       Vector2dBase<StatStor, Bin>,
                       Vector2dStatData>
{
  public:
    Vector2d &init(size_t _x, size_t _y) {
        this->statData()->x = this->x = _x;
        this->statData()->y = this->y = _y;
        this->bin.init(this->x * this->y, this->params);
        this->setInit();

        return *this;
    }
};

/**
 * A simple distribution stat.
 * @sa Stat, DistBase, DistStor
 */
template <class Bin = DefaultBin>
class Distribution
    : public Wrap<Distribution<Bin>,
                  DistBase<DistStor, Bin>,
                  DistStatData>
{
  public:
    /** Base implementation. */
    typedef DistBase<DistStor, Bin> Base;
    /** The Parameter type. */
    typedef typename DistStor::Params Params;

  public:
    /**
     * 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) {
        this->params.min = min;
        this->params.max = max;
        this->params.bucket_size = bkt;
        this->params.size = (int)rint((max - min) / bkt + 1.0);
        this->bin.init(this->params);
        this->setInit();

        return *this;
    }
};

/**
 * Calculates the mean and variance of all the samples.
 * @sa Stat, DistBase, FancyStor
 */
template <class Bin = DefaultBin>
class StandardDeviation
    : public Wrap<StandardDeviation<Bin>,
                  DistBase<FancyStor, Bin>,
                  DistStatData>
{
  public:
    /** The base implementation */
    typedef DistBase<DistStor, Bin> Base;
    /** The parameter type. */
    typedef typename DistStor::Params Params;

  public:
    /**
     * Construct and initialize this distribution.
     */
    StandardDeviation() {
        this->bin.init(this->params);
        this->setInit();
    }
};

/**
 * Calculates the per cycle mean and variance of the samples.
 * @sa Stat, DistBase, AvgFancy
 */
template <class Bin = DefaultBin>
class AverageDeviation
    : public Wrap<AverageDeviation<Bin>,
                  DistBase<AvgFancy, Bin>,
                  DistStatData>
{
  public:
    /** The base implementation */
    typedef DistBase<DistStor, Bin> Base;
    /** The parameter type. */
    typedef typename DistStor::Params Params;

  public:
    /**
     * Construct and initialize this distribution.
     */
    AverageDeviation()
    {
        this->bin.init(this->params);
        this->setInit();
    }
};

/**
 * A vector of distributions.
 * @sa Stat, VectorDistBase, DistStor
 */
template <class Bin = DefaultBin>
class VectorDistribution
    : public WrapVec<VectorDistribution<Bin>,
                     VectorDistBase<DistStor, Bin>,
                     VectorDistStatData>
{
  public:
    /** The base implementation */
    typedef VectorDistBase<DistStor, Bin> Base;
    /** The parameter type. */
    typedef typename DistStor::Params Params;

  public:
    /**
     * 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(int size, Counter min, Counter max, Counter bkt) {
        this->params.min = min;
        this->params.max = max;
        this->params.bucket_size = bkt;
        this->params.size = (int)rint((max - min) / bkt + 1.0);
        this->bin.init(size, this->params);
        this->setInit();

        return *this;
    }
};

/**
 * This is a vector of StandardDeviation stats.
 * @sa Stat, VectorDistBase, FancyStor
 */
template <class Bin = DefaultBin>
class VectorStandardDeviation
    : public WrapVec<VectorStandardDeviation<Bin>,
                     VectorDistBase<FancyStor, Bin>,
                     VectorDistStatData>
{
  public:
    /** The base implementation */
    typedef VectorDistBase<FancyStor, Bin> Base;
    /** The parameter type. */
    typedef typename DistStor::Params Params;

  public:
    /**
     * Initialize storage for this distribution.
     * @param size The size of the vector.
     * @return A reference to this distribution.
     */
    VectorStandardDeviation &init(int size) {
        this->bin.init(size, this->params);
        this->setInit();

        return *this;
    }
};

/**
 * This is a vector of AverageDeviation stats.
 * @sa Stat, VectorDistBase, AvgFancy
 */
template <class Bin = DefaultBin>
class VectorAverageDeviation
    : public WrapVec<VectorAverageDeviation<Bin>,
                     VectorDistBase<AvgFancy, Bin>,
                     VectorDistStatData>
{
  public:
    /** The base implementation */
    typedef VectorDistBase<AvgFancy, Bin> Base;
    /** The parameter type. */
    typedef typename DistStor::Params Params;

  public:
    /**
     * Initialize storage for this distribution.
     * @param size The size of the vector.
     * @return A reference to this distribution.
     */
    VectorAverageDeviation &init(int size) {
        this->bin.init(size, this->params);
        this->setInit();

        return *this;
    }
};

/**
 * 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 FormulaBase : public DataAccess
{
  protected:
    /** The root of the tree which represents the Formula */
    NodePtr root;
    friend class Temp;

  public:
    /**
     * 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_t size() const;

    /**
     * Return true if Formula is binned. i.e. any of its children
     * nodes are binned
     * @return True if Formula is binned.
     */
    bool binned() const;

    bool check() const { return true; }

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

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

    /**
     *
     */
    void update(StatData *);

    std::string str() const;
};

class FormulaData : public VectorData
{
  public:
    virtual std::string str() const = 0;
    virtual bool check() const { return true; }
};

template <class Stat>
class FormulaStatData : public FormulaData
{
  protected:
    Stat &s;
    mutable VResult vec;
    mutable VCounter cvec;

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

    virtual bool binned() const { return s.binned(); }
    virtual bool zero() const { return s.zero(); }
    virtual void reset() { s.reset(); }

    virtual size_t size() const { return s.size(); }
    virtual const VResult &result() const
    {
        s.result(vec);
        return vec;
    }
    virtual Result total() const { return s.total(); }
    virtual VCounter &value() const { return cvec; }
    virtual void visit(Visit &visitor)
    {
        update();
        s.update(this);
        visitor.visit(*this);
    }
    virtual std::string str() const { return s.str(); }
};

class Temp;
class Formula
    : public WrapVec<Formula,
                     FormulaBase,
                     FormulaStatData>
{
  public:
    /**
     * Create and initialize thie formula, and register it with the database.
     */
    Formula();

    /**
     * Create a formula with the given root node, register it with the
     * database.
     * @param r The root of the expression tree.
     */
    Formula(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=(Temp r);

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

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

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

    virtual size_t size() const { return formula.size(); }
    virtual const VResult &result() const { formula.result(vec); return vec; }
    virtual Result total() const { return formula.total(); }
    virtual bool binned() const { return formula.binned(); }

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

/**
 * 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(NodePtr n) : node(n) { }

    /**
     * Return the node pointer.
     * @return the node pointer.
     */
    operator NodePtr&() { return node;}

  public:
    /**
     * Create a new ScalarStatNode.
     * @param s The ScalarStat to place in a node.
     */
    template <class Bin>
    Temp(const Scalar<Bin> &s)
        : node(new ScalarStatNode(s.statData())) { }

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

    /**
     * Create a new ScalarStatNode.
     * @param s The ScalarStat to place in a node.
     */
    template <class Bin>
    Temp(const Average<Bin> &s)
        : node(new ScalarStatNode(s.statData())) { }

    /**
     * Create a new VectorStatNode.
     * @param s The VectorStat to place in a node.
     */
    template <class Bin>
    Temp(const Vector<Bin> &s)
        : node(new VectorStatNode(s.statData())) { }

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

    /**
     * Create a new ScalarProxyNode.
     * @param p The ScalarProxy to place in a node.
     */
    template <class Storage, class Bin>
    Temp(const ScalarProxy<Storage, Bin> &p)
        : node(new ScalarProxyNode<Storage, Bin>(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)) {}
};


/**
 * @}
 */

void check();
void reset();
void registerResetCallback(Callback *cb);

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

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

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

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

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

template <typename T>
inline Temp
constant(T val)
{
    return NodePtr(new ConstNode<T>(val));
}

inline Temp
sum(Temp val)
{
    return NodePtr(new SumNode<std::plus<Result> >(val));
}

/* namespace Stats */ }

#endif // __BASE_STATISTICS_HH__
