• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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