1 // Copyright 2014 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 // A convenience class to store rtt samples and calculate smoothed rtt. 6 7 #ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_RTT_STATS_H_ 8 #define QUICHE_QUIC_CORE_CONGESTION_CONTROL_RTT_STATS_H_ 9 10 #include <algorithm> 11 #include <cstdint> 12 13 #include "net/third_party/quiche/src/quic/core/quic_packets.h" 14 #include "net/third_party/quiche/src/quic/core/quic_time.h" 15 #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" 16 #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" 17 18 namespace quic { 19 20 namespace test { 21 class RttStatsPeer; 22 } // namespace test 23 24 class QUIC_EXPORT_PRIVATE RttStats { 25 public: 26 // Calculates running standard-deviation using Welford's algorithm: 27 // https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance# 28 // Welford's_Online_algorithm. 29 struct QUIC_EXPORT_PRIVATE StandardDeviationCaculator { StandardDeviationCaculatorStandardDeviationCaculator30 StandardDeviationCaculator() {} 31 32 // Called when a new RTT sample is available. 33 void OnNewRttSample(QuicTime::Delta rtt_sample, 34 QuicTime::Delta smoothed_rtt); 35 // Calculates the standard deviation. 36 QuicTime::Delta CalculateStandardDeviation() const; 37 38 bool has_valid_standard_deviation = false; 39 40 private: 41 double m2 = 0; 42 }; 43 44 RttStats(); 45 RttStats(const RttStats&) = delete; 46 RttStats& operator=(const RttStats&) = delete; 47 48 // Updates the RTT from an incoming ack which is received |send_delta| after 49 // the packet is sent and the peer reports the ack being delayed |ack_delay|. 50 void UpdateRtt(QuicTime::Delta send_delta, 51 QuicTime::Delta ack_delay, 52 QuicTime now); 53 54 // Causes the smoothed_rtt to be increased to the latest_rtt if the latest_rtt 55 // is larger. The mean deviation is increased to the most recent deviation if 56 // it's larger. 57 void ExpireSmoothedMetrics(); 58 59 // Called when connection migrates and rtt measurement needs to be reset. 60 void OnConnectionMigration(); 61 62 // Returns the EWMA smoothed RTT for the connection. 63 // May return Zero if no valid updates have occurred. smoothed_rtt()64 QuicTime::Delta smoothed_rtt() const { return smoothed_rtt_; } 65 66 // Returns the EWMA smoothed RTT prior to the most recent RTT sample. previous_srtt()67 QuicTime::Delta previous_srtt() const { return previous_srtt_; } 68 initial_rtt()69 QuicTime::Delta initial_rtt() const { return initial_rtt_; } 70 SmoothedOrInitialRtt()71 QuicTime::Delta SmoothedOrInitialRtt() const { 72 return smoothed_rtt_.IsZero() ? initial_rtt_ : smoothed_rtt_; 73 } 74 75 // Sets an initial RTT to be used for SmoothedRtt before any RTT updates. set_initial_rtt(QuicTime::Delta initial_rtt)76 void set_initial_rtt(QuicTime::Delta initial_rtt) { 77 if (initial_rtt.ToMicroseconds() <= 0) { 78 QUIC_BUG << "Attempt to set initial rtt to <= 0."; 79 return; 80 } 81 initial_rtt_ = initial_rtt; 82 } 83 84 // The most recent rtt measurement. 85 // May return Zero if no valid updates have occurred. latest_rtt()86 QuicTime::Delta latest_rtt() const { return latest_rtt_; } 87 88 // Returns the min_rtt for the entire connection. 89 // May return Zero if no valid updates have occurred. min_rtt()90 QuicTime::Delta min_rtt() const { return min_rtt_; } 91 mean_deviation()92 QuicTime::Delta mean_deviation() const { return mean_deviation_; } 93 94 // Returns standard deviation if there is a valid one. Otherwise, returns 95 // mean_deviation_. 96 QuicTime::Delta GetStandardOrMeanDeviation() const; 97 last_update_time()98 QuicTime last_update_time() const { return last_update_time_; } 99 ignore_max_ack_delay()100 bool ignore_max_ack_delay() const { return ignore_max_ack_delay_; } 101 set_ignore_max_ack_delay(bool ignore_max_ack_delay)102 void set_ignore_max_ack_delay(bool ignore_max_ack_delay) { 103 ignore_max_ack_delay_ = ignore_max_ack_delay; 104 } 105 set_initial_max_ack_delay(QuicTime::Delta initial_max_ack_delay)106 void set_initial_max_ack_delay(QuicTime::Delta initial_max_ack_delay) { 107 max_ack_delay_ = std::max(max_ack_delay_, initial_max_ack_delay); 108 } 109 EnableStandardDeviationCalculation()110 void EnableStandardDeviationCalculation() { 111 calculate_standard_deviation_ = true; 112 } 113 114 private: 115 friend class test::RttStatsPeer; 116 117 QuicTime::Delta latest_rtt_; 118 QuicTime::Delta min_rtt_; 119 QuicTime::Delta smoothed_rtt_; 120 QuicTime::Delta previous_srtt_; 121 // Mean RTT deviation during this session. 122 // Approximation of standard deviation, the error is roughly 1.25 times 123 // larger than the standard deviation, for a normally distributed signal. 124 QuicTime::Delta mean_deviation_; 125 // Standard deviation calculator. Only used calculate_standard_deviation_ is 126 // true. 127 StandardDeviationCaculator standard_deviation_calculator_; 128 bool calculate_standard_deviation_; 129 QuicTime::Delta initial_rtt_; 130 // The maximum ack delay observed over the connection after excluding ack 131 // delays that were too large to be included in an RTT measurement. 132 // TODO(ianswett): Remove when deprecating quic_sent_packet_manager_cleanup. 133 QuicTime::Delta max_ack_delay_; 134 QuicTime last_update_time_; 135 // Whether to ignore the peer's max ack delay. 136 bool ignore_max_ack_delay_; 137 }; 138 139 } // namespace quic 140 141 #endif // QUICHE_QUIC_CORE_CONGESTION_CONTROL_RTT_STATS_H_ 142