/*
 * Copyright (c) 2019-2020 Inria
 * 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 __MEM_CACHE_COMPRESSORS_FREQUENT_VALUES_HH__
#define __MEM_CACHE_COMPRESSORS_FREQUENT_VALUES_HH__

#include <climits>
#include <cstdint>
#include <memory>
#include <vector>

#include "base/sat_counter.hh"
#include "base/types.hh"
#include "mem/cache/base.hh"
#include "mem/cache/compressors/base.hh"
#include "mem/cache/compressors/encoders/huffman.hh"
#include "mem/cache/prefetch/associative_set.hh"
#include "sim/eventq.hh"
#include "sim/probe/probe.hh"

namespace gem5
{

struct FrequentValuesCompressorParams;

GEM5_DEPRECATED_NAMESPACE(Compressor, compression);
namespace compression
{

/**
 * This compressor samples the cache for a while, trying to define the
 * most frequently used values. When these values are determined, they are
 * associated to shorter representations (codes). Then the compressor can
 * start its effective compression phase, in which occurrences of these
 * values are substituted by their codes.
 */
class FrequentValues : public Base
{
  private:
    class CompData;

    using DataUpdate = BaseCache::DataUpdate;

    class FrequentValuesListener : public ProbeListenerArgBase<DataUpdate>
    {
      protected:
        FrequentValues &parent;

      public:
        FrequentValuesListener(FrequentValues &_parent, ProbeManager *pm,
            const std::string &name)
          : ProbeListenerArgBase(pm, name), parent(_parent)
        {
        }
        void notify(const DataUpdate &data_update) override;
    };
    std::vector<FrequentValuesListener*> listeners;

    /** Whether Huffman encoding is applied to the VFT indices. */
    const bool useHuffmanEncoding;

    /** The encoder applied to the VFT indices. */
    encoder::Huffman indexEncoder;

    /** Number of bits in the saturating counters. */
    const int counterBits;

    /** Ticks needed to perform the CODE_GENERATION phase. */
    const Tick codeGenerationTicks;

    /** Whether an action must be performed when counters saturate. */
    const bool checkSaturation;

    /** Maximum number of VFT entries, and thus of codewords too. */
    const unsigned numVFTEntries;

    /** Number of samples in the sampling phase. */
    const unsigned numSamples;

    /** Number of samples taken so far. */
    unsigned takenSamples;

    /**
     * The phase that the compressor is at. It assumes that sampling and
     * code generation are done only once.
     */
    enum Phase {SAMPLING, CODE_GENERATION, COMPRESSING};
    Phase phase;

    class VFTEntry : public TaggedEntry
    {
      public:
        /**
         * The value is stored as a 64 bit entry to accomodate for the
         * uncompressed value. All real values must be 32 bits.
         */
        uint64_t value;

        /**
         * The ideal counter width (in bits) is determined by the maximum
         * number of times a given value appears in the cache
         * (log2(cache_size / chunkSizeBits)). If smaller counters are used
         * their values should be rescaled when saturated.
         */
        SatCounter32 counter;

        VFTEntry(std::size_t num_bits)
          : TaggedEntry(), value(0), counter(num_bits)
        {
        }

        void
        invalidate() override
        {
            TaggedEntry::invalidate();
            value = 0;
            counter.reset();
        }
    };

    /**
     * The Value Frequency Table, a small cache that keeps track and estimates
     * the frequency distribution of values in the cache.
     */
    AssociativeSet<VFTEntry> VFT;

    /**
     * A pseudo value is used as the representation of uncompressed values.
     * This value is a random value that is not present in the VFT. It is
     * selected at the end of the sampling phase.
     */
    uint64_t uncompressedValue;

    /** Event to handle finishing code generation and starting compression. */
    EventFunctionWrapper codeGenerationEvent;

    /**
     * Sample values from a packet, adding them to the VFT.
     *
     * @param data The line being sampled.
     * @param is_invalidation whether this event comes from an invalidation.
     */
    void sampleValues(const std::vector<uint64_t> &data,
        bool is_invalidation);

    /** End sampling phase and start the code generation. */
    void generateCodes();

    std::unique_ptr<Base::CompressionData> compress(
        const std::vector<Chunk>& chunks, Cycles& comp_lat,
        Cycles& decomp_lat) override;

    void decompress(const CompressionData* comp_data, uint64_t* data) override;

  public:
    typedef FrequentValuesCompressorParams Params;
    FrequentValues(const Params &p);
    ~FrequentValues() = default;

    /**
     * Process a notification event from the ProbeListener.
     *
     * @param data_update The data regarding the entry's contents update.
     */
    void probeNotify(const DataUpdate &data_update);

    void regProbeListeners() override;
};

class FrequentValues::CompData : public CompressionData
{
  public:
    /**
     * A compressed value contains its encoding, and the compressed data
     * itself.
     */
    struct CompressedValue
    {
        /** The codeword.*/
        encoder::Code code;

        /**
         * Original value, stored both for when the codeword marks an
         * uncompressed entry, and to verify correctness.
         */
        uint64_t value;

        CompressedValue(encoder::Code _code, uint64_t _value)
          : code(_code), value(_value)
        {
        }
    };

    /**
     * The values contained in the original data, after being compressed
     * sequentially.
     */
    std::vector<CompressedValue> compressedValues;
};

} // namespace compression
} // namespace gem5

#endif //__MEM_CACHE_COMPRESSORS_FREQUENT_VALUES_HH__
