/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_LIBARTBASE_BASE_HISTOGRAM_INL_H_
#define ART_LIBARTBASE_BASE_HISTOGRAM_INL_H_

#include <algorithm>
#include <cmath>
#include <limits>
#include <ostream>

#include "histogram.h"

#include <android-base/logging.h>

#include "bit_utils.h"
#include "time_utils.h"
#include "utils.h"

namespace art {

template <class Value> inline void Histogram<Value>::AddValue(Value value) {
  CHECK_GE(value, static_cast<Value>(0));
  if (value >= max_) {
    Value new_max = ((value + 1) / bucket_width_ + 1) * bucket_width_;
    DCHECK_GT(new_max, max_);
    GrowBuckets(new_max);
  }
  BucketiseValue(value);
}

template <class Value> inline void Histogram<Value>::AdjustAndAddValue(Value value) {
  AddValue(value / kAdjust);
}

template <class Value> inline Histogram<Value>::Histogram(const char* name)
    : kAdjust(0),
      kInitialBucketCount(0),
      name_(name),
      max_buckets_(0),
      sample_size_(0) {
}

template <class Value>
inline Histogram<Value>::Histogram(const char* name, Value initial_bucket_width,
                                   size_t max_buckets)
    : kAdjust(1000),
      kInitialBucketCount(kMinBuckets),
      name_(name),
      max_buckets_(max_buckets),
      bucket_width_(initial_bucket_width) {
  CHECK_GE(max_buckets, kInitialBucketCount);
  CHECK_EQ(max_buckets_ % 2, 0u);
  Reset();
}

template <class Value>
inline void Histogram<Value>::GrowBuckets(Value new_max) {
  while (max_ < new_max) {
    // If we have reached the maximum number of buckets, merge buckets together.
    DCHECK_LE(frequency_.size(), max_buckets_);
    if (frequency_.size() == max_buckets_) {
      DCHECK_EQ(frequency_.size() % 2, 0u);
      // We double the width of each bucket to reduce the number of buckets by a factor of 2.
      bucket_width_ *= 2;
      const size_t limit = frequency_.size() / 2;
      // Merge the frequencies by adding each adjacent two together.
      for (size_t i = 0; i < limit; ++i) {
        frequency_[i] = frequency_[i * 2] + frequency_[i * 2 + 1];
      }
      // Remove frequencies in the second half of the array which were added to the first half.
      while (frequency_.size() > limit) {
        frequency_.pop_back();
      }
    }
    max_ += bucket_width_;
    frequency_.push_back(0);
  }
}

template <class Value> inline size_t Histogram<Value>::FindBucket(Value val) const {
  // Since this is only a linear histogram, bucket index can be found simply with
  // dividing the value by the bucket width.
  DCHECK_GE(val, min_);
  DCHECK_LE(val, max_);
  const size_t bucket_idx = static_cast<size_t>((val - min_) / bucket_width_);
  DCHECK_GE(bucket_idx, 0ul);
  DCHECK_LE(bucket_idx, GetBucketCount());
  return bucket_idx;
}

template <class Value>
inline void Histogram<Value>::BucketiseValue(Value val) {
  CHECK_LT(val, max_);
  sum_ += val;
  sum_of_squares_ += val * val;
  ++sample_size_;
  ++frequency_[FindBucket(val)];
  max_value_added_ = std::max(val, max_value_added_);
  min_value_added_ = std::min(val, min_value_added_);
}

template <class Value> inline void Histogram<Value>::Initialize() {
  for (size_t idx = 0; idx < kInitialBucketCount; idx++) {
    frequency_.push_back(0);
  }
  // Cumulative frequency and ranges has a length of 1 over frequency.
  max_ = bucket_width_ * GetBucketCount();
}

template <class Value> inline size_t Histogram<Value>::GetBucketCount() const {
  return frequency_.size();
}

template <class Value> inline void Histogram<Value>::Reset() {
  sum_of_squares_ = 0;
  sample_size_ = 0;
  min_ = 0;
  sum_ = 0;
  min_value_added_ = std::numeric_limits<Value>::max();
  max_value_added_ = std::numeric_limits<Value>::min();
  frequency_.clear();
  Initialize();
}

template <class Value> inline Value Histogram<Value>::GetRange(size_t bucket_idx) const {
  DCHECK_LE(bucket_idx, GetBucketCount());
  return min_ + bucket_idx * bucket_width_;
}

template <class Value> inline double Histogram<Value>::Mean() const {
  DCHECK_GT(sample_size_, 0ull);
  return static_cast<double>(sum_) / static_cast<double>(sample_size_);
}

template <class Value> inline double Histogram<Value>::Variance() const {
  DCHECK_GT(sample_size_, 0ull);
  // Using algorithms for calculating variance over a population:
  // http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
  Value sum_squared = sum_ * sum_;
  double sum_squared_by_n_squared =
      static_cast<double>(sum_squared) /
      static_cast<double>(sample_size_ * sample_size_);
  double sum_of_squares_by_n =
      static_cast<double>(sum_of_squares_) / static_cast<double>(sample_size_);
  return sum_of_squares_by_n - sum_squared_by_n_squared;
}

template <class Value>
inline void Histogram<Value>::PrintBins(std::ostream& os, const CumulativeData& data) const {
  DCHECK_GT(sample_size_, 0ull);
  for (size_t bin_idx = 0; bin_idx < data.freq_.size(); ++bin_idx) {
    if (bin_idx > 0 && data.perc_[bin_idx] == data.perc_[bin_idx - 1]) {
      bin_idx++;
      continue;
    }
    os << GetRange(bin_idx) << ": " << data.freq_[bin_idx] << "\t"
       << data.perc_[bin_idx] * 100.0 << "%\n";
  }
}

template <class Value>
inline void Histogram<Value>::DumpBins(std::ostream& os) const {
  DCHECK_GT(sample_size_, 0ull);
  bool dumped_one = false;
  for (size_t bin_idx = 0; bin_idx < frequency_.size(); ++bin_idx) {
    if (frequency_[bin_idx] != 0U) {
      if (dumped_one) {
        // Prepend a comma if not the first bin.
        os << ",";
      } else {
        dumped_one = true;
      }
      os << GetRange(bin_idx) << ":" << frequency_[bin_idx];
    }
  }
}

template <class Value>
inline void Histogram<Value>::PrintConfidenceIntervals(std::ostream &os, double interval,
                                                       const CumulativeData& data) const {
  static constexpr size_t kFractionalDigits = 3;
  DCHECK_GT(interval, 0);
  DCHECK_LT(interval, 1.0);
  const double per_0 = (1.0 - interval) / 2.0;
  const double per_1 = per_0 + interval;
  const TimeUnit unit = GetAppropriateTimeUnit(Mean() * kAdjust);
  os << Name() << ":\tSum: " << PrettyDuration(Sum() * kAdjust) << " "
     << (interval * 100) << "% C.I. " << FormatDuration(Percentile(per_0, data) * kAdjust, unit,
                                                        kFractionalDigits)
     << "-" << FormatDuration(Percentile(per_1, data) * kAdjust, unit, kFractionalDigits) << " "
     << "Avg: " << FormatDuration(Mean() * kAdjust, unit, kFractionalDigits) << " Max: "
     << FormatDuration(Max() * kAdjust, unit, kFractionalDigits) << std::endl;
}

template <class Value>
inline void Histogram<Value>::PrintMemoryUse(std::ostream &os) const {
  os << Name();
  if (sample_size_ != 0u) {
    os << ": Avg: " << PrettySize(Mean()) << " Max: "
       << PrettySize(Max()) << " Min: " << PrettySize(Min()) << "\n";
  } else {
    os << ": <no data>\n";
  }
}

template <class Value>
inline void Histogram<Value>::CreateHistogram(CumulativeData* out_data) const {
  DCHECK_GT(sample_size_, 0ull);
  out_data->freq_.clear();
  out_data->perc_.clear();
  uint64_t accumulated = 0;
  out_data->freq_.push_back(accumulated);
  out_data->perc_.push_back(0.0);
  for (size_t idx = 0; idx < frequency_.size(); idx++) {
    accumulated += frequency_[idx];
    out_data->freq_.push_back(accumulated);
    out_data->perc_.push_back(static_cast<double>(accumulated) / static_cast<double>(sample_size_));
  }
  DCHECK_EQ(out_data->freq_.back(), sample_size_);
  DCHECK_LE(std::abs(out_data->perc_.back() - 1.0), 0.001);
}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wfloat-equal"

template <class Value>
inline double Histogram<Value>::Percentile(double per, const CumulativeData& data) const {
  DCHECK_GT(data.perc_.size(), 0ull);
  size_t upper_idx = 0, lower_idx = 0;
  for (size_t idx = 0; idx < data.perc_.size(); idx++) {
    if (per <= data.perc_[idx]) {
      upper_idx = idx;
      break;
    }

    if (per >= data.perc_[idx] && idx != 0 && data.perc_[idx] != data.perc_[idx - 1]) {
      lower_idx = idx;
    }
  }

  const double lower_perc = data.perc_[lower_idx];
  const double lower_value = static_cast<double>(GetRange(lower_idx));
  if (per == lower_perc) {
    return lower_value;
  }

  const double upper_perc = data.perc_[upper_idx];
  const double upper_value = static_cast<double>(GetRange(upper_idx));
  if (per == upper_perc) {
    return upper_value;
  }
  DCHECK_GT(upper_perc, lower_perc);

  double value = lower_value + (upper_value - lower_value) *
                               (per - lower_perc) / (upper_perc - lower_perc);

  if (value < min_value_added_) {
    value = min_value_added_;
  } else if (value > max_value_added_) {
    value = max_value_added_;
  }

  return value;
}

#pragma clang diagnostic pop

}  // namespace art
#endif  // ART_LIBARTBASE_BASE_HISTOGRAM_INL_H_
