/*
 * Copyright (c) 2021 Daniel R. Carvalho
 * Copyright (c) 2019 Arm Limited
 * All rights reserved.
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2003-2005 The Regents of The University of Michigan
 * 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.
 */

#include "base/stats/storage.hh"

#include <cmath>

namespace gem5
{

namespace statistics
{

void
DistStor::sample(Counter val, int number)
{
    assert(bucket_size > 0);
    if (val < min_track)
        underflow += number;
    else if (val > max_track)
        overflow += number;
    else {
        cvec[std::floor((val - min_track) / bucket_size)] += number;
    }

    if (val < min_val)
        min_val = val;

    if (val > max_val)
        max_val = val;

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

void
HistStor::growOut()
{
    int size = cvec.size();
    int zero = size / 2; // round down!
    int top_half = zero + (size - zero + 1) / 2; // round up!
    int bottom_half = (size - zero) / 2; // round down!

    // grow down
    int low_pair = zero - 1;
    for (int i = zero - 1; i >= bottom_half; i--) {
        cvec[i] = cvec[low_pair];
        if (low_pair - 1 >= 0)
            cvec[i] += cvec[low_pair - 1];
        low_pair -= 2;
    }
    assert(low_pair == 0 || low_pair == -1 || low_pair == -2);

    for (int i = bottom_half - 1; i >= 0; i--)
        cvec[i] = Counter();

    // grow up
    int high_pair = zero;
    for (int i = zero; i < top_half; i++) {
        cvec[i] = cvec[high_pair];
        if (high_pair + 1 < size)
            cvec[i] += cvec[high_pair + 1];
        high_pair += 2;
    }
    assert(high_pair == size || high_pair == size + 1);

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

    max_bucket *= 2;
    min_bucket *= 2;
    bucket_size *= 2;
}

void
HistStor::growDown()
{
    const int size = cvec.size();
    const int zero = size / 2; // round down!
    const bool even = ((size - 1) % 2) == 0;

    // Make sure that zero becomes the lower bound of the middle bucket. On
    // an even number of buckets the last bucket does not change its lower
    // bound, therefore it does not need to absorb any other bucket
    int pair = size - 1;
    if (even) {
        pair--;
    }
    for (int i = pair; i >= zero; --i) {
        cvec[i] = cvec[pair];
        if (pair - 1 >= 0)
            cvec[i] += cvec[pair - 1];
        pair -= 2;
    }

    for (int i = zero - 1; i >= 0; i--)
        cvec[i] = Counter();

    // Double the range by using the negative of the lower bound of the last
    // bucket as the new lower bound of the first bucket
    min_bucket = -max_bucket;

    // A special case must be handled when there is an odd number of
    // buckets so that zero is kept as the lower bound of the middle bucket
    if (!even) {
        min_bucket -= bucket_size;
        max_bucket -= bucket_size;
    }

    // Only update the bucket size once the range has been updated
    bucket_size *= 2;
}

void
HistStor::growUp()
{
    int size = cvec.size();
    int half = (size + 1) / 2; // round up!

    int pair = 0;
    for (int i = 0; i < half; i++) {
        cvec[i] = cvec[pair];
        if (pair + 1 < size)
            cvec[i] += cvec[pair + 1];
        pair += 2;
    }
    assert(pair == size || pair == size + 1);

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

    max_bucket *= 2;
    bucket_size *= 2;
}

void
HistStor::sample(Counter val, int number)
{
    assert(min_bucket < max_bucket);
    if (val < min_bucket) {
        if (min_bucket == 0)
            growDown();

        while (val < min_bucket)
            growOut();
    } else if (val >= max_bucket + bucket_size) {
        if (min_bucket == 0) {
            while (val >= max_bucket + bucket_size)
                growUp();
        } else {
            while (val >= max_bucket + bucket_size)
                growOut();
        }
    }

    assert(bucket_size > 0);
    size_type index =
        (int64_t)std::floor((val - min_bucket) / bucket_size);

    assert(index < size());
    cvec[index] += number;

    sum += val * number;
    squares += val * val * number;
    logs += std::log(val) * number;
    samples += number;
}

void
HistStor::add(HistStor *hs)
{
    int b_size = hs->size();
    assert(size() == b_size);
    assert(min_bucket == hs->min_bucket);

    sum += hs->sum;
    logs += hs->logs;
    squares += hs->squares;
    samples += hs->samples;

    while (bucket_size > hs->bucket_size)
        hs->growUp();
    while (bucket_size < hs->bucket_size)
        growUp();

    for (uint32_t i = 0; i < b_size; i++)
        cvec[i] += hs->cvec[i];
}

} // namespace statistics
} // namespace gem5
