/*
 * Copyright (c) 2021 Daniel R. Carvalho
 * 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.
 */

#ifndef __BASE_STATS_STORAGE_HH__
#define __BASE_STATS_STORAGE_HH__

#include <cassert>
#include <cmath>

#include "base/cast.hh"
#include "base/compiler.hh"
#include "base/logging.hh"
#include "base/stats/types.hh"
#include "sim/cur_tick.hh"

namespace gem5
{

GEM5_DEPRECATED_NAMESPACE(Stats, statistics);
namespace statistics
{

struct StorageParams
{
    virtual ~StorageParams() = default;
};

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

  public:
    struct Params : public StorageParams {};

    /**
     * Builds this storage element and calls the base constructor of the
     * datatype.
     */
    StatStor(const StorageParams* const storage_params)
        : 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(const StorageParams* const storage_params) { }

    /**
     * Reset stat value to default
     */
    void reset(const StorageParams* const storage_params) { 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 {};

    /**
     * Build and initializes this stat storage.
     */
    AvgStor(const StorageParams* const storage_params)
        : 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(const StorageParams* const storage_params)
    {
        total += current * (curTick() - last);
        last = curTick();
    }

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

};

/** 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. A distribution
 * uses buckets to keep track of values within a given range. All other
 * values, although accounted for on the overall calculations, are not tracked
 * in buckets themselves; two special counters, underflow and overflow store
 * the number of occurrences of such values.
 */
class DistStor
{
  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:
    /** 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(Counter _min, Counter _max, Counter _bucket_size)
          : DistParams(Dist), min(_min), max(_max), bucket_size(_bucket_size),
            buckets(0)
        {
            fatal_if(bucket_size <= 0,
                "Bucket size (%f) must be greater than zero", bucket_size);
            warn_if(std::floor((max - min + 1.0) / bucket_size) !=
                std::ceil((max - min + 1.0) / bucket_size),
                "Bucket size (%f) does not divide range [%f:%f] into equal-" \
                "sized buckets. Rounding up.", bucket_size, min + 1.0, max);

            buckets = std::ceil((max - min + 1.0) / bucket_size);
        }
    };

    DistStor(const StorageParams* const storage_params)
        : cvec(safe_cast<const Params *>(storage_params)->buckets)
    {
        reset(storage_params);
    }

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

    /**
     * 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(const StorageParams* const storage_params, DistData &data)
    {
        const Params *params = safe_cast<const Params *>(storage_params);

        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(const StorageParams* const storage_params)
    {
        const Params *params = safe_cast<const Params *>(storage_params);
        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.
 *
 * The number of buckets is fixed on initialization; however, the bucket size
 * isn't. That means that when samples that are outside the current range are
 * seen, the bucket size will be increased so that each bucket can hold a
 * bigger range of values. When that happens, the bucket's contents are re-
 * located.
 *
 * The min and max bucket values can only be, respectively, decreased and
 * increased when sampling. If this wasn't true, samples that were previously
 * within the buclet range could not be anymore within the valid range, making
 * the storage's state incoherent. These values are set back to their initial
 * states on reset().
 *
 * The bucket range always is zero-centric. While the storage does not
 * contain negative values the bucket range will keep its lower bound at
 * zero, doubling the upper bound when needed; However, as soon a negative
 * value is sampled, zero becomes the lower bound of the middle (rounded up)
 * bucket. Although this means that the histogram will not be symmetric if
 * negative values are sampled, it makes it possible to grow the buckets
 * without keeping track of the individual values.
 *
 * This happens because if zero was not a lower or upper bound, when its
 * value was doubled, the lower and upper bound of the bucket containing
 * zero would intersect with middle values of the previous and next buckets.
 * For example, if the bucket containing zero has range [-2,2[, therefore
 * its neighbor buckets would have ranges at [-6,-2[ and [2,6[. When the
 * buckets are grown, the zero bucket would grow its range to [-4,4[, which
 * cannot be easily extracted from the neighor buckets.
 */
class HistStor
{
  private:
    /** Lower bound of the first bucket's range. */
    Counter min_bucket;
    /** Lower bound of the last bucket's range. */
    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;

    /**
     * Given a bucket size B, and a range of values [0, N], this function
     * doubles the bucket size to double the range of values towards the
     * positive infinite; that is, double the upper range of this storage
     * so that the range becomes [0, 2*N].
     *
     * Because the bucket size is doubled, the buckets contents are rearranged,
     * since the original range of values is mapped to the lower half buckets.
     */
    void growUp();

