// Copyright (c) 2012 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.

#include "net/quic/congestion_control/hybrid_slow_start.h"

#include <algorithm>

using std::max;
using std::min;

namespace net {

// Note(pwestin): the magic clamping numbers come from the original code in
// tcp_cubic.c.
const int64 kHybridStartLowWindow = 16;
// Number of delay samples for detecting the increase of delay.
const uint32 kHybridStartMinSamples = 8;
const int kHybridStartDelayFactorExp = 4;  // 2^4 = 16
// The original paper specifies 2 and 8ms, but those have changed over time.
const int kHybridStartDelayMinThresholdUs = 4000;
const int kHybridStartDelayMaxThresholdUs = 16000;

HybridSlowStart::HybridSlowStart(const QuicClock* clock)
    : clock_(clock),
      started_(false),
      hystart_found_(NOT_FOUND),
      last_sent_sequence_number_(0),
      round_start_(QuicTime::Zero()),
      end_sequence_number_(0),
      last_close_ack_pair_time_(QuicTime::Zero()),
      rtt_sample_count_(0),
      current_min_rtt_(QuicTime::Delta::Zero()) {
}

void HybridSlowStart::OnPacketAcked(
    QuicPacketSequenceNumber acked_sequence_number, bool in_slow_start) {
  // OnPacketAcked gets invoked after ShouldExitSlowStart, so it's best to end
  // the round when the final packet of the burst is received and start it on
  // the next incoming ack.
  if (in_slow_start && IsEndOfRound(acked_sequence_number)) {
    started_ = false;
  }
}

void HybridSlowStart::OnPacketSent(QuicPacketSequenceNumber sequence_number) {
  last_sent_sequence_number_ = sequence_number;
}

void HybridSlowStart::Restart() {
  started_ = false;
  hystart_found_ = NOT_FOUND;
}

void HybridSlowStart::StartReceiveRound(QuicPacketSequenceNumber last_sent) {
  DVLOG(1) << "Reset hybrid slow start @" << last_sent;
  round_start_ = last_close_ack_pair_time_ = clock_->ApproximateNow();
  end_sequence_number_ = last_sent;
  current_min_rtt_ = QuicTime::Delta::Zero();
  rtt_sample_count_ = 0;
  started_ = true;
}

bool HybridSlowStart::IsEndOfRound(QuicPacketSequenceNumber ack) const {
  return end_sequence_number_ <= ack;
}

bool HybridSlowStart::ShouldExitSlowStart(QuicTime::Delta latest_rtt,
                                          QuicTime::Delta min_rtt,
                                          int64 congestion_window) {
  if (!started_) {
    // Time to start the hybrid slow start.
    StartReceiveRound(last_sent_sequence_number_);
  }
  if (hystart_found_ != NOT_FOUND) {
    return true;
  }
  QuicTime current_time = clock_->ApproximateNow();

  // First detection parameter - ack-train detection.
  // Since slow start burst out packets we can indirectly estimate the inter-
  // arrival time by looking at the arrival time of the ACKs if the ACKs are
  // spread out more then half the minimum RTT packets are being spread out
  // more than the capacity.
  // This first trigger will not come into play until we hit roughly 9.6 Mbps
  // with delayed acks (or 4.8Mbps without delayed acks)
  // TODO(ianswett): QUIC always uses delayed acks, even at the beginning, so
  // this should likely be at least 4ms.
  // TODO(pwestin): we need to make sure our pacing don't trigger this detector.
  // TODO(ianswett): Pacing or other cases could be handled by checking the send
  // time of the first acked packet in a receive round.
  if (current_time.Subtract(last_close_ack_pair_time_).ToMicroseconds() <=
          kHybridStartDelayMinThresholdUs) {
    last_close_ack_pair_time_ = current_time;
    if (current_time.Subtract(round_start_).ToMicroseconds() >=
            min_rtt.ToMicroseconds() >> 1) {
      hystart_found_ = ACK_TRAIN;
    }
  } else if (last_close_ack_pair_time_ == round_start_) {
    // If the previous ack wasn't close, then move forward the round start time
    // to the incoming ack.
    last_close_ack_pair_time_ = round_start_ = current_time;
  }
  // Second detection parameter - delay increase detection.
  // Compare the minimum delay (current_min_rtt_) of the current
  // burst of packets relative to the minimum delay during the session.
  // Note: we only look at the first few(8) packets in each burst, since we
  // only want to compare the lowest RTT of the burst relative to previous
  // bursts.
  rtt_sample_count_++;
  if (rtt_sample_count_ <= kHybridStartMinSamples) {
    if (current_min_rtt_.IsZero() || current_min_rtt_ > latest_rtt) {
      current_min_rtt_ = latest_rtt;
    }
  }
  // We only need to check this once per round.
  if (rtt_sample_count_ == kHybridStartMinSamples) {
    // Divide min_rtt by 16 to get a rtt increase threshold for exiting.
    int min_rtt_increase_threshold_us = min_rtt.ToMicroseconds() >>
        kHybridStartDelayFactorExp;
    // Ensure the rtt threshold is never less than 2ms or more than 16ms.
    min_rtt_increase_threshold_us = min(min_rtt_increase_threshold_us,
                                        kHybridStartDelayMaxThresholdUs);
    QuicTime::Delta min_rtt_increase_threshold =
        QuicTime::Delta::FromMicroseconds(max(min_rtt_increase_threshold_us,
                                              kHybridStartDelayMinThresholdUs));

    if (current_min_rtt_ > min_rtt.Add(min_rtt_increase_threshold)) {
      hystart_found_= DELAY;
    }
  }
  // Exit from slow start if the cwnd is greater than 16 and an ack train or
  // increasing delay are found.
  return congestion_window >= kHybridStartLowWindow &&
      hystart_found_ != NOT_FOUND;
}

}  // namespace net
