/*
 * 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"

struct FrequentValuesCompressorParams;

namespace Compressor {

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

    /** 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 Compressor

#endif //__MEM_CACHE_COMPRESSORS_FREQUENT_VALUES_HH__
