From 66fa535e6e98701c47bde2e026ed22475938c10d Mon Sep 17 00:00:00 2001 From: Sebastian Jansson Date: Mon, 30 Apr 2018 16:54:57 +0200 Subject: [PATCH] Prepares for moving units to API. Cleanup based on review of move CL. Using separate CL to keep the move clean. Bug: webrtc:9155 Change-Id: Ie0b15c6d3efcd86e2fa5761f014d0daf72ccfa06 Reviewed-on: https://webrtc-review.googlesource.com/73367 Commit-Queue: Sebastian Jansson Reviewed-by: Karl Wiberg Cr-Commit-Position: refs/heads/master@{#23068} --- .../network_control/units/data_rate.cc | 27 --------- .../network_control/units/data_rate.h | 59 +++++++++++-------- .../units/data_rate_unittest.cc | 47 +++++++-------- .../network_control/units/data_size.h | 35 ++++------- .../units/data_size_unittest.cc | 4 -- .../network_control/units/time_delta.h | 27 +++++---- 6 files changed, 86 insertions(+), 113 deletions(-) diff --git a/modules/congestion_controller/network_control/units/data_rate.cc b/modules/congestion_controller/network_control/units/data_rate.cc index b4b9a4cfa7..182c07b846 100644 --- a/modules/congestion_controller/network_control/units/data_rate.cc +++ b/modules/congestion_controller/network_control/units/data_rate.cc @@ -13,33 +13,6 @@ #include "rtc_base/strings/string_builder.h" namespace webrtc { -namespace { -int64_t Microbytes(const DataSize& size) { - constexpr int64_t kMaxBeforeConversion = - std::numeric_limits::max() / 1000000; - RTC_DCHECK(size.bytes() < kMaxBeforeConversion) - << "size is too large to be expressed in microbytes, size: " - << size.bytes() << " is not less than " << kMaxBeforeConversion; - return size.bytes() * 1000000; -} -} // namespace - -DataRate operator/(const DataSize& size, const TimeDelta& duration) { - return DataRate::bytes_per_second(Microbytes(size) / duration.us()); -} - -TimeDelta operator/(const DataSize& size, const DataRate& rate) { - return TimeDelta::us(Microbytes(size) / rate.bytes_per_second()); -} - -DataSize operator*(const DataRate& rate, const TimeDelta& duration) { - int64_t microbytes = rate.bytes_per_second() * duration.us(); - return DataSize::bytes((microbytes + 500000) / 1000000); -} - -DataSize operator*(const TimeDelta& duration, const DataRate& rate) { - return rate * duration; -} std::string ToString(const DataRate& value) { char buf[64]; diff --git a/modules/congestion_controller/network_control/units/data_rate.h b/modules/congestion_controller/network_control/units/data_rate.h index e42cdadcce..e3834944d4 100644 --- a/modules/congestion_controller/network_control/units/data_rate.h +++ b/modules/congestion_controller/network_control/units/data_rate.h @@ -25,14 +25,19 @@ namespace webrtc { namespace data_rate_impl { constexpr int64_t kPlusInfinityVal = std::numeric_limits::max(); constexpr int64_t kNotInitializedVal = -1; + +inline int64_t Microbits(const DataSize& size) { + constexpr int64_t kMaxBeforeConversion = + std::numeric_limits::max() / 8000000; + RTC_DCHECK_LE(size.bytes(), kMaxBeforeConversion) + << "size is too large to be expressed in microbytes"; + return size.bytes() * 8000000; +} } // namespace data_rate_impl // DataRate is a class that represents a given data rate. This can be used to -// represent bandwidth, encoding bitrate, etc. The internal storage is currently -// bits per second (bps) since this makes it easier to intepret the raw value -// when debugging. The promised precision, however is only that it will -// represent bytes per second accurately. Any implementation depending on bps -// resolution should document this by changing this comment. +// represent bandwidth, encoding bitrate, etc. The internal storage is bits per +// second (bps). class DataRate { public: DataRate() : DataRate(data_rate_impl::kNotInitializedVal) {} @@ -40,10 +45,6 @@ class DataRate { static DataRate Infinity() { return DataRate(data_rate_impl::kPlusInfinityVal); } - static DataRate bytes_per_second(int64_t bytes_per_sec) { - RTC_DCHECK_GE(bytes_per_sec, 0); - return DataRate(bytes_per_sec * 8); - } static DataRate bits_per_second(int64_t bits_per_sec) { RTC_DCHECK_GE(bits_per_sec, 0); return DataRate(bits_per_sec); @@ -58,7 +59,6 @@ class DataRate { RTC_DCHECK(IsFinite()); return bits_per_sec_; } - int64_t bytes_per_second() const { return bits_per_second() / 8; } int64_t bps() const { return bits_per_second(); } int64_t bps_or(int64_t fallback) const { return IsFinite() ? bits_per_second() : fallback; @@ -72,15 +72,7 @@ class DataRate { return bits_per_sec_ != data_rate_impl::kNotInitializedVal; } bool IsFinite() const { return IsInitialized() && !IsInfinite(); } - DataRate operator*(double scalar) const { - return DataRate::bytes_per_second(std::round(bytes_per_second() * scalar)); - } - DataRate operator*(int64_t scalar) const { - return DataRate::bytes_per_second(bytes_per_second() * scalar); - } - DataRate operator*(int32_t scalar) const { - return DataRate::bytes_per_second(bytes_per_second() * scalar); - } + bool operator==(const DataRate& other) const { return bits_per_sec_ == other.bits_per_sec_; } @@ -106,20 +98,41 @@ class DataRate { explicit DataRate(int64_t bits_per_second) : bits_per_sec_(bits_per_second) {} int64_t bits_per_sec_; }; + +inline DataRate operator*(const DataRate& rate, const double& scalar) { + return DataRate::bits_per_second(std::round(rate.bits_per_second() * scalar)); +} inline DataRate operator*(const double& scalar, const DataRate& rate) { return rate * scalar; } +inline DataRate operator*(const DataRate& rate, const int64_t& scalar) { + return DataRate::bits_per_second(rate.bits_per_second() * scalar); +} inline DataRate operator*(const int64_t& scalar, const DataRate& rate) { return rate * scalar; } +inline DataRate operator*(const DataRate& rate, const int32_t& scalar) { + return DataRate::bits_per_second(rate.bits_per_second() * scalar); +} inline DataRate operator*(const int32_t& scalar, const DataRate& rate) { return rate * scalar; } -DataRate operator/(const DataSize& size, const TimeDelta& duration); -TimeDelta operator/(const DataSize& size, const DataRate& rate); -DataSize operator*(const DataRate& rate, const TimeDelta& duration); -DataSize operator*(const TimeDelta& duration, const DataRate& rate); +inline DataRate operator/(const DataSize& size, const TimeDelta& duration) { + return DataRate::bits_per_second(data_rate_impl::Microbits(size) / + duration.us()); +} +inline TimeDelta operator/(const DataSize& size, const DataRate& rate) { + return TimeDelta::us(data_rate_impl::Microbits(size) / + rate.bits_per_second()); +} +inline DataSize operator*(const DataRate& rate, const TimeDelta& duration) { + int64_t microbits = rate.bits_per_second() * duration.us(); + return DataSize::bytes((microbits + 4000000) / 8000000); +} +inline DataSize operator*(const TimeDelta& duration, const DataRate& rate) { + return rate * duration; +} std::string ToString(const DataRate& value); diff --git a/modules/congestion_controller/network_control/units/data_rate_unittest.cc b/modules/congestion_controller/network_control/units/data_rate_unittest.cc index abc339fdd4..68375b1463 100644 --- a/modules/congestion_controller/network_control/units/data_rate_unittest.cc +++ b/modules/congestion_controller/network_control/units/data_rate_unittest.cc @@ -15,7 +15,6 @@ namespace webrtc { namespace test { TEST(DataRateTest, GetBackSameValues) { const int64_t kValue = 123 * 8; - EXPECT_EQ(DataRate::bytes_per_second(kValue).bytes_per_second(), kValue); EXPECT_EQ(DataRate::bits_per_second(kValue).bits_per_second(), kValue); EXPECT_EQ(DataRate::bps(kValue).bps(), kValue); EXPECT_EQ(DataRate::kbps(kValue).kbps(), kValue); @@ -23,30 +22,28 @@ TEST(DataRateTest, GetBackSameValues) { TEST(DataRateTest, GetDifferentPrefix) { const int64_t kValue = 123 * 8000; - EXPECT_EQ(DataRate::bytes_per_second(kValue).bps(), kValue * 8); - EXPECT_EQ(DataRate::bits_per_second(kValue).bytes_per_second(), kValue / 8); EXPECT_EQ(DataRate::bps(kValue).kbps(), kValue / 1000); } TEST(DataRateTest, IdentityChecks) { const int64_t kValue = 3000; EXPECT_TRUE(DataRate::Zero().IsZero()); - EXPECT_FALSE(DataRate::bytes_per_second(kValue).IsZero()); + EXPECT_FALSE(DataRate::bits_per_second(kValue).IsZero()); EXPECT_TRUE(DataRate::Infinity().IsInfinite()); EXPECT_FALSE(DataRate::Zero().IsInfinite()); - EXPECT_FALSE(DataRate::bytes_per_second(kValue).IsInfinite()); + EXPECT_FALSE(DataRate::bits_per_second(kValue).IsInfinite()); EXPECT_FALSE(DataRate::Infinity().IsFinite()); - EXPECT_TRUE(DataRate::bytes_per_second(kValue).IsFinite()); + EXPECT_TRUE(DataRate::bits_per_second(kValue).IsFinite()); EXPECT_TRUE(DataRate::Zero().IsFinite()); } TEST(DataRateTest, ComparisonOperators) { const int64_t kSmall = 450; const int64_t kLarge = 451; - const DataRate small = DataRate::bytes_per_second(kSmall); - const DataRate large = DataRate::bytes_per_second(kLarge); + const DataRate small = DataRate::bits_per_second(kSmall); + const DataRate large = DataRate::bits_per_second(kLarge); EXPECT_EQ(DataRate::Zero(), DataRate::bps(0)); EXPECT_EQ(DataRate::Infinity(), DataRate::Infinity()); @@ -65,25 +62,25 @@ TEST(DataRateTest, ComparisonOperators) { TEST(DataRateTest, MathOperations) { const int64_t kValueA = 450; const int64_t kValueB = 267; - const DataRate size_a = DataRate::bytes_per_second(kValueA); + const DataRate size_a = DataRate::bits_per_second(kValueA); const int32_t kInt32Value = 123; const double kFloatValue = 123.0; - EXPECT_EQ((size_a * kValueB).bytes_per_second(), kValueA * kValueB); - EXPECT_EQ((size_a * kInt32Value).bytes_per_second(), kValueA * kInt32Value); - EXPECT_EQ((size_a * kFloatValue).bytes_per_second(), kValueA * kFloatValue); + EXPECT_EQ((size_a * kValueB).bits_per_second(), kValueA * kValueB); + EXPECT_EQ((size_a * kInt32Value).bits_per_second(), kValueA * kInt32Value); + EXPECT_EQ((size_a * kFloatValue).bits_per_second(), kValueA * kFloatValue); } TEST(UnitConversionTest, DataRateAndDataSizeAndTimeDelta) { - const int64_t kValueA = 5; - const int64_t kValueB = 450; - const int64_t kValueC = 45000; - const TimeDelta delta_a = TimeDelta::seconds(kValueA); - const DataRate rate_b = DataRate::bytes_per_second(kValueB); - const DataSize size_c = DataSize::bytes(kValueC); - EXPECT_EQ((delta_a * rate_b).bytes(), kValueA * kValueB); - EXPECT_EQ((rate_b * delta_a).bytes(), kValueA * kValueB); - EXPECT_EQ((size_c / delta_a).bytes_per_second(), kValueC / kValueA); - EXPECT_EQ((size_c / rate_b).seconds(), kValueC / kValueB); + const int64_t kSeconds = 5; + const int64_t kBitsPerSecond = 440; + const int64_t kBytes = 44000; + const TimeDelta delta_a = TimeDelta::seconds(kSeconds); + const DataRate rate_b = DataRate::bits_per_second(kBitsPerSecond); + const DataSize size_c = DataSize::bytes(kBytes); + EXPECT_EQ((delta_a * rate_b).bytes(), kSeconds * kBitsPerSecond / 8); + EXPECT_EQ((rate_b * delta_a).bytes(), kSeconds * kBitsPerSecond / 8); + EXPECT_EQ((size_c / delta_a).bits_per_second(), kBytes * 8 / kSeconds); + EXPECT_EQ((size_c / rate_b).seconds(), kBytes * 8 / kBitsPerSecond); } #if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) @@ -103,9 +100,9 @@ TEST(UnitConversionTest, DivisionFailsOnLargeSize) { // Note that the failure is expected since the current implementation is // implementated in a way that does not support division of large sizes. If // the implementation is changed, this test can safely be removed. - const int64_t kToolargeForDivision = - std::numeric_limits::max() / 1000000; - const int64_t kJustSmallEnoughForDivision = kToolargeForDivision - 1; + const int64_t kJustSmallEnoughForDivision = + std::numeric_limits::max() / 8000000; + const int64_t kToolargeForDivision = kJustSmallEnoughForDivision + 1; const DataSize large_size = DataSize::bytes(kJustSmallEnoughForDivision); const DataSize too_large_size = DataSize::bytes(kToolargeForDivision); const DataRate data_rate = DataRate::kbps(100); diff --git a/modules/congestion_controller/network_control/units/data_size.h b/modules/congestion_controller/network_control/units/data_size.h index da396d8899..ab6ddbc2cb 100644 --- a/modules/congestion_controller/network_control/units/data_size.h +++ b/modules/congestion_controller/network_control/units/data_size.h @@ -24,10 +24,7 @@ constexpr int64_t kPlusInfinityVal = std::numeric_limits::max(); constexpr int64_t kNotInitializedVal = -1; } // namespace data_size_impl -// DataSize is a class represeting a count of bytes. Note that while it can be -// initialized by a number of bits, it does not guarantee that the resolution is -// kept and the internal storage is in bytes. The number of bits will be -// truncated to fit. +// DataSize is a class represeting a count of bytes. class DataSize { public: DataSize() : DataSize(data_size_impl::kNotInitializedVal) {} @@ -39,17 +36,11 @@ class DataSize { RTC_DCHECK_GE(bytes, 0); return DataSize(bytes); } - static DataSize bits(int64_t bits) { - RTC_DCHECK_GE(bits, 0); - return DataSize(bits / 8); - } int64_t bytes() const { RTC_DCHECK(IsFinite()); return bytes_; } int64_t kilobytes() const { return (bytes() + 500) / 1000; } - int64_t bits() const { return bytes() * 8; } - int64_t kilobits() const { return (bits() + 500) / 1000; } bool IsZero() const { return bytes_ == 0; } bool IsInfinite() const { return bytes_ == data_size_impl::kPlusInfinityVal; } bool IsInitialized() const { @@ -62,18 +53,6 @@ class DataSize { DataSize operator+(const DataSize& other) const { return DataSize::bytes(bytes() + other.bytes()); } - DataSize operator*(double scalar) const { - return DataSize::bytes(std::round(bytes() * scalar)); - } - DataSize operator*(int64_t scalar) const { - return DataSize::bytes(bytes() * scalar); - } - DataSize operator*(int32_t scalar) const { - return DataSize::bytes(bytes() * scalar); - } - DataSize operator/(int64_t scalar) const { - return DataSize::bytes(bytes() / scalar); - } DataSize& operator-=(const DataSize& other) { bytes_ -= other.bytes(); return *this; @@ -101,15 +80,27 @@ class DataSize { explicit DataSize(int64_t bytes) : bytes_(bytes) {} int64_t bytes_; }; +inline DataSize operator*(const DataSize& size, const double& scalar) { + return DataSize::bytes(std::round(size.bytes() * scalar)); +} inline DataSize operator*(const double& scalar, const DataSize& size) { return size * scalar; } +inline DataSize operator*(const DataSize& size, const int64_t& scalar) { + return DataSize::bytes(size.bytes() * scalar); +} inline DataSize operator*(const int64_t& scalar, const DataSize& size) { return size * scalar; } +inline DataSize operator*(const DataSize& size, const int32_t& scalar) { + return DataSize::bytes(size.bytes() * scalar); +} inline DataSize operator*(const int32_t& scalar, const DataSize& size) { return size * scalar; } +inline DataSize operator/(const DataSize& size, const int64_t& scalar) { + return DataSize::bytes(size.bytes() / scalar); +} std::string ToString(const DataSize& value); diff --git a/modules/congestion_controller/network_control/units/data_size_unittest.cc b/modules/congestion_controller/network_control/units/data_size_unittest.cc index 6314787650..febc170f12 100644 --- a/modules/congestion_controller/network_control/units/data_size_unittest.cc +++ b/modules/congestion_controller/network_control/units/data_size_unittest.cc @@ -17,14 +17,10 @@ namespace test { TEST(DataSizeTest, GetBackSameValues) { const int64_t kValue = 123 * 8; EXPECT_EQ(DataSize::bytes(kValue).bytes(), kValue); - EXPECT_EQ(DataSize::bits(kValue).bits(), kValue); } TEST(DataSizeTest, GetDifferentPrefix) { const int64_t kValue = 123 * 8000; - EXPECT_EQ(DataSize::bytes(kValue).bits(), kValue * 8); - EXPECT_EQ(DataSize::bits(kValue).bytes(), kValue / 8); - EXPECT_EQ(DataSize::bits(kValue).kilobits(), kValue / 1000); EXPECT_EQ(DataSize::bytes(kValue).kilobytes(), kValue / 1000); } diff --git a/modules/congestion_controller/network_control/units/time_delta.h b/modules/congestion_controller/network_control/units/time_delta.h index 7c570c7c34..36cbccffec 100644 --- a/modules/congestion_controller/network_control/units/time_delta.h +++ b/modules/congestion_controller/network_control/units/time_delta.h @@ -97,18 +97,7 @@ class TimeDelta { microseconds_ += other.us(); return *this; } - TimeDelta operator*(double scalar) const { - return TimeDelta::us(std::round(us() * scalar)); - } - TimeDelta operator*(int64_t scalar) const { - return TimeDelta::us(us() * scalar); - } - TimeDelta operator*(int32_t scalar) const { - return TimeDelta::us(us() * scalar); - } - TimeDelta operator/(int64_t scalar) const { - return TimeDelta::us(us() / scalar); - } + bool operator==(const TimeDelta& other) const { return microseconds_ == other.microseconds_; } @@ -132,16 +121,30 @@ class TimeDelta { explicit TimeDelta(int64_t us) : microseconds_(us) {} int64_t microseconds_; }; + +inline TimeDelta operator*(const TimeDelta& delta, const double& scalar) { + return TimeDelta::us(std::round(delta.us() * scalar)); +} inline TimeDelta operator*(const double& scalar, const TimeDelta& delta) { return delta * scalar; } +inline TimeDelta operator*(const TimeDelta& delta, const int64_t& scalar) { + return TimeDelta::us(delta.us() * scalar); +} inline TimeDelta operator*(const int64_t& scalar, const TimeDelta& delta) { return delta * scalar; } +inline TimeDelta operator*(const TimeDelta& delta, const int32_t& scalar) { + return TimeDelta::us(delta.us() * scalar); +} inline TimeDelta operator*(const int32_t& scalar, const TimeDelta& delta) { return delta * scalar; } +inline TimeDelta operator/(const TimeDelta& delta, const int64_t& scalar) { + return TimeDelta::us(delta.us() / scalar); +} + std::string ToString(const TimeDelta& value); } // namespace webrtc