1 // Copyright 2016 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 #ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_BANDWIDTH_SAMPLER_H_
6 #define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BANDWIDTH_SAMPLER_H_
7 
8 #include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
9 #include "quiche/quic/core/congestion_control/windowed_filter.h"
10 #include "quiche/quic/core/packet_number_indexed_queue.h"
11 #include "quiche/quic/core/quic_bandwidth.h"
12 #include "quiche/quic/core/quic_packet_number.h"
13 #include "quiche/quic/core/quic_packets.h"
14 #include "quiche/quic/core/quic_time.h"
15 #include "quiche/quic/core/quic_types.h"
16 #include "quiche/quic/core/quic_unacked_packet_map.h"
17 #include "quiche/quic/platform/api/quic_export.h"
18 #include "quiche/quic/platform/api/quic_flags.h"
19 #include "quiche/common/quiche_circular_deque.h"
20 
21 namespace quic {
22 
23 namespace test {
24 class BandwidthSamplerPeer;
25 }  // namespace test
26 
27 // A subset of BandwidthSampler::ConnectionStateOnSentPacket which is returned
28 // to the caller when the packet is acked or lost.
29 struct QUICHE_EXPORT SendTimeState {
SendTimeStateSendTimeState30   SendTimeState()
31       : is_valid(false),
32         is_app_limited(false),
33         total_bytes_sent(0),
34         total_bytes_acked(0),
35         total_bytes_lost(0),
36         bytes_in_flight(0) {}
37 
SendTimeStateSendTimeState38   SendTimeState(bool is_app_limited, QuicByteCount total_bytes_sent,
39                 QuicByteCount total_bytes_acked, QuicByteCount total_bytes_lost,
40                 QuicByteCount bytes_in_flight)
41       : is_valid(true),
42         is_app_limited(is_app_limited),
43         total_bytes_sent(total_bytes_sent),
44         total_bytes_acked(total_bytes_acked),
45         total_bytes_lost(total_bytes_lost),
46         bytes_in_flight(bytes_in_flight) {}
47 
48   SendTimeState(const SendTimeState& other) = default;
49   SendTimeState& operator=(const SendTimeState& other) = default;
50 
51   friend QUICHE_EXPORT std::ostream& operator<<(std::ostream& os,
52                                                 const SendTimeState& s);
53 
54   // Whether other states in this object is valid.
55   bool is_valid;
56 
57   // Whether the sender is app limited at the time the packet was sent.
58   // App limited bandwidth sample might be artificially low because the sender
59   // did not have enough data to send in order to saturate the link.
60   bool is_app_limited;
61 
62   // Total number of sent bytes at the time the packet was sent.
63   // Includes the packet itself.
64   QuicByteCount total_bytes_sent;
65 
66   // Total number of acked bytes at the time the packet was sent.
67   QuicByteCount total_bytes_acked;
68 
69   // Total number of lost bytes at the time the packet was sent.
70   QuicByteCount total_bytes_lost;
71 
72   // Total number of inflight bytes at the time the packet was sent.
73   // Includes the packet itself.
74   // It should be equal to |total_bytes_sent| minus the sum of
75   // |total_bytes_acked|, |total_bytes_lost| and total neutered bytes.
76   QuicByteCount bytes_in_flight;
77 };
78 
79 struct QUICHE_EXPORT ExtraAckedEvent {
80   // The excess bytes acknowlwedged in the time delta for this event.
81   QuicByteCount extra_acked = 0;
82 
83   // The bytes acknowledged and time delta from the event.
84   QuicByteCount bytes_acked = 0;
85   QuicTime::Delta time_delta = QuicTime::Delta::Zero();
86   // The round trip of the event.
87   QuicRoundTripCount round = 0;
88 
89   bool operator>=(const ExtraAckedEvent& other) const {
90     return extra_acked >= other.extra_acked;
91   }
92   bool operator==(const ExtraAckedEvent& other) const {
93     return extra_acked == other.extra_acked;
94   }
95 };
96 
97 struct QUICHE_EXPORT BandwidthSample {
98   // The bandwidth at that particular sample. Zero if no valid bandwidth sample
99   // is available.
100   QuicBandwidth bandwidth = QuicBandwidth::Zero();
101 
102   // The RTT measurement at this particular sample.  Zero if no RTT sample is
103   // available.  Does not correct for delayed ack time.
104   QuicTime::Delta rtt = QuicTime::Delta::Zero();
105 
106   // |send_rate| is computed from the current packet being acked('P') and an
107   // earlier packet that is acked before P was sent.
108   QuicBandwidth send_rate = QuicBandwidth::Infinite();
109 
110   // States captured when the packet was sent.
111   SendTimeState state_at_send;
112 };
113 
114 // MaxAckHeightTracker is part of the BandwidthSampler. It is called after every
115 // ack event to keep track the degree of ack aggregation(a.k.a "ack height").
116 class QUICHE_EXPORT MaxAckHeightTracker {
117  public:
MaxAckHeightTracker(QuicRoundTripCount initial_filter_window)118   explicit MaxAckHeightTracker(QuicRoundTripCount initial_filter_window)
119       : max_ack_height_filter_(initial_filter_window, ExtraAckedEvent(), 0) {}
120 
Get()121   QuicByteCount Get() const {
122     return max_ack_height_filter_.GetBest().extra_acked;
123   }
124 
125   QuicByteCount Update(QuicBandwidth bandwidth_estimate,
126                        bool is_new_max_bandwidth,
127                        QuicRoundTripCount round_trip_count,
128                        QuicPacketNumber last_sent_packet_number,
129                        QuicPacketNumber last_acked_packet_number,
130                        QuicTime ack_time, QuicByteCount bytes_acked);
131 
SetFilterWindowLength(QuicRoundTripCount length)132   void SetFilterWindowLength(QuicRoundTripCount length) {
133     max_ack_height_filter_.SetWindowLength(length);
134   }
135 
Reset(QuicByteCount new_height,QuicRoundTripCount new_time)136   void Reset(QuicByteCount new_height, QuicRoundTripCount new_time) {
137     ExtraAckedEvent new_event;
138     new_event.extra_acked = new_height;
139     new_event.round = new_time;
140     max_ack_height_filter_.Reset(new_event, new_time);
141   }
142 
SetAckAggregationBandwidthThreshold(double threshold)143   void SetAckAggregationBandwidthThreshold(double threshold) {
144     ack_aggregation_bandwidth_threshold_ = threshold;
145   }
146 
SetStartNewAggregationEpochAfterFullRound(bool value)147   void SetStartNewAggregationEpochAfterFullRound(bool value) {
148     start_new_aggregation_epoch_after_full_round_ = value;
149   }
150 
SetReduceExtraAckedOnBandwidthIncrease(bool value)151   void SetReduceExtraAckedOnBandwidthIncrease(bool value) {
152     reduce_extra_acked_on_bandwidth_increase_ = value;
153   }
154 
ack_aggregation_bandwidth_threshold()155   double ack_aggregation_bandwidth_threshold() const {
156     return ack_aggregation_bandwidth_threshold_;
157   }
158 
num_ack_aggregation_epochs()159   uint64_t num_ack_aggregation_epochs() const {
160     return num_ack_aggregation_epochs_;
161   }
162 
163  private:
164   // Tracks the maximum number of bytes acked faster than the estimated
165   // bandwidth.
166   using MaxAckHeightFilter =
167       WindowedFilter<ExtraAckedEvent, MaxFilter<ExtraAckedEvent>,
168                      QuicRoundTripCount, QuicRoundTripCount>;
169   MaxAckHeightFilter max_ack_height_filter_;
170 
171   // The time this aggregation started and the number of bytes acked during it.
172   QuicTime aggregation_epoch_start_time_ = QuicTime::Zero();
173   QuicByteCount aggregation_epoch_bytes_ = 0;
174   // The last sent packet number before the current aggregation epoch started.
175   QuicPacketNumber last_sent_packet_number_before_epoch_;
176   // The number of ack aggregation epochs ever started, including the ongoing
177   // one. Stats only.
178   uint64_t num_ack_aggregation_epochs_ = 0;
179   double ack_aggregation_bandwidth_threshold_ =
180       GetQuicFlag(quic_ack_aggregation_bandwidth_threshold);
181   bool start_new_aggregation_epoch_after_full_round_ = false;
182   bool reduce_extra_acked_on_bandwidth_increase_ = false;
183 };
184 
185 // An interface common to any class that can provide bandwidth samples from the
186 // information per individual acknowledged packet.
187 class QUICHE_EXPORT BandwidthSamplerInterface {
188  public:
~BandwidthSamplerInterface()189   virtual ~BandwidthSamplerInterface() {}
190 
191   // Inputs the sent packet information into the sampler. Assumes that all
192   // packets are sent in order. The information about the packet will not be
193   // released from the sampler until it the packet is either acknowledged or
194   // declared lost.
195   virtual void OnPacketSent(
196       QuicTime sent_time, QuicPacketNumber packet_number, QuicByteCount bytes,
197       QuicByteCount bytes_in_flight,
198       HasRetransmittableData has_retransmittable_data) = 0;
199 
200   virtual void OnPacketNeutered(QuicPacketNumber packet_number) = 0;
201 
202   struct QUICHE_EXPORT CongestionEventSample {
203     // The maximum bandwidth sample from all acked packets.
204     // QuicBandwidth::Zero() if no samples are available.
205     QuicBandwidth sample_max_bandwidth = QuicBandwidth::Zero();
206     // Whether |sample_max_bandwidth| is from a app-limited sample.
207     bool sample_is_app_limited = false;
208     // The minimum rtt sample from all acked packets.
209     // QuicTime::Delta::Infinite() if no samples are available.
210     QuicTime::Delta sample_rtt = QuicTime::Delta::Infinite();
211     // For each packet p in acked packets, this is the max value of INFLIGHT(p),
212     // where INFLIGHT(p) is the number of bytes acked while p is inflight.
213     QuicByteCount sample_max_inflight = 0;
214     // The send state of the largest packet in acked_packets, unless it is
215     // empty. If acked_packets is empty, it's the send state of the largest
216     // packet in lost_packets.
217     SendTimeState last_packet_send_state;
218     // The number of extra bytes acked from this ack event, compared to what is
219     // expected from the flow's bandwidth. Larger value means more ack
220     // aggregation.
221     QuicByteCount extra_acked = 0;
222   };
223   // Notifies the sampler that at |ack_time|, all packets in |acked_packets|
224   // have been acked, and all packets in |lost_packets| have been lost.
225   // See the comments in CongestionEventSample for the return value.
226   // |max_bandwidth| is the windowed maximum observed bandwidth.
227   // |est_bandwidth_upper_bound| is an upper bound of estimated bandwidth used
228   // to calculate extra_acked.
229   virtual CongestionEventSample OnCongestionEvent(
230       QuicTime ack_time, const AckedPacketVector& acked_packets,
231       const LostPacketVector& lost_packets, QuicBandwidth max_bandwidth,
232       QuicBandwidth est_bandwidth_upper_bound,
233       QuicRoundTripCount round_trip_count) = 0;
234 
235   // Informs the sampler that the connection is currently app-limited, causing
236   // the sampler to enter the app-limited phase.  The phase will expire by
237   // itself.
238   virtual void OnAppLimited() = 0;
239 
240   // Remove all the packets lower than the specified packet number.
241   virtual void RemoveObsoletePackets(QuicPacketNumber least_unacked) = 0;
242 
243   // Total number of bytes sent/acked/lost/neutered in the connection.
244   virtual QuicByteCount total_bytes_sent() const = 0;
245   virtual QuicByteCount total_bytes_acked() const = 0;
246   virtual QuicByteCount total_bytes_lost() const = 0;
247   virtual QuicByteCount total_bytes_neutered() const = 0;
248 
249   // Application-limited information exported for debugging.
250   virtual bool is_app_limited() const = 0;
251 
252   virtual QuicPacketNumber end_of_app_limited_phase() const = 0;
253 };
254 
255 // BandwidthSampler keeps track of sent and acknowledged packets and outputs a
256 // bandwidth sample for every packet acknowledged. The samples are taken for
257 // individual packets, and are not filtered; the consumer has to filter the
258 // bandwidth samples itself. In certain cases, the sampler will locally severely
259 // underestimate the bandwidth, hence a maximum filter with a size of at least
260 // one RTT is recommended.
261 //
262 // This class bases its samples on the slope of two curves: the number of bytes
263 // sent over time, and the number of bytes acknowledged as received over time.
264 // It produces a sample of both slopes for every packet that gets acknowledged,
265 // based on a slope between two points on each of the corresponding curves. Note
266 // that due to the packet loss, the number of bytes on each curve might get
267 // further and further away from each other, meaning that it is not feasible to
268 // compare byte values coming from different curves with each other.
269 //
270 // The obvious points for measuring slope sample are the ones corresponding to
271 // the packet that was just acknowledged. Let us denote them as S_1 (point at
272 // which the current packet was sent) and A_1 (point at which the current packet
273 // was acknowledged). However, taking a slope requires two points on each line,
274 // so estimating bandwidth requires picking a packet in the past with respect to
275 // which the slope is measured.
276 //
277 // For that purpose, BandwidthSampler always keeps track of the most recently
278 // acknowledged packet, and records it together with every outgoing packet.
279 // When a packet gets acknowledged (A_1), it has not only information about when
280 // it itself was sent (S_1), but also the information about a previously
281 // acknowledged packet before it was sent (S_0 and A_0).
282 //
283 // Based on that data, send and ack rate are estimated as:
284 //   send_rate = (bytes(S_1) - bytes(S_0)) / (time(S_1) - time(S_0))
285 //   ack_rate = (bytes(A_1) - bytes(A_0)) / (time(A_1) - time(A_0))
286 //
287 // Here, the ack rate is intuitively the rate we want to treat as bandwidth.
288 // However, in certain cases (e.g. ack compression) the ack rate at a point may
289 // end up higher than the rate at which the data was originally sent, which is
290 // not indicative of the real bandwidth. Hence, we use the send rate as an upper
291 // bound, and the sample value is
292 //   rate_sample = min(send_rate, ack_rate)
293 //
294 // An important edge case handled by the sampler is tracking the app-limited
295 // samples. There are multiple meaning of "app-limited" used interchangeably,
296 // hence it is important to understand and to be able to distinguish between
297 // them.
298 //
299 // Meaning 1: connection state. The connection is said to be app-limited when
300 // there is no outstanding data to send. This means that certain bandwidth
301 // samples in the future would not be an accurate indication of the link
302 // capacity, and it is important to inform consumer about that. Whenever
303 // connection becomes app-limited, the sampler is notified via OnAppLimited()
304 // method.
305 //
306 // Meaning 2: a phase in the bandwidth sampler. As soon as the bandwidth
307 // sampler becomes notified about the connection being app-limited, it enters
308 // app-limited phase. In that phase, all *sent* packets are marked as
309 // app-limited. Note that the connection itself does not have to be
310 // app-limited during the app-limited phase, and in fact it will not be
311 // (otherwise how would it send packets?). The boolean flag below indicates
312 // whether the sampler is in that phase.
313 //
314 // Meaning 3: a flag on the sent packet and on the sample. If a sent packet is
315 // sent during the app-limited phase, the resulting sample related to the
316 // packet will be marked as app-limited.
317 //
318 // With the terminology issue out of the way, let us consider the question of
319 // what kind of situation it addresses.
320 //
321 // Consider a scenario where we first send packets 1 to 20 at a regular
322 // bandwidth, and then immediately run out of data. After a few seconds, we send
323 // packets 21 to 60, and only receive ack for 21 between sending packets 40 and
324 // 41. In this case, when we sample bandwidth for packets 21 to 40, the S_0/A_0
325 // we use to compute the slope is going to be packet 20, a few seconds apart
326 // from the current packet, hence the resulting estimate would be extremely low
327 // and not indicative of anything. Only at packet 41 the S_0/A_0 will become 21,
328 // meaning that the bandwidth sample would exclude the quiescence.
329 //
330 // Based on the analysis of that scenario, we implement the following rule: once
331 // OnAppLimited() is called, all sent packets will produce app-limited samples
332 // up until an ack for a packet that was sent after OnAppLimited() was called.
333 // Note that while the scenario above is not the only scenario when the
334 // connection is app-limited, the approach works in other cases too.
335 class QUICHE_EXPORT BandwidthSampler : public BandwidthSamplerInterface {
336  public:
337   BandwidthSampler(const QuicUnackedPacketMap* unacked_packet_map,
338                    QuicRoundTripCount max_height_tracker_window_length);
339 
340   // Copy states from |other|. This is useful when changing send algorithms in
341   // the middle of a connection.
342   BandwidthSampler(const BandwidthSampler& other);
343   ~BandwidthSampler() override;
344 
345   void OnPacketSent(QuicTime sent_time, QuicPacketNumber packet_number,
346                     QuicByteCount bytes, QuicByteCount bytes_in_flight,
347                     HasRetransmittableData has_retransmittable_data) override;
348   void OnPacketNeutered(QuicPacketNumber packet_number) override;
349 
350   CongestionEventSample OnCongestionEvent(
351       QuicTime ack_time, const AckedPacketVector& acked_packets,
352       const LostPacketVector& lost_packets, QuicBandwidth max_bandwidth,
353       QuicBandwidth est_bandwidth_upper_bound,
354       QuicRoundTripCount round_trip_count) override;
355   QuicByteCount OnAckEventEnd(QuicBandwidth bandwidth_estimate,
356                               bool is_new_max_bandwidth,
357                               QuicRoundTripCount round_trip_count);
358 
359   void OnAppLimited() override;
360 
361   void RemoveObsoletePackets(QuicPacketNumber least_unacked) override;
362 
363   QuicByteCount total_bytes_sent() const override;
364   QuicByteCount total_bytes_acked() const override;
365   QuicByteCount total_bytes_lost() const override;
366   QuicByteCount total_bytes_neutered() const override;
367 
368   bool is_app_limited() const override;
369 
370   QuicPacketNumber end_of_app_limited_phase() const override;
371 
max_ack_height()372   QuicByteCount max_ack_height() const { return max_ack_height_tracker_.Get(); }
373 
num_ack_aggregation_epochs()374   uint64_t num_ack_aggregation_epochs() const {
375     return max_ack_height_tracker_.num_ack_aggregation_epochs();
376   }
377 
SetMaxAckHeightTrackerWindowLength(QuicRoundTripCount length)378   void SetMaxAckHeightTrackerWindowLength(QuicRoundTripCount length) {
379     max_ack_height_tracker_.SetFilterWindowLength(length);
380   }
381 
ResetMaxAckHeightTracker(QuicByteCount new_height,QuicRoundTripCount new_time)382   void ResetMaxAckHeightTracker(QuicByteCount new_height,
383                                 QuicRoundTripCount new_time) {
384     max_ack_height_tracker_.Reset(new_height, new_time);
385   }
386 
SetStartNewAggregationEpochAfterFullRound(bool value)387   void SetStartNewAggregationEpochAfterFullRound(bool value) {
388     max_ack_height_tracker_.SetStartNewAggregationEpochAfterFullRound(value);
389   }
390 
SetLimitMaxAckHeightTrackerBySendRate(bool value)391   void SetLimitMaxAckHeightTrackerBySendRate(bool value) {
392     limit_max_ack_height_tracker_by_send_rate_ = value;
393   }
394 
SetReduceExtraAckedOnBandwidthIncrease(bool value)395   void SetReduceExtraAckedOnBandwidthIncrease(bool value) {
396     max_ack_height_tracker_.SetReduceExtraAckedOnBandwidthIncrease(value);
397   }
398 
399   // AckPoint represents a point on the ack line.
400   struct QUICHE_EXPORT AckPoint {
401     QuicTime ack_time = QuicTime::Zero();
402     QuicByteCount total_bytes_acked = 0;
403 
404     friend QUICHE_EXPORT std::ostream& operator<<(std::ostream& os,
405                                                   const AckPoint& ack_point) {
406       return os << ack_point.ack_time << ":" << ack_point.total_bytes_acked;
407     }
408   };
409 
410   // RecentAckPoints maintains the most recent 2 ack points at distinct times.
411   class QUICHE_EXPORT RecentAckPoints {
412    public:
Update(QuicTime ack_time,QuicByteCount total_bytes_acked)413     void Update(QuicTime ack_time, QuicByteCount total_bytes_acked) {
414       QUICHE_DCHECK_GE(total_bytes_acked, ack_points_[1].total_bytes_acked);
415 
416       if (ack_time < ack_points_[1].ack_time) {
417         // This can only happen when time goes backwards, we use the smaller
418         // timestamp for the most recent ack point in that case.
419         // TODO(wub): Add a QUIC_BUG if ack time stops going backwards.
420         ack_points_[1].ack_time = ack_time;
421       } else if (ack_time > ack_points_[1].ack_time) {
422         ack_points_[0] = ack_points_[1];
423         ack_points_[1].ack_time = ack_time;
424       }
425 
426       ack_points_[1].total_bytes_acked = total_bytes_acked;
427     }
428 
Clear()429     void Clear() { ack_points_[0] = ack_points_[1] = AckPoint(); }
430 
MostRecentPoint()431     const AckPoint& MostRecentPoint() const { return ack_points_[1]; }
432 
LessRecentPoint()433     const AckPoint& LessRecentPoint() const {
434       if (ack_points_[0].total_bytes_acked != 0) {
435         return ack_points_[0];
436       }
437 
438       return ack_points_[1];
439     }
440 
441    private:
442     AckPoint ack_points_[2];
443   };
444 
445   void EnableOverestimateAvoidance();
IsOverestimateAvoidanceEnabled()446   bool IsOverestimateAvoidanceEnabled() const {
447     return overestimate_avoidance_;
448   }
449 
450  private:
451   friend class test::BandwidthSamplerPeer;
452 
453   // ConnectionStateOnSentPacket represents the information about a sent packet
454   // and the state of the connection at the moment the packet was sent,
455   // specifically the information about the most recently acknowledged packet at
456   // that moment.
457   class QUICHE_EXPORT ConnectionStateOnSentPacket {
458    public:
459     // Time at which the packet is sent.
sent_time()460     QuicTime sent_time() const { return sent_time_; }
461 
462     // Size of the packet.
size()463     QuicByteCount size() const { return size_; }
464 
465     // The value of |total_bytes_sent_at_last_acked_packet_| at the time the
466     // packet was sent.
total_bytes_sent_at_last_acked_packet()467     QuicByteCount total_bytes_sent_at_last_acked_packet() const {
468       return total_bytes_sent_at_last_acked_packet_;
469     }
470 
471     // The value of |last_acked_packet_sent_time_| at the time the packet was
472     // sent.
last_acked_packet_sent_time()473     QuicTime last_acked_packet_sent_time() const {
474       return last_acked_packet_sent_time_;
475     }
476 
477     // The value of |last_acked_packet_ack_time_| at the time the packet was
478     // sent.
last_acked_packet_ack_time()479     QuicTime last_acked_packet_ack_time() const {
480       return last_acked_packet_ack_time_;
481     }
482 
483     // Send time states that are returned to the congestion controller when the
484     // packet is acked or lost.
send_time_state()485     const SendTimeState& send_time_state() const { return send_time_state_; }
486 
487     // Snapshot constructor. Records the current state of the bandwidth
488     // sampler.
489     // |bytes_in_flight| is the bytes in flight right after the packet is sent.
ConnectionStateOnSentPacket(QuicTime sent_time,QuicByteCount size,QuicByteCount bytes_in_flight,const BandwidthSampler & sampler)490     ConnectionStateOnSentPacket(QuicTime sent_time, QuicByteCount size,
491                                 QuicByteCount bytes_in_flight,
492                                 const BandwidthSampler& sampler)
493         : sent_time_(sent_time),
494           size_(size),
495           total_bytes_sent_at_last_acked_packet_(
496               sampler.total_bytes_sent_at_last_acked_packet_),
497           last_acked_packet_sent_time_(sampler.last_acked_packet_sent_time_),
498           last_acked_packet_ack_time_(sampler.last_acked_packet_ack_time_),
499           send_time_state_(sampler.is_app_limited_, sampler.total_bytes_sent_,
500                            sampler.total_bytes_acked_,
501                            sampler.total_bytes_lost_, bytes_in_flight) {}
502 
503     // Default constructor.  Required to put this structure into
504     // PacketNumberIndexedQueue.
ConnectionStateOnSentPacket()505     ConnectionStateOnSentPacket()
506         : sent_time_(QuicTime::Zero()),
507           size_(0),
508           total_bytes_sent_at_last_acked_packet_(0),
509           last_acked_packet_sent_time_(QuicTime::Zero()),
510           last_acked_packet_ack_time_(QuicTime::Zero()) {}
511 
512     friend QUICHE_EXPORT std::ostream& operator<<(
513         std::ostream& os, const ConnectionStateOnSentPacket& p) {
514       os << "{sent_time:" << p.sent_time() << ", size:" << p.size()
515          << ", total_bytes_sent_at_last_acked_packet:"
516          << p.total_bytes_sent_at_last_acked_packet()
517          << ", last_acked_packet_sent_time:" << p.last_acked_packet_sent_time()
518          << ", last_acked_packet_ack_time:" << p.last_acked_packet_ack_time()
519          << ", send_time_state:" << p.send_time_state() << "}";
520       return os;
521     }
522 
523    private:
524     QuicTime sent_time_;
525     QuicByteCount size_;
526     QuicByteCount total_bytes_sent_at_last_acked_packet_;
527     QuicTime last_acked_packet_sent_time_;
528     QuicTime last_acked_packet_ack_time_;
529     SendTimeState send_time_state_;
530   };
531 
532   BandwidthSample OnPacketAcknowledged(QuicTime ack_time,
533                                        QuicPacketNumber packet_number);
534 
535   SendTimeState OnPacketLost(QuicPacketNumber packet_number,
536                              QuicPacketLength bytes_lost);
537 
538   // Copy a subset of the (private) ConnectionStateOnSentPacket to the (public)
539   // SendTimeState. Always set send_time_state->is_valid to true.
540   void SentPacketToSendTimeState(const ConnectionStateOnSentPacket& sent_packet,
541                                  SendTimeState* send_time_state) const;
542 
543   // Choose the best a0 from |a0_candidates_| to calculate the ack rate.
544   // |total_bytes_acked| is the total bytes acked when the packet being acked is
545   // sent. The best a0 is chosen as follows:
546   // - If there's only one candidate, use it.
547   // - If there are multiple candidates, let a[n] be the nth candidate, and
548   //   a[n-1].total_bytes_acked <= |total_bytes_acked| < a[n].total_bytes_acked,
549   //   use a[n-1].
550   // - If all candidates's total_bytes_acked is > |total_bytes_acked|, use a[0].
551   //   This may happen when acks are received out of order, and ack[n] caused
552   //   some candidates of ack[n-x] to be removed.
553   // - If all candidates's total_bytes_acked is <= |total_bytes_acked|, use
554   //   a[a.size()-1].
555   bool ChooseA0Point(QuicByteCount total_bytes_acked, AckPoint* a0);
556 
557   // The total number of congestion controlled bytes sent during the connection.
558   QuicByteCount total_bytes_sent_;
559 
560   // The total number of congestion controlled bytes which were acknowledged.
561   QuicByteCount total_bytes_acked_;
562 
563   // The total number of congestion controlled bytes which were lost.
564   QuicByteCount total_bytes_lost_;
565 
566   // The total number of congestion controlled bytes which have been neutered.
567   QuicByteCount total_bytes_neutered_;
568 
569   // The value of |total_bytes_sent_| at the time the last acknowledged packet
570   // was sent. Valid only when |last_acked_packet_sent_time_| is valid.
571   QuicByteCount total_bytes_sent_at_last_acked_packet_;
572 
573   // The time at which the last acknowledged packet was sent. Set to
574   // QuicTime::Zero() if no valid timestamp is available.
575   QuicTime last_acked_packet_sent_time_;
576 
577   // The time at which the most recent packet was acknowledged.
578   QuicTime last_acked_packet_ack_time_;
579 
580   // The most recently sent packet.
581   QuicPacketNumber last_sent_packet_;
582 
583   // The most recently acked packet.
584   QuicPacketNumber last_acked_packet_;
585 
586   // Indicates whether the bandwidth sampler is currently in an app-limited
587   // phase.
588   bool is_app_limited_;
589 
590   // The packet that will be acknowledged after this one will cause the sampler
591   // to exit the app-limited phase.
592   QuicPacketNumber end_of_app_limited_phase_;
593 
594   // Record of the connection state at the point where each packet in flight was
595   // sent, indexed by the packet number.
596   PacketNumberIndexedQueue<ConnectionStateOnSentPacket> connection_state_map_;
597 
598   RecentAckPoints recent_ack_points_;
599   quiche::QuicheCircularDeque<AckPoint> a0_candidates_;
600 
601   // Maximum number of tracked packets.
602   const QuicPacketCount max_tracked_packets_;
603 
604   // The main unacked packet map.  Used for outputting extra debugging details.
605   // May be null.
606   // TODO(vasilvv): remove this once it's no longer useful for debugging.
607   const QuicUnackedPacketMap* unacked_packet_map_;
608 
609   // Handles the actual bandwidth calculations, whereas the outer method handles
610   // retrieving and removing |sent_packet|.
611   BandwidthSample OnPacketAcknowledgedInner(
612       QuicTime ack_time, QuicPacketNumber packet_number,
613       const ConnectionStateOnSentPacket& sent_packet);
614 
615   MaxAckHeightTracker max_ack_height_tracker_;
616   QuicByteCount total_bytes_acked_after_last_ack_event_;
617 
618   // True if connection option 'BSAO' is set.
619   bool overestimate_avoidance_;
620 
621   // True if connection option 'BBRB' is set.
622   bool limit_max_ack_height_tracker_by_send_rate_;
623 };
624 
625 }  // namespace quic
626 
627 #endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BANDWIDTH_SAMPLER_H_
628