• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "quiche/quic/core/congestion_control/bandwidth_sampler.h"
6 
7 #include <algorithm>
8 
9 #include "quiche/quic/core/quic_types.h"
10 #include "quiche/quic/platform/api/quic_bug_tracker.h"
11 #include "quiche/quic/platform/api/quic_flag_utils.h"
12 #include "quiche/quic/platform/api/quic_flags.h"
13 #include "quiche/quic/platform/api/quic_logging.h"
14 
15 namespace quic {
16 
operator <<(std::ostream & os,const SendTimeState & s)17 std::ostream& operator<<(std::ostream& os, const SendTimeState& s) {
18   os << "{valid:" << s.is_valid << ", app_limited:" << s.is_app_limited
19      << ", total_sent:" << s.total_bytes_sent
20      << ", total_acked:" << s.total_bytes_acked
21      << ", total_lost:" << s.total_bytes_lost
22      << ", inflight:" << s.bytes_in_flight << "}";
23   return os;
24 }
25 
Update(QuicBandwidth bandwidth_estimate,bool is_new_max_bandwidth,QuicRoundTripCount round_trip_count,QuicPacketNumber last_sent_packet_number,QuicPacketNumber last_acked_packet_number,QuicTime ack_time,QuicByteCount bytes_acked)26 QuicByteCount MaxAckHeightTracker::Update(
27     QuicBandwidth bandwidth_estimate, bool is_new_max_bandwidth,
28     QuicRoundTripCount round_trip_count,
29     QuicPacketNumber last_sent_packet_number,
30     QuicPacketNumber last_acked_packet_number, QuicTime ack_time,
31     QuicByteCount bytes_acked) {
32   bool force_new_epoch = false;
33 
34   if (reduce_extra_acked_on_bandwidth_increase_ && is_new_max_bandwidth) {
35     // Save and clear existing entries.
36     ExtraAckedEvent best = max_ack_height_filter_.GetBest();
37     ExtraAckedEvent second_best = max_ack_height_filter_.GetSecondBest();
38     ExtraAckedEvent third_best = max_ack_height_filter_.GetThirdBest();
39     max_ack_height_filter_.Clear();
40 
41     // Reinsert the heights into the filter after recalculating.
42     QuicByteCount expected_bytes_acked = bandwidth_estimate * best.time_delta;
43     if (expected_bytes_acked < best.bytes_acked) {
44       best.extra_acked = best.bytes_acked - expected_bytes_acked;
45       max_ack_height_filter_.Update(best, best.round);
46     }
47     expected_bytes_acked = bandwidth_estimate * second_best.time_delta;
48     if (expected_bytes_acked < second_best.bytes_acked) {
49       QUICHE_DCHECK_LE(best.round, second_best.round);
50       second_best.extra_acked = second_best.bytes_acked - expected_bytes_acked;
51       max_ack_height_filter_.Update(second_best, second_best.round);
52     }
53     expected_bytes_acked = bandwidth_estimate * third_best.time_delta;
54     if (expected_bytes_acked < third_best.bytes_acked) {
55       QUICHE_DCHECK_LE(second_best.round, third_best.round);
56       third_best.extra_acked = third_best.bytes_acked - expected_bytes_acked;
57       max_ack_height_filter_.Update(third_best, third_best.round);
58     }
59   }
60 
61   // If any packet sent after the start of the epoch has been acked, start a new
62   // epoch.
63   if (start_new_aggregation_epoch_after_full_round_ &&
64       last_sent_packet_number_before_epoch_.IsInitialized() &&
65       last_acked_packet_number.IsInitialized() &&
66       last_acked_packet_number > last_sent_packet_number_before_epoch_) {
67     QUIC_DVLOG(3) << "Force starting a new aggregation epoch. "
68                      "last_sent_packet_number_before_epoch_:"
69                   << last_sent_packet_number_before_epoch_
70                   << ", last_acked_packet_number:" << last_acked_packet_number;
71     if (reduce_extra_acked_on_bandwidth_increase_) {
72       QUIC_BUG(quic_bwsampler_46)
73           << "A full round of aggregation should never "
74           << "pass with startup_include_extra_acked(B204) enabled.";
75     }
76     force_new_epoch = true;
77   }
78   if (aggregation_epoch_start_time_ == QuicTime::Zero() || force_new_epoch) {
79     aggregation_epoch_bytes_ = bytes_acked;
80     aggregation_epoch_start_time_ = ack_time;
81     last_sent_packet_number_before_epoch_ = last_sent_packet_number;
82     ++num_ack_aggregation_epochs_;
83     return 0;
84   }
85 
86   // Compute how many bytes are expected to be delivered, assuming max bandwidth
87   // is correct.
88   QuicTime::Delta aggregation_delta = ack_time - aggregation_epoch_start_time_;
89   QuicByteCount expected_bytes_acked = bandwidth_estimate * aggregation_delta;
90   // Reset the current aggregation epoch as soon as the ack arrival rate is less
91   // than or equal to the max bandwidth.
92   if (aggregation_epoch_bytes_ <=
93       ack_aggregation_bandwidth_threshold_ * expected_bytes_acked) {
94     QUIC_DVLOG(3) << "Starting a new aggregation epoch because "
95                      "aggregation_epoch_bytes_ "
96                   << aggregation_epoch_bytes_
97                   << " is smaller than expected. "
98                      "ack_aggregation_bandwidth_threshold_:"
99                   << ack_aggregation_bandwidth_threshold_
100                   << ", expected_bytes_acked:" << expected_bytes_acked
101                   << ", bandwidth_estimate:" << bandwidth_estimate
102                   << ", aggregation_duration:" << aggregation_delta
103                   << ", new_aggregation_epoch:" << ack_time
104                   << ", new_aggregation_bytes_acked:" << bytes_acked;
105     // Reset to start measuring a new aggregation epoch.
106     aggregation_epoch_bytes_ = bytes_acked;
107     aggregation_epoch_start_time_ = ack_time;
108     last_sent_packet_number_before_epoch_ = last_sent_packet_number;
109     ++num_ack_aggregation_epochs_;
110     return 0;
111   }
112 
113   aggregation_epoch_bytes_ += bytes_acked;
114 
115   // Compute how many extra bytes were delivered vs max bandwidth.
116   QuicByteCount extra_bytes_acked =
117       aggregation_epoch_bytes_ - expected_bytes_acked;
118   QUIC_DVLOG(3) << "Updating MaxAckHeight. ack_time:" << ack_time
119                 << ", last sent packet:" << last_sent_packet_number
120                 << ", bandwidth_estimate:" << bandwidth_estimate
121                 << ", bytes_acked:" << bytes_acked
122                 << ", expected_bytes_acked:" << expected_bytes_acked
123                 << ", aggregation_epoch_bytes_:" << aggregation_epoch_bytes_
124                 << ", extra_bytes_acked:" << extra_bytes_acked;
125   ExtraAckedEvent new_event;
126   new_event.extra_acked = extra_bytes_acked;
127   new_event.bytes_acked = aggregation_epoch_bytes_;
128   new_event.time_delta = aggregation_delta;
129   max_ack_height_filter_.Update(new_event, round_trip_count);
130   return extra_bytes_acked;
131 }
132 
BandwidthSampler(const QuicUnackedPacketMap * unacked_packet_map,QuicRoundTripCount max_height_tracker_window_length)133 BandwidthSampler::BandwidthSampler(
134     const QuicUnackedPacketMap* unacked_packet_map,
135     QuicRoundTripCount max_height_tracker_window_length)
136     : total_bytes_sent_(0),
137       total_bytes_acked_(0),
138       total_bytes_lost_(0),
139       total_bytes_neutered_(0),
140       total_bytes_sent_at_last_acked_packet_(0),
141       last_acked_packet_sent_time_(QuicTime::Zero()),
142       last_acked_packet_ack_time_(QuicTime::Zero()),
143       is_app_limited_(true),
144       connection_state_map_(),
145       max_tracked_packets_(GetQuicFlag(quic_max_tracked_packet_count)),
146       unacked_packet_map_(unacked_packet_map),
147       max_ack_height_tracker_(max_height_tracker_window_length),
148       total_bytes_acked_after_last_ack_event_(0),
149       overestimate_avoidance_(false),
150       limit_max_ack_height_tracker_by_send_rate_(false) {}
151 
BandwidthSampler(const BandwidthSampler & other)152 BandwidthSampler::BandwidthSampler(const BandwidthSampler& other)
153     : total_bytes_sent_(other.total_bytes_sent_),
154       total_bytes_acked_(other.total_bytes_acked_),
155       total_bytes_lost_(other.total_bytes_lost_),
156       total_bytes_neutered_(other.total_bytes_neutered_),
157       total_bytes_sent_at_last_acked_packet_(
158           other.total_bytes_sent_at_last_acked_packet_),
159       last_acked_packet_sent_time_(other.last_acked_packet_sent_time_),
160       last_acked_packet_ack_time_(other.last_acked_packet_ack_time_),
161       last_sent_packet_(other.last_sent_packet_),
162       last_acked_packet_(other.last_acked_packet_),
163       is_app_limited_(other.is_app_limited_),
164       end_of_app_limited_phase_(other.end_of_app_limited_phase_),
165       connection_state_map_(other.connection_state_map_),
166       recent_ack_points_(other.recent_ack_points_),
167       a0_candidates_(other.a0_candidates_),
168       max_tracked_packets_(other.max_tracked_packets_),
169       unacked_packet_map_(other.unacked_packet_map_),
170       max_ack_height_tracker_(other.max_ack_height_tracker_),
171       total_bytes_acked_after_last_ack_event_(
172           other.total_bytes_acked_after_last_ack_event_),
173       overestimate_avoidance_(other.overestimate_avoidance_),
174       limit_max_ack_height_tracker_by_send_rate_(
175           other.limit_max_ack_height_tracker_by_send_rate_) {}
176 
EnableOverestimateAvoidance()177 void BandwidthSampler::EnableOverestimateAvoidance() {
178   if (overestimate_avoidance_) {
179     return;
180   }
181 
182   overestimate_avoidance_ = true;
183   // TODO(wub): Change the default value of
184   // --quic_ack_aggregation_bandwidth_threshold to 2.0.
185   max_ack_height_tracker_.SetAckAggregationBandwidthThreshold(2.0);
186 }
187 
~BandwidthSampler()188 BandwidthSampler::~BandwidthSampler() {}
189 
OnPacketSent(QuicTime sent_time,QuicPacketNumber packet_number,QuicByteCount bytes,QuicByteCount bytes_in_flight,HasRetransmittableData has_retransmittable_data)190 void BandwidthSampler::OnPacketSent(
191     QuicTime sent_time, QuicPacketNumber packet_number, QuicByteCount bytes,
192     QuicByteCount bytes_in_flight,
193     HasRetransmittableData has_retransmittable_data) {
194   last_sent_packet_ = packet_number;
195 
196   if (has_retransmittable_data != HAS_RETRANSMITTABLE_DATA) {
197     return;
198   }
199 
200   total_bytes_sent_ += bytes;
201 
202   // If there are no packets in flight, the time at which the new transmission
203   // opens can be treated as the A_0 point for the purpose of bandwidth
204   // sampling. This underestimates bandwidth to some extent, and produces some
205   // artificially low samples for most packets in flight, but it provides with
206   // samples at important points where we would not have them otherwise, most
207   // importantly at the beginning of the connection.
208   if (bytes_in_flight == 0) {
209     last_acked_packet_ack_time_ = sent_time;
210     if (overestimate_avoidance_) {
211       recent_ack_points_.Clear();
212       recent_ack_points_.Update(sent_time, total_bytes_acked_);
213       a0_candidates_.clear();
214       a0_candidates_.push_back(recent_ack_points_.MostRecentPoint());
215     }
216     total_bytes_sent_at_last_acked_packet_ = total_bytes_sent_;
217 
218     // In this situation ack compression is not a concern, set send rate to
219     // effectively infinite.
220     last_acked_packet_sent_time_ = sent_time;
221   }
222 
223   if (!connection_state_map_.IsEmpty() &&
224       packet_number >
225           connection_state_map_.last_packet() + max_tracked_packets_) {
226     if (unacked_packet_map_ != nullptr && !unacked_packet_map_->empty()) {
227       QuicPacketNumber maybe_least_unacked =
228           unacked_packet_map_->GetLeastUnacked();
229       QUIC_BUG(quic_bug_10437_1)
230           << "BandwidthSampler in-flight packet map has exceeded maximum "
231              "number of tracked packets("
232           << max_tracked_packets_
233           << ").  First tracked: " << connection_state_map_.first_packet()
234           << "; last tracked: " << connection_state_map_.last_packet()
235           << "; entry_slots_used: " << connection_state_map_.entry_slots_used()
236           << "; number_of_present_entries: "
237           << connection_state_map_.number_of_present_entries()
238           << "; packet number: " << packet_number
239           << "; unacked_map: " << unacked_packet_map_->DebugString()
240           << "; total_bytes_sent: " << total_bytes_sent_
241           << "; total_bytes_acked: " << total_bytes_acked_
242           << "; total_bytes_lost: " << total_bytes_lost_
243           << "; total_bytes_neutered: " << total_bytes_neutered_
244           << "; last_acked_packet_sent_time: " << last_acked_packet_sent_time_
245           << "; total_bytes_sent_at_last_acked_packet: "
246           << total_bytes_sent_at_last_acked_packet_
247           << "; least_unacked_packet_info: "
248           << (unacked_packet_map_->IsUnacked(maybe_least_unacked)
249                   ? unacked_packet_map_
250                         ->GetTransmissionInfo(maybe_least_unacked)
251                         .DebugString()
252                   : "n/a");
253     } else {
254       QUIC_BUG(quic_bug_10437_2)
255           << "BandwidthSampler in-flight packet map has exceeded maximum "
256              "number of tracked packets.";
257     }
258   }
259 
260   bool success = connection_state_map_.Emplace(packet_number, sent_time, bytes,
261                                                bytes_in_flight + bytes, *this);
262   QUIC_BUG_IF(quic_bug_10437_3, !success)
263       << "BandwidthSampler failed to insert the packet "
264          "into the map, most likely because it's already "
265          "in it.";
266 }
267 
OnPacketNeutered(QuicPacketNumber packet_number)268 void BandwidthSampler::OnPacketNeutered(QuicPacketNumber packet_number) {
269   connection_state_map_.Remove(
270       packet_number, [&](const ConnectionStateOnSentPacket& sent_packet) {
271         QUIC_CODE_COUNT(quic_bandwidth_sampler_packet_neutered);
272         total_bytes_neutered_ += sent_packet.size;
273       });
274 }
275 
276 BandwidthSamplerInterface::CongestionEventSample
OnCongestionEvent(QuicTime ack_time,const AckedPacketVector & acked_packets,const LostPacketVector & lost_packets,QuicBandwidth max_bandwidth,QuicBandwidth est_bandwidth_upper_bound,QuicRoundTripCount round_trip_count)277 BandwidthSampler::OnCongestionEvent(QuicTime ack_time,
278                                     const AckedPacketVector& acked_packets,
279                                     const LostPacketVector& lost_packets,
280                                     QuicBandwidth max_bandwidth,
281                                     QuicBandwidth est_bandwidth_upper_bound,
282                                     QuicRoundTripCount round_trip_count) {
283   CongestionEventSample event_sample;
284 
285   SendTimeState last_lost_packet_send_state;
286 
287   for (const LostPacket& packet : lost_packets) {
288     SendTimeState send_state =
289         OnPacketLost(packet.packet_number, packet.bytes_lost);
290     if (send_state.is_valid) {
291       last_lost_packet_send_state = send_state;
292     }
293   }
294 
295   if (acked_packets.empty()) {
296     // Only populate send state for a loss-only event.
297     event_sample.last_packet_send_state = last_lost_packet_send_state;
298     return event_sample;
299   }
300 
301   SendTimeState last_acked_packet_send_state;
302   QuicBandwidth max_send_rate = QuicBandwidth::Zero();
303   for (const auto& packet : acked_packets) {
304     BandwidthSample sample =
305         OnPacketAcknowledged(ack_time, packet.packet_number);
306     if (!sample.state_at_send.is_valid) {
307       continue;
308     }
309 
310     last_acked_packet_send_state = sample.state_at_send;
311 
312     if (!sample.rtt.IsZero()) {
313       event_sample.sample_rtt = std::min(event_sample.sample_rtt, sample.rtt);
314     }
315     if (sample.bandwidth > event_sample.sample_max_bandwidth) {
316       event_sample.sample_max_bandwidth = sample.bandwidth;
317       event_sample.sample_is_app_limited = sample.state_at_send.is_app_limited;
318     }
319     if (!sample.send_rate.IsInfinite()) {
320       max_send_rate = std::max(max_send_rate, sample.send_rate);
321     }
322     const QuicByteCount inflight_sample =
323         total_bytes_acked() - last_acked_packet_send_state.total_bytes_acked;
324     if (inflight_sample > event_sample.sample_max_inflight) {
325       event_sample.sample_max_inflight = inflight_sample;
326     }
327   }
328 
329   if (!last_lost_packet_send_state.is_valid) {
330     event_sample.last_packet_send_state = last_acked_packet_send_state;
331   } else if (!last_acked_packet_send_state.is_valid) {
332     event_sample.last_packet_send_state = last_lost_packet_send_state;
333   } else {
334     // If two packets are inflight and an alarm is armed to lose a packet and it
335     // wakes up late, then the first of two in flight packets could have been
336     // acknowledged before the wakeup, which re-evaluates loss detection, and
337     // could declare the later of the two lost.
338     event_sample.last_packet_send_state =
339         lost_packets.back().packet_number > acked_packets.back().packet_number
340             ? last_lost_packet_send_state
341             : last_acked_packet_send_state;
342   }
343 
344   bool is_new_max_bandwidth = event_sample.sample_max_bandwidth > max_bandwidth;
345   max_bandwidth = std::max(max_bandwidth, event_sample.sample_max_bandwidth);
346   if (limit_max_ack_height_tracker_by_send_rate_) {
347     max_bandwidth = std::max(max_bandwidth, max_send_rate);
348   }
349   // TODO(ianswett): Why is the min being passed in here?
350   event_sample.extra_acked =
351       OnAckEventEnd(std::min(est_bandwidth_upper_bound, max_bandwidth),
352                     is_new_max_bandwidth, round_trip_count);
353 
354   return event_sample;
355 }
356 
OnAckEventEnd(QuicBandwidth bandwidth_estimate,bool is_new_max_bandwidth,QuicRoundTripCount round_trip_count)357 QuicByteCount BandwidthSampler::OnAckEventEnd(
358     QuicBandwidth bandwidth_estimate, bool is_new_max_bandwidth,
359     QuicRoundTripCount round_trip_count) {
360   const QuicByteCount newly_acked_bytes =
361       total_bytes_acked_ - total_bytes_acked_after_last_ack_event_;
362 
363   if (newly_acked_bytes == 0) {
364     return 0;
365   }
366   total_bytes_acked_after_last_ack_event_ = total_bytes_acked_;
367   QuicByteCount extra_acked = max_ack_height_tracker_.Update(
368       bandwidth_estimate, is_new_max_bandwidth, round_trip_count,
369       last_sent_packet_, last_acked_packet_, last_acked_packet_ack_time_,
370       newly_acked_bytes);
371   // If |extra_acked| is zero, i.e. this ack event marks the start of a new ack
372   // aggregation epoch, save LessRecentPoint, which is the last ack point of the
373   // previous epoch, as a A0 candidate.
374   if (overestimate_avoidance_ && extra_acked == 0) {
375     a0_candidates_.push_back(recent_ack_points_.LessRecentPoint());
376     QUIC_DVLOG(1) << "New a0_candidate:" << a0_candidates_.back();
377   }
378   return extra_acked;
379 }
380 
OnPacketAcknowledged(QuicTime ack_time,QuicPacketNumber packet_number)381 BandwidthSample BandwidthSampler::OnPacketAcknowledged(
382     QuicTime ack_time, QuicPacketNumber packet_number) {
383   last_acked_packet_ = packet_number;
384   ConnectionStateOnSentPacket* sent_packet_pointer =
385       connection_state_map_.GetEntry(packet_number);
386   if (sent_packet_pointer == nullptr) {
387     // See the TODO below.
388     return BandwidthSample();
389   }
390   BandwidthSample sample =
391       OnPacketAcknowledgedInner(ack_time, packet_number, *sent_packet_pointer);
392   return sample;
393 }
394 
OnPacketAcknowledgedInner(QuicTime ack_time,QuicPacketNumber packet_number,const ConnectionStateOnSentPacket & sent_packet)395 BandwidthSample BandwidthSampler::OnPacketAcknowledgedInner(
396     QuicTime ack_time, QuicPacketNumber packet_number,
397     const ConnectionStateOnSentPacket& sent_packet) {
398   total_bytes_acked_ += sent_packet.size;
399   total_bytes_sent_at_last_acked_packet_ =
400       sent_packet.send_time_state.total_bytes_sent;
401   last_acked_packet_sent_time_ = sent_packet.sent_time;
402   last_acked_packet_ack_time_ = ack_time;
403   if (overestimate_avoidance_) {
404     recent_ack_points_.Update(ack_time, total_bytes_acked_);
405   }
406 
407   if (is_app_limited_) {
408     // Exit app-limited phase in two cases:
409     // (1) end_of_app_limited_phase_ is not initialized, i.e., so far all
410     // packets are sent while there are buffered packets or pending data.
411     // (2) The current acked packet is after the sent packet marked as the end
412     // of the app limit phase.
413     if (!end_of_app_limited_phase_.IsInitialized() ||
414         packet_number > end_of_app_limited_phase_) {
415       is_app_limited_ = false;
416     }
417   }
418 
419   // There might have been no packets acknowledged at the moment when the
420   // current packet was sent. In that case, there is no bandwidth sample to
421   // make.
422   if (sent_packet.last_acked_packet_sent_time == QuicTime::Zero()) {
423     QUIC_BUG(quic_bug_10437_4)
424         << "sent_packet.last_acked_packet_sent_time is zero";
425     return BandwidthSample();
426   }
427 
428   // Infinite rate indicates that the sampler is supposed to discard the
429   // current send rate sample and use only the ack rate.
430   QuicBandwidth send_rate = QuicBandwidth::Infinite();
431   if (sent_packet.sent_time > sent_packet.last_acked_packet_sent_time) {
432     send_rate = QuicBandwidth::FromBytesAndTimeDelta(
433         sent_packet.send_time_state.total_bytes_sent -
434             sent_packet.total_bytes_sent_at_last_acked_packet,
435         sent_packet.sent_time - sent_packet.last_acked_packet_sent_time);
436   }
437 
438   AckPoint a0;
439   if (overestimate_avoidance_ &&
440       ChooseA0Point(sent_packet.send_time_state.total_bytes_acked, &a0)) {
441     QUIC_DVLOG(2) << "Using a0 point: " << a0;
442   } else {
443     a0.ack_time = sent_packet.last_acked_packet_ack_time,
444     a0.total_bytes_acked = sent_packet.send_time_state.total_bytes_acked;
445   }
446 
447   // During the slope calculation, ensure that ack time of the current packet is
448   // always larger than the time of the previous packet, otherwise division by
449   // zero or integer underflow can occur.
450   if (ack_time <= a0.ack_time) {
451     // TODO(wub): Compare this code count before and after fixing clock jitter
452     // issue.
453     if (a0.ack_time == sent_packet.sent_time) {
454       // This is the 1st packet after quiescense.
455       QUIC_CODE_COUNT_N(quic_prev_ack_time_larger_than_current_ack_time, 1, 2);
456     } else {
457       QUIC_CODE_COUNT_N(quic_prev_ack_time_larger_than_current_ack_time, 2, 2);
458     }
459     QUIC_LOG_EVERY_N_SEC(ERROR, 60)
460         << "Time of the previously acked packet:"
461         << a0.ack_time.ToDebuggingValue()
462         << " is larger than the ack time of the current packet:"
463         << ack_time.ToDebuggingValue()
464         << ". acked packet number:" << packet_number
465         << ", total_bytes_acked_:" << total_bytes_acked_
466         << ", overestimate_avoidance_:" << overestimate_avoidance_
467         << ", sent_packet:" << sent_packet;
468     return BandwidthSample();
469   }
470   QuicBandwidth ack_rate = QuicBandwidth::FromBytesAndTimeDelta(
471       total_bytes_acked_ - a0.total_bytes_acked, ack_time - a0.ack_time);
472 
473   BandwidthSample sample;
474   sample.bandwidth = std::min(send_rate, ack_rate);
475   // Note: this sample does not account for delayed acknowledgement time.  This
476   // means that the RTT measurements here can be artificially high, especially
477   // on low bandwidth connections.
478   sample.rtt = ack_time - sent_packet.sent_time;
479   sample.send_rate = send_rate;
480   SentPacketToSendTimeState(sent_packet, &sample.state_at_send);
481 
482   if (sample.bandwidth.IsZero()) {
483     QUIC_LOG_EVERY_N_SEC(ERROR, 60)
484         << "ack_rate: " << ack_rate << ", send_rate: " << send_rate
485         << ". acked packet number:" << packet_number
486         << ", overestimate_avoidance_:" << overestimate_avoidance_ << "a1:{"
487         << total_bytes_acked_ << "@" << ack_time << "}, a0:{"
488         << a0.total_bytes_acked << "@" << a0.ack_time
489         << "}, sent_packet:" << sent_packet;
490   }
491   return sample;
492 }
493 
ChooseA0Point(QuicByteCount total_bytes_acked,AckPoint * a0)494 bool BandwidthSampler::ChooseA0Point(QuicByteCount total_bytes_acked,
495                                      AckPoint* a0) {
496   if (a0_candidates_.empty()) {
497     QUIC_BUG(quic_bug_10437_5)
498         << "No A0 point candicates. total_bytes_acked:" << total_bytes_acked;
499     return false;
500   }
501 
502   if (a0_candidates_.size() == 1) {
503     *a0 = a0_candidates_.front();
504     return true;
505   }
506 
507   for (size_t i = 1; i < a0_candidates_.size(); ++i) {
508     if (a0_candidates_[i].total_bytes_acked > total_bytes_acked) {
509       *a0 = a0_candidates_[i - 1];
510       if (i > 1) {
511         a0_candidates_.pop_front_n(i - 1);
512       }
513       return true;
514     }
515   }
516 
517   // All candidates' total_bytes_acked is <= |total_bytes_acked|.
518   *a0 = a0_candidates_.back();
519   a0_candidates_.pop_front_n(a0_candidates_.size() - 1);
520   return true;
521 }
522 
OnPacketLost(QuicPacketNumber packet_number,QuicPacketLength bytes_lost)523 SendTimeState BandwidthSampler::OnPacketLost(QuicPacketNumber packet_number,
524                                              QuicPacketLength bytes_lost) {
525   // TODO(vasilvv): see the comment for the case of missing packets in
526   // BandwidthSampler::OnPacketAcknowledged on why this does not raise a
527   // QUIC_BUG when removal fails.
528   SendTimeState send_time_state;
529 
530   total_bytes_lost_ += bytes_lost;
531   ConnectionStateOnSentPacket* sent_packet_pointer =
532       connection_state_map_.GetEntry(packet_number);
533   if (sent_packet_pointer != nullptr) {
534     SentPacketToSendTimeState(*sent_packet_pointer, &send_time_state);
535   }
536 
537   return send_time_state;
538 }
539 
SentPacketToSendTimeState(const ConnectionStateOnSentPacket & sent_packet,SendTimeState * send_time_state) const540 void BandwidthSampler::SentPacketToSendTimeState(
541     const ConnectionStateOnSentPacket& sent_packet,
542     SendTimeState* send_time_state) const {
543   *send_time_state = sent_packet.send_time_state;
544   send_time_state->is_valid = true;
545 }
546 
OnAppLimited()547 void BandwidthSampler::OnAppLimited() {
548   is_app_limited_ = true;
549   end_of_app_limited_phase_ = last_sent_packet_;
550 }
551 
RemoveObsoletePackets(QuicPacketNumber least_unacked)552 void BandwidthSampler::RemoveObsoletePackets(QuicPacketNumber least_unacked) {
553   // A packet can become obsolete when it is removed from QuicUnackedPacketMap's
554   // view of inflight before it is acked or marked as lost. For example, when
555   // QuicSentPacketManager::RetransmitCryptoPackets retransmits a crypto packet,
556   // the packet is removed from QuicUnackedPacketMap's inflight, but is not
557   // marked as acked or lost in the BandwidthSampler.
558   connection_state_map_.RemoveUpTo(least_unacked);
559 }
560 
total_bytes_sent() const561 QuicByteCount BandwidthSampler::total_bytes_sent() const {
562   return total_bytes_sent_;
563 }
564 
total_bytes_acked() const565 QuicByteCount BandwidthSampler::total_bytes_acked() const {
566   return total_bytes_acked_;
567 }
568 
total_bytes_lost() const569 QuicByteCount BandwidthSampler::total_bytes_lost() const {
570   return total_bytes_lost_;
571 }
572 
total_bytes_neutered() const573 QuicByteCount BandwidthSampler::total_bytes_neutered() const {
574   return total_bytes_neutered_;
575 }
576 
is_app_limited() const577 bool BandwidthSampler::is_app_limited() const { return is_app_limited_; }
578 
end_of_app_limited_phase() const579 QuicPacketNumber BandwidthSampler::end_of_app_limited_phase() const {
580   return end_of_app_limited_phase_;
581 }
582 
583 }  // namespace quic
584