1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/quic/congestion_control/paced_sender.h"
6
7#include "net/quic/quic_protocol.h"
8
9namespace net {
10
11// To prevent too aggressive pacing we allow the following packet burst size.
12const int64 kMinPacketBurstSize = 2;
13// Max estimated time between calls to TimeUntilSend and
14// AvailableCongestionWindow.
15const int64 kMaxSchedulingDelayUs = 2000;
16
17PacedSender::PacedSender(QuicBandwidth estimate)
18    : leaky_bucket_(estimate),
19      pace_(estimate) {
20}
21
22void PacedSender::UpdateBandwidthEstimate(QuicTime now,
23                                          QuicBandwidth estimate) {
24  leaky_bucket_.SetDrainingRate(now, estimate);
25  pace_ = estimate;
26}
27
28void PacedSender::SentPacket(QuicTime now, QuicByteCount bytes) {
29  leaky_bucket_.Add(now, bytes);
30}
31
32QuicTime::Delta PacedSender::TimeUntilSend(QuicTime now,
33                                           QuicTime::Delta time_until_send) {
34  if (time_until_send.ToMicroseconds() >= kMaxSchedulingDelayUs) {
35    return time_until_send;
36  }
37  // Pace the data.
38  QuicByteCount pacing_window = pace_.ToBytesPerPeriod(
39      QuicTime::Delta::FromMicroseconds(kMaxSchedulingDelayUs));
40  QuicByteCount min_window_size = kMinPacketBurstSize *  kMaxPacketSize;
41  pacing_window = std::max(pacing_window, min_window_size);
42
43  if (pacing_window > leaky_bucket_.BytesPending(now)) {
44    // We have not filled our pacing window yet.
45    return time_until_send;
46  }
47  return leaky_bucket_.TimeRemaining(now);
48}
49
50}  // namespace net
51