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 // QuicBandwidth represents a bandwidth, stored in bits per second resolution. 6 7 #ifndef QUICHE_QUIC_CORE_QUIC_BANDWIDTH_H_ 8 #define QUICHE_QUIC_CORE_QUIC_BANDWIDTH_H_ 9 10 #include <cmath> 11 #include <cstdint> 12 #include <limits> 13 #include <ostream> 14 #include <string> 15 16 #include "quiche/quic/core/quic_constants.h" 17 #include "quiche/quic/core/quic_time.h" 18 #include "quiche/quic/core/quic_types.h" 19 #include "quiche/quic/platform/api/quic_export.h" 20 #include "quiche/quic/platform/api/quic_flag_utils.h" 21 22 namespace quic { 23 24 class QUIC_EXPORT_PRIVATE QuicBandwidth { 25 public: 26 // Creates a new QuicBandwidth with an internal value of 0. Zero()27 static constexpr QuicBandwidth Zero() { return QuicBandwidth(0); } 28 29 // Creates a new QuicBandwidth with an internal value of INT64_MAX. Infinite()30 static constexpr QuicBandwidth Infinite() { 31 return QuicBandwidth(std::numeric_limits<int64_t>::max()); 32 } 33 34 // Create a new QuicBandwidth holding the bits per second. FromBitsPerSecond(int64_t bits_per_second)35 static constexpr QuicBandwidth FromBitsPerSecond(int64_t bits_per_second) { 36 return QuicBandwidth(bits_per_second); 37 } 38 39 // Create a new QuicBandwidth holding the kilo bits per second. FromKBitsPerSecond(int64_t k_bits_per_second)40 static constexpr QuicBandwidth FromKBitsPerSecond(int64_t k_bits_per_second) { 41 return QuicBandwidth(k_bits_per_second * 1000); 42 } 43 44 // Create a new QuicBandwidth holding the bytes per second. FromBytesPerSecond(int64_t bytes_per_second)45 static constexpr QuicBandwidth FromBytesPerSecond(int64_t bytes_per_second) { 46 return QuicBandwidth(bytes_per_second * 8); 47 } 48 49 // Create a new QuicBandwidth holding the kilo bytes per second. FromKBytesPerSecond(int64_t k_bytes_per_second)50 static constexpr QuicBandwidth FromKBytesPerSecond( 51 int64_t k_bytes_per_second) { 52 return QuicBandwidth(k_bytes_per_second * 8000); 53 } 54 55 // Create a new QuicBandwidth based on the bytes per the elapsed delta. FromBytesAndTimeDelta(QuicByteCount bytes,QuicTime::Delta delta)56 static QuicBandwidth FromBytesAndTimeDelta(QuicByteCount bytes, 57 QuicTime::Delta delta) { 58 if (bytes == 0) { 59 return QuicBandwidth(0); 60 } 61 62 // 1 bit is 1000000 micro bits. 63 int64_t num_micro_bits = 8 * bytes * kNumMicrosPerSecond; 64 if (num_micro_bits < delta.ToMicroseconds()) { 65 return QuicBandwidth(1); 66 } 67 68 return QuicBandwidth(num_micro_bits / delta.ToMicroseconds()); 69 } 70 ToBitsPerSecond()71 int64_t ToBitsPerSecond() const { return bits_per_second_; } 72 ToKBitsPerSecond()73 int64_t ToKBitsPerSecond() const { return bits_per_second_ / 1000; } 74 ToBytesPerSecond()75 int64_t ToBytesPerSecond() const { return bits_per_second_ / 8; } 76 ToKBytesPerSecond()77 int64_t ToKBytesPerSecond() const { return bits_per_second_ / 8000; } 78 ToBytesPerPeriod(QuicTime::Delta time_period)79 constexpr QuicByteCount ToBytesPerPeriod(QuicTime::Delta time_period) const { 80 return bits_per_second_ * time_period.ToMicroseconds() / 8 / 81 kNumMicrosPerSecond; 82 } 83 ToKBytesPerPeriod(QuicTime::Delta time_period)84 int64_t ToKBytesPerPeriod(QuicTime::Delta time_period) const { 85 return bits_per_second_ * time_period.ToMicroseconds() / 8000 / 86 kNumMicrosPerSecond; 87 } 88 IsZero()89 bool IsZero() const { return bits_per_second_ == 0; } IsInfinite()90 bool IsInfinite() const { 91 return bits_per_second_ == Infinite().ToBitsPerSecond(); 92 } 93 TransferTime(QuicByteCount bytes)94 constexpr QuicTime::Delta TransferTime(QuicByteCount bytes) const { 95 if (bits_per_second_ == 0) { 96 return QuicTime::Delta::Zero(); 97 } 98 return QuicTime::Delta::FromMicroseconds(bytes * 8 * kNumMicrosPerSecond / 99 bits_per_second_); 100 } 101 102 std::string ToDebuggingValue() const; 103 104 private: QuicBandwidth(int64_t bits_per_second)105 explicit constexpr QuicBandwidth(int64_t bits_per_second) 106 : bits_per_second_(bits_per_second >= 0 ? bits_per_second : 0) {} 107 108 int64_t bits_per_second_; 109 110 friend constexpr QuicBandwidth operator+(QuicBandwidth lhs, 111 QuicBandwidth rhs); 112 friend constexpr QuicBandwidth operator-(QuicBandwidth lhs, 113 QuicBandwidth rhs); 114 friend QuicBandwidth operator*(QuicBandwidth lhs, float rhs); 115 }; 116 117 // Non-member relational operators for QuicBandwidth. 118 inline bool operator==(QuicBandwidth lhs, QuicBandwidth rhs) { 119 return lhs.ToBitsPerSecond() == rhs.ToBitsPerSecond(); 120 } 121 inline bool operator!=(QuicBandwidth lhs, QuicBandwidth rhs) { 122 return !(lhs == rhs); 123 } 124 inline bool operator<(QuicBandwidth lhs, QuicBandwidth rhs) { 125 return lhs.ToBitsPerSecond() < rhs.ToBitsPerSecond(); 126 } 127 inline bool operator>(QuicBandwidth lhs, QuicBandwidth rhs) { 128 return rhs < lhs; 129 } 130 inline bool operator<=(QuicBandwidth lhs, QuicBandwidth rhs) { 131 return !(rhs < lhs); 132 } 133 inline bool operator>=(QuicBandwidth lhs, QuicBandwidth rhs) { 134 return !(lhs < rhs); 135 } 136 137 // Non-member arithmetic operators for QuicBandwidth. 138 inline constexpr QuicBandwidth operator+(QuicBandwidth lhs, QuicBandwidth rhs) { 139 return QuicBandwidth(lhs.bits_per_second_ + rhs.bits_per_second_); 140 } 141 inline constexpr QuicBandwidth operator-(QuicBandwidth lhs, QuicBandwidth rhs) { 142 return QuicBandwidth(lhs.bits_per_second_ - rhs.bits_per_second_); 143 } 144 inline QuicBandwidth operator*(QuicBandwidth lhs, float rhs) { 145 return QuicBandwidth( 146 static_cast<int64_t>(std::llround(lhs.bits_per_second_ * rhs))); 147 } 148 inline QuicBandwidth operator*(float lhs, QuicBandwidth rhs) { 149 return rhs * lhs; 150 } 151 inline constexpr QuicByteCount operator*(QuicBandwidth lhs, 152 QuicTime::Delta rhs) { 153 return lhs.ToBytesPerPeriod(rhs); 154 } 155 inline constexpr QuicByteCount operator*(QuicTime::Delta lhs, 156 QuicBandwidth rhs) { 157 return rhs * lhs; 158 } 159 160 // Override stream output operator for gtest. 161 inline std::ostream& operator<<(std::ostream& output, 162 const QuicBandwidth bandwidth) { 163 output << bandwidth.ToDebuggingValue(); 164 return output; 165 } 166 167 } // namespace quic 168 #endif // QUICHE_QUIC_CORE_QUIC_BANDWIDTH_H_ 169