    /**
     * Given a bucket size B, and a range of values [M, N], where M < 0, this
     * function doubles the bucket size to double the range of values towards
     * both positive and negative infinites; that is, it doubles both the lower
     * and the upper range of this storage so that the range becomes
     * [2*M, 2*N].
     *
     * Because the bucket size is doubled, the buckets contents are
     * rearranged, and the original range of values are redistributed to free
     * buckets for the newly appended ranges.
     */
    void growOut();

    /**
     * Given a bucket size B, and a range of values [0, N], this function
     * doubles the bucket size to double the range of values towards the
     * negative infinite; that is, it doubles the lower range of this
     * storage so that the middle buckes contaihs zero as a lower bound. As
     * such, the storage range becomes [-N, N+B] if there is an odd number
     * of buckets, and [-N-B, N+B] if there is an even number of buckets.
     *
     * Because the bucket size is doubled, the buckets contents are
     * rearranged, and the original range of values are redistributed to free
     * buckets for the newly appended ranges.
     */
    void growDown();

  public:
    /** The parameters for a distribution stat. */
    struct Params : public DistParams
    {
        /** The number of buckets. */
        size_type buckets;

        Params(size_type _buckets)
          : DistParams(Hist)
        {
            fatal_if(_buckets < 2,
                "There must be at least two buckets in a histogram");
            buckets = _buckets;
        }
    };

    HistStor(const StorageParams* const storage_params)
        : cvec(safe_cast<const Params *>(storage_params)->buckets)
    {
        reset(storage_params);
    }

    /**
     * Adds the contents of the given storage to this storage.
     * @param other The other storage to be added.
     */
    void add(HistStor *other);

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

    /**
     * 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(const StorageParams* const storage_params, DistData &data)
    {
        const Params *params = safe_cast<const Params *>(storage_params);

        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(const StorageParams* const storage_params)
    {
        const Params *params = safe_cast<const Params *>(storage_params);
        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
{
  private:
    /** The current sum. */
    Counter sum;
    /** The sum of squares. */
    Counter squares;
    /** The number of samples. */
    Counter samples;

  public:
    struct Params : public DistParams
    {
        Params() : DistParams(Deviation) {}
    };

    /**
     * Create and initialize this storage.
     */
    SampleStor(const StorageParams* const storage_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.
     */
    void
    sample(Counter val, int number)
    {
        sum += val * number;
        squares += val * val * number;
        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(const StorageParams* const storage_params, DistData &data)
    {
        const Params *params = safe_cast<const Params *>(storage_params);

        assert(params->type == Deviation);
        data.type = params->type;
        data.sum = sum;
        data.squares = squares;
        data.samples = samples;
    }

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

/**
 * Templatized storage for distribution that calculates per tick mean and
 * variance.
 */
class AvgSampleStor
{
  private:
    /** Current total. */
    Counter sum;
    /** Current sum of squares. */
    Counter squares;

  public:
    struct Params : public DistParams
    {
        Params() : DistParams(Deviation) {}
    };

    /**
     * Create and initialize this storage.
     */
    AvgSampleStor(const StorageParams* const storage_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.
     */
    void
    sample(Counter val, int number)
    {
        sum += val * number;
        squares += val * val * number;
    }

    /**
     * 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(const StorageParams* const storage_params, DistData &data)
    {
        const Params *params = safe_cast<const Params *>(storage_params);

        assert(params->type == Deviation);
        data.type = params->type;
        data.sum = sum;
        data.squares = squares;
        data.samples = curTick();
    }

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

/**
 * Templatized storage and interface for a sparse histogram stat. There
 * is no actual limit on the number of buckets, and each of them has a size
 * of 1, meaning that samples are individually recorded, and there is no
 * need to keep track of the samples that occur in between two distant
 * sampled values.
 */
class SparseHistStor
{
  private:
    /** Counter for number of samples */
    Counter samples;
    /** Counter for each bucket. */
    MCounter cmap;

  public:
    /** The parameters for a sparse histogram stat. */
    struct Params : public DistParams
    {
        Params() : DistParams(Hist) {}
    };

    SparseHistStor(const StorageParams* const storage_params)
    {
        reset(storage_params);
    }

    /**
     * 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(const StorageParams* const storage_params, 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(const StorageParams* const storage_params)
    {
        cmap.clear();
        samples = 0;
    }
};

} // namespace statistics
} // namespace gem5

#endif // __BASE_STATS_STORAGE_HH__
