text: // Copyright (c) 2013 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.
  
  // A send algorithm that adds pacing on top of an another send algorithm.
  // It uses the underlying sender's pacing rate to schedule packets.
  // It also takes into consideration the expected granularity of the underlying
  // alarm to ensure that alarms are not set too aggressively, and err towards
  // sending packets too early instead of too late.
  
  #ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_PACING_SENDER_H_
  #define QUICHE_QUIC_CORE_CONGESTION_CONTROL_PACING_SENDER_H_
  
  #include <cstdint>
  #include <map>
  #include <memory>
  
  #include "net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.h"
  #include "net/third_party/quiche/src/quic/core/quic_bandwidth.h"
  #include "net/third_party/quiche/src/quic/core/quic_config.h"
  #include "net/third_party/quiche/src/quic/core/quic_packets.h"
  #include "net/third_party/quiche/src/quic/core/quic_time.h"
  #include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
  
  namespace quic {
  
  namespace test {
  class QuicSentPacketManagerPeer;
  }  // namespace test
  
  class QUIC_EXPORT_PRIVATE PacingSender {
   public:
    PacingSender();
    PacingSender(const PacingSender&) = delete;
    PacingSender& operator=(const PacingSender&) = delete;
    ~PacingSender();
  
    // Sets the underlying sender. Does not take ownership of |sender|. |sender|
    // must not be null. This must be called before any of the
    // SendAlgorithmInterface wrapper methods are called.
    void set_sender(SendAlgorithmInterface* sender);
  
    void set_max_pacing_rate(QuicBandwidth max_pacing_rate) {
      max_pacing_rate_ = max_pacing_rate;
    }
  
    void set_alarm_granularity(QuicTime::Delta alarm_granularity) {
      alarm_granularity_ = alarm_granularity;
    }
  
    QuicBandwidth max_pacing_rate() const { return max_pacing_rate_; }
  
    void OnCongestionEvent(bool rtt_updated,
                           QuicByteCount bytes_in_flight,
                           QuicTime event_time,
                           const AckedPacketVector& acked_packets,
                           const LostPacketVector& lost_packets);
  
    void OnPacketSent(QuicTime sent_time,
                      QuicByteCount bytes_in_flight,
                      QuicPacketNumber packet_number,
                      QuicByteCount bytes,
                      HasRetransmittableData has_retransmittable_data);
  
    // Called when application throttles the sending, so that pacing sender stops
    // making up for lost time.
    void OnApplicationLimited();
  
    // Set burst_tokens_ and initial_burst_size_.
    void SetBurstTokens(uint32_t burst_tokens);
  
    QuicTime::Delta TimeUntilSend(QuicTime now,
                                  QuicByteCount bytes_in_flight) const;
  
    QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const;
  
    QuicTime ideal_next_packet_send_time() const {
      return ideal_next_packet_send_time_;
    }
  
   private:
    friend class test::QuicSentPacketManagerPeer;
  
    // Underlying sender. Not owned.
    SendAlgorithmInterface* sender_;
    // If not QuicBandidth::Zero, the maximum rate the PacingSender will use.
    QuicBandwidth max_pacing_rate_;
  
    // Number of unpaced packets to be sent before packets are delayed.
    uint32_t burst_tokens_;
    QuicTime ideal_next_packet_send_time_;  // When can the next packet be sent.
    uint32_t initial_burst_size_;
  
    // Number of unpaced packets to be sent before packets are delayed. This token
    // is consumed after burst_tokens_ ran out.
    uint32_t lumpy_tokens_;
  
    // If the next send time is within alarm_granularity_, send immediately.
    // TODO(fayang): Remove alarm_granularity_ when deprecating
    // quic_offload_pacing_to_usps2 flag.
    QuicTime::Delta alarm_granularity_;
  
    // Indicates whether pacing throttles the sending. If true, make up for lost
    // time.
    bool pacing_limited_;
  };
  
  }  // namespace quic
  
  #endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_PACING_SENDER_H_
  