diff --git a/modules/congestion_controller/network_control/units/BUILD.gn b/modules/congestion_controller/network_control/units/BUILD.gn index ecb8554280..4dc884e9cc 100644 --- a/modules/congestion_controller/network_control/units/BUILD.gn +++ b/modules/congestion_controller/network_control/units/BUILD.gn @@ -8,11 +8,9 @@ import("../../../../webrtc.gni") -rtc_static_library("units") { +rtc_source_set("units") { sources = [ "network_units.h", - "unit_operators.cc", - "unit_operators.h", ] deps = [ @@ -33,6 +31,8 @@ rtc_source_set("data_rate") { ] deps = [ + ":data_size", + ":time_delta", "../../../../api:optional", "../../../../rtc_base:checks", "../../../../rtc_base:rtc_base_approved", @@ -46,7 +46,6 @@ rtc_source_set("data_size") { ] deps = [ - ":data_rate", "../../../../api:optional", "../../../../rtc_base:checks", "../../../../rtc_base:rtc_base_approved", @@ -87,7 +86,6 @@ if (rtc_include_tests) { "data_size_unittest.cc", "time_delta_unittest.cc", "timestamp_unittest.cc", - "unit_operators_unittest.cc", ] deps = [ ":data_rate", diff --git a/modules/congestion_controller/network_control/units/data_rate.cc b/modules/congestion_controller/network_control/units/data_rate.cc index 182c07b846..b4b9a4cfa7 100644 --- a/modules/congestion_controller/network_control/units/data_rate.cc +++ b/modules/congestion_controller/network_control/units/data_rate.cc @@ -13,6 +13,33 @@ #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 1cc43f5f30..e42cdadcce 100644 --- a/modules/congestion_controller/network_control/units/data_rate.h +++ b/modules/congestion_controller/network_control/units/data_rate.h @@ -18,6 +18,9 @@ #include "rtc_base/checks.h" +#include "modules/congestion_controller/network_control/units/data_size.h" +#include "modules/congestion_controller/network_control/units/time_delta.h" + namespace webrtc { namespace data_rate_impl { constexpr int64_t kPlusInfinityVal = std::numeric_limits::max(); @@ -113,7 +116,13 @@ 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); + std::string ToString(const DataRate& value); + } // namespace webrtc #endif // MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_UNITS_DATA_RATE_H_ 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 48d0e78837..f3c5bd5989 100644 --- a/modules/congestion_controller/network_control/units/data_rate_unittest.cc +++ b/modules/congestion_controller/network_control/units/data_rate_unittest.cc @@ -72,5 +72,50 @@ TEST(DataRateTest, MathOperations) { EXPECT_EQ((size_a * kInt32Value).bytes_per_second(), kValueA * kInt32Value); EXPECT_EQ((size_a * kFloatValue).bytes_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).s(), kValueC / kValueB); +} + +#if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) +TEST(UnitConversionTest, DivisionByZeroFails) { + const DataSize non_zero_size = DataSize::bytes(100); + const DataSize zero_size = DataSize::Zero(); + const DataRate zero_rate = DataRate::Zero(); + const TimeDelta zero_delta = TimeDelta::Zero(); + + EXPECT_DEATH(non_zero_size / zero_rate, ""); + EXPECT_DEATH(non_zero_size / zero_delta, ""); + EXPECT_DEATH(zero_size / zero_rate, ""); + EXPECT_DEATH(zero_size / zero_delta, ""); +} + +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 DataSize large_size = DataSize::bytes(kJustSmallEnoughForDivision); + const DataSize too_large_size = DataSize::bytes(kToolargeForDivision); + const DataRate data_rate = DataRate::kbps(100); + const TimeDelta time_delta = TimeDelta::ms(100); + EXPECT_TRUE((large_size / data_rate).IsFinite()); + EXPECT_TRUE((large_size / time_delta).IsFinite()); + + EXPECT_DEATH(too_large_size / data_rate, ""); + EXPECT_DEATH(too_large_size / time_delta, ""); +} +#endif // GTEST_HAS_DEATH_TEST && !!defined(WEBRTC_ANDROID) } // namespace test } // namespace webrtc diff --git a/modules/congestion_controller/network_control/units/network_units.h b/modules/congestion_controller/network_control/units/network_units.h index 5b8eeecfd7..cd88c50056 100644 --- a/modules/congestion_controller/network_control/units/network_units.h +++ b/modules/congestion_controller/network_control/units/network_units.h @@ -15,6 +15,5 @@ #include "modules/congestion_controller/network_control/units/data_size.h" #include "modules/congestion_controller/network_control/units/time_delta.h" #include "modules/congestion_controller/network_control/units/timestamp.h" -#include "modules/congestion_controller/network_control/units/unit_operators.h" #endif // MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_UNITS_NETWORK_UNITS_H_ diff --git a/modules/congestion_controller/network_control/units/unit_operators.cc b/modules/congestion_controller/network_control/units/unit_operators.cc deleted file mode 100644 index 9ebc109e0b..0000000000 --- a/modules/congestion_controller/network_control/units/unit_operators.cc +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "modules/congestion_controller/network_control/units/unit_operators.h" - -#include - -namespace webrtc { -DataRate operator/(const DataSize& size, const TimeDelta& duration) { - RTC_DCHECK(size.bytes() < std::numeric_limits::max() / 1000000) - << "size is too large, size: " << size.bytes() << " is not less than " - << std::numeric_limits::max() / 1000000; - int64_t bytes_per_sec = size.bytes() * 1000000 / duration.us(); - return DataRate::bytes_per_second(bytes_per_sec); -} - -TimeDelta operator/(const DataSize& size, const DataRate& rate) { - RTC_DCHECK(size.bytes() < std::numeric_limits::max() / 1000000) - << "size is too large, size: " << size.bytes() << " is not less than " - << std::numeric_limits::max() / 1000000; - int64_t microseconds = size.bytes() * 1000000 / rate.bytes_per_second(); - return TimeDelta::us(microseconds); -} - -DataSize operator*(const DataRate& rate, const TimeDelta& duration) { - int64_t micro_bytes = rate.bytes_per_second() * duration.us(); - return DataSize::bytes((micro_bytes + 500000) / 1000000); -} - -DataSize operator*(const TimeDelta& duration, const DataRate& rate) { - return rate * duration; -} -} // namespace webrtc diff --git a/modules/congestion_controller/network_control/units/unit_operators.h b/modules/congestion_controller/network_control/units/unit_operators.h deleted file mode 100644 index 33de2a1908..0000000000 --- a/modules/congestion_controller/network_control/units/unit_operators.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_UNITS_UNIT_OPERATORS_H_ -#define MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_UNITS_UNIT_OPERATORS_H_ - -#include "modules/congestion_controller/network_control/units/data_rate.h" -#include "modules/congestion_controller/network_control/units/data_size.h" -#include "modules/congestion_controller/network_control/units/time_delta.h" - -namespace webrtc { -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); -} // namespace webrtc - -#endif // MODULES_CONGESTION_CONTROLLER_NETWORK_CONTROL_UNITS_UNIT_OPERATORS_H_ diff --git a/modules/congestion_controller/network_control/units/unit_operators_unittest.cc b/modules/congestion_controller/network_control/units/unit_operators_unittest.cc deleted file mode 100644 index 8c7b3e2a34..0000000000 --- a/modules/congestion_controller/network_control/units/unit_operators_unittest.cc +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "modules/congestion_controller/network_control/units/unit_operators.h" -#include "test/gtest.h" - -namespace webrtc { -namespace test { - -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).s(), kValueC / kValueB); -} - -} // namespace test -} // namespace webrtc