// Copyright (c) 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_WINDOWED_FILTER_H_
#define QUICHE_QUIC_CORE_CONGESTION_CONTROL_WINDOWED_FILTER_H_

// Implements Kathleen Nichols' algorithm for tracking the minimum (or maximum)
// estimate of a stream of samples over some fixed time interval. (E.g.,
// the minimum RTT over the past five minutes.) The algorithm keeps track of
// the best, second best, and third best min (or max) estimates, maintaining an
// invariant that the measurement time of the n'th best >= n-1'th best.

// The algorithm works as follows. On a reset, all three estimates are set to
// the same sample. The second best estimate is then recorded in the second
// quarter of the window, and a third best estimate is recorded in the second
// half of the window, bounding the worst case error when the true min is
// monotonically increasing (or true max is monotonically decreasing) over the
// window.
//
// A new best sample replaces all three estimates, since the new best is lower
// (or higher) than everything else in the window and it is the most recent.
// The window thus effectively gets reset on every new min. The same property
// holds true for second best and third best estimates. Specifically, when a
// sample arrives that is better than the second best but not better than the
// best, it replaces the second and third best estimates but not the best
// estimate. Similarly, a sample that is better than the third best estimate
// but not the other estimates replaces only the third best estimate.
//
// Finally, when the best expires, it is replaced by the second best, which in
// turn is replaced by the third best. The newest sample replaces the third
// best.

#include "quiche/quic/core/quic_time.h"

namespace quic {

// Compares two values and returns true if the first is less than or equal
// to the second.
template <class T>
struct QUIC_EXPORT_PRIVATE MinFilter {
  bool operator()(const T& lhs, const T& rhs) const { return lhs <= rhs; }
};

// Compares two values and returns true if the first is greater than or equal
// to the second.
template <class T>
struct QUIC_EXPORT_PRIVATE MaxFilter {
  bool operator()(const T& lhs, const T& rhs) const { return lhs >= rhs; }
};

// Use the following to construct a windowed filter object of type T.
// For example, a min filter using QuicTime as the time type:
//   WindowedFilter<T, MinFilter<T>, QuicTime, QuicTime::Delta> ObjectName;
// A max filter using 64-bit integers as the time type:
//   WindowedFilter<T, MaxFilter<T>, uint64_t, int64_t> ObjectName;
// Specifically, this template takes four arguments:
// 1. T -- type of the measurement that is being filtered.
// 2. Compare -- MinFilter<T> or MaxFilter<T>, depending on the type of filter
//    desired.
// 3. TimeT -- the type used to represent timestamps.
// 4. TimeDeltaT -- the type used to represent continuous time intervals between
//    two timestamps.  Has to be the type of (a - b) if both |a| and |b| are
//    of type TimeT.
template <class T, class Compare, typename TimeT, typename TimeDeltaT>
class QUIC_EXPORT_PRIVATE WindowedFilter {
 public:
  // |window_length| is the period after which a best estimate expires.
  // |zero_value| is used as the uninitialized value for objects of T.
  // Importantly, |zero_value| should be an invalid value for a true sample.
  WindowedFilter(TimeDeltaT window_length, T zero_value, TimeT zero_time)
      : window_length_(window_length),
        zero_value_(zero_value),
        zero_time_(zero_time),
        estimates_{Sample(zero_value_, zero_time),
                   Sample(zero_value_, zero_time),
                   Sample(zero_value_, zero_time)} {}

  // Changes the window length.  Does not update any current samples.
  void SetWindowLength(TimeDeltaT window_length) {
    window_length_ = window_length;
  }

  // Updates best estimates with |sample|, and expires and updates best
  // estimates as necessary.
  void Update(T new_sample, TimeT new_time) {
    // Reset all estimates if they have not yet been initialized, if new sample
    // is a new best, or if the newest recorded estimate is too old.
    if (estimates_[0].sample == zero_value_ ||
        Compare()(new_sample, estimates_[0].sample) ||
        new_time - estimates_[2].time > window_length_) {
      Reset(new_sample, new_time);
      return;
    }

    if (Compare()(new_sample, estimates_[1].sample)) {
      estimates_[1] = Sample(new_sample, new_time);
      estimates_[2] = estimates_[1];
    } else if (Compare()(new_sample, estimates_[2].sample)) {
      estimates_[2] = Sample(new_sample, new_time);
    }

    // Expire and update estimates as necessary.
    if (new_time - estimates_[0].time > window_length_) {
      // The best estimate hasn't been updated for an entire window, so promote
      // second and third best estimates.
      estimates_[0] = estimates_[1];
      estimates_[1] = estimates_[2];
      estimates_[2] = Sample(new_sample, new_time);
      // Need to iterate one more time. Check if the new best estimate is
      // outside the window as well, since it may also have been recorded a
      // long time ago. Don't need to iterate once more since we cover that
      // case at the beginning of the method.
      if (new_time - estimates_[0].time > window_length_) {
        estimates_[0] = estimates_[1];
        estimates_[1] = estimates_[2];
      }
      return;
    }
    if (estimates_[1].sample == estimates_[0].sample &&
        new_time - estimates_[1].time > window_length_ >> 2) {
      // A quarter of the window has passed without a better sample, so the
      // second-best estimate is taken from the second quarter of the window.
      estimates_[2] = estimates_[1] = Sample(new_sample, new_time);
      return;
    }

    if (estimates_[2].sample == estimates_[1].sample &&
        new_time - estimates_[2].time > window_length_ >> 1) {
      // We've passed a half of the window without a better estimate, so take
      // a third-best estimate from the second half of the window.
      estimates_[2] = Sample(new_sample, new_time);
    }
  }

  // Resets all estimates to new sample.
  void Reset(T new_sample, TimeT new_time) {
    estimates_[0] = estimates_[1] = estimates_[2] =
        Sample(new_sample, new_time);
  }

  void Clear() { Reset(zero_value_, zero_time_); }

  T GetBest() const { return estimates_[0].sample; }
  T GetSecondBest() const { return estimates_[1].sample; }
  T GetThirdBest() const { return estimates_[2].sample; }

 private:
  struct QUIC_EXPORT_PRIVATE Sample {
    T sample;
    TimeT time;
    Sample(T init_sample, TimeT init_time)
        : sample(init_sample), time(init_time) {}
  };

  TimeDeltaT window_length_;  // Time length of window.
  T zero_value_;              // Uninitialized value of T.
  TimeT zero_time_;           // Uninitialized value of TimeT.
  Sample estimates_[3];       // Best estimate is element 0.
};

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_WINDOWED_FILTER_H_
