| /* |
| * Copyright 2016 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 "rtc_base/numerics/percentile_filter.h" |
| |
| #include <stdlib.h> |
| |
| #include <array> |
| #include <climits> |
| #include <cstdint> |
| #include <random> |
| |
| #include "absl/algorithm/container.h" |
| #include "rtc_base/constructor_magic.h" |
| #include "test/gtest.h" |
| |
| namespace webrtc { |
| |
| class PercentileFilterTest : public ::testing::TestWithParam<float> { |
| public: |
| PercentileFilterTest() : filter_(GetParam()) { |
| // Make sure the tests are deterministic by seeding with a constant. |
| srand(42); |
| } |
| |
| protected: |
| PercentileFilter<int64_t> filter_; |
| |
| private: |
| RTC_DISALLOW_COPY_AND_ASSIGN(PercentileFilterTest); |
| }; |
| |
| INSTANTIATE_TEST_SUITE_P(PercentileFilterTests, |
| PercentileFilterTest, |
| ::testing::Values(0.0f, 0.1f, 0.5f, 0.9f, 1.0f)); |
| |
| TEST(PercentileFilterTest, MinFilter) { |
| PercentileFilter<int64_t> filter(0.0f); |
| filter.Insert(4); |
| EXPECT_EQ(4, filter.GetPercentileValue()); |
| filter.Insert(3); |
| EXPECT_EQ(3, filter.GetPercentileValue()); |
| } |
| |
| TEST(PercentileFilterTest, MaxFilter) { |
| PercentileFilter<int64_t> filter(1.0f); |
| filter.Insert(3); |
| EXPECT_EQ(3, filter.GetPercentileValue()); |
| filter.Insert(4); |
| EXPECT_EQ(4, filter.GetPercentileValue()); |
| } |
| |
| TEST(PercentileFilterTest, MedianFilterDouble) { |
| PercentileFilter<double> filter(0.5f); |
| filter.Insert(2.71828); |
| filter.Insert(3.14159); |
| filter.Insert(1.41421); |
| EXPECT_EQ(2.71828, filter.GetPercentileValue()); |
| } |
| |
| TEST(PercentileFilterTest, MedianFilterInt) { |
| PercentileFilter<int> filter(0.5f); |
| filter.Insert(INT_MIN); |
| filter.Insert(1); |
| filter.Insert(2); |
| EXPECT_EQ(1, filter.GetPercentileValue()); |
| filter.Insert(INT_MAX); |
| filter.Erase(INT_MIN); |
| EXPECT_EQ(2, filter.GetPercentileValue()); |
| } |
| |
| TEST(PercentileFilterTest, MedianFilterUnsigned) { |
| PercentileFilter<unsigned> filter(0.5f); |
| filter.Insert(UINT_MAX); |
| filter.Insert(2u); |
| filter.Insert(1u); |
| EXPECT_EQ(2u, filter.GetPercentileValue()); |
| filter.Insert(0u); |
| filter.Erase(UINT_MAX); |
| EXPECT_EQ(1u, filter.GetPercentileValue()); |
| } |
| |
| TEST_P(PercentileFilterTest, EmptyFilter) { |
| EXPECT_EQ(0, filter_.GetPercentileValue()); |
| filter_.Insert(3); |
| bool success = filter_.Erase(3); |
| EXPECT_TRUE(success); |
| EXPECT_EQ(0, filter_.GetPercentileValue()); |
| } |
| |
| TEST_P(PercentileFilterTest, EraseNonExistingElement) { |
| bool success = filter_.Erase(3); |
| EXPECT_FALSE(success); |
| EXPECT_EQ(0, filter_.GetPercentileValue()); |
| filter_.Insert(4); |
| success = filter_.Erase(3); |
| EXPECT_FALSE(success); |
| EXPECT_EQ(4, filter_.GetPercentileValue()); |
| } |
| |
| TEST_P(PercentileFilterTest, DuplicateElements) { |
| filter_.Insert(3); |
| filter_.Insert(3); |
| filter_.Erase(3); |
| EXPECT_EQ(3, filter_.GetPercentileValue()); |
| } |
| |
| TEST_P(PercentileFilterTest, InsertAndEraseTenValuesInRandomOrder) { |
| std::array<int64_t, 10> zero_to_nine = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; |
| // The percentile value of the ten values above. |
| const int64_t expected_value = static_cast<int64_t>(GetParam() * 9); |
| |
| // Insert two sets of `zero_to_nine` in random order. |
| for (int i = 0; i < 2; ++i) { |
| absl::c_shuffle(zero_to_nine, std::mt19937(std::random_device()())); |
| for (int64_t value : zero_to_nine) |
| filter_.Insert(value); |
| // After inserting a full set of `zero_to_nine`, the percentile should |
| // stay constant. |
| EXPECT_EQ(expected_value, filter_.GetPercentileValue()); |
| } |
| |
| // Insert and erase sets of `zero_to_nine` in random order a few times. |
| for (int i = 0; i < 3; ++i) { |
| absl::c_shuffle(zero_to_nine, std::mt19937(std::random_device()())); |
| for (int64_t value : zero_to_nine) |
| filter_.Erase(value); |
| EXPECT_EQ(expected_value, filter_.GetPercentileValue()); |
| absl::c_shuffle(zero_to_nine, std::mt19937(std::random_device()())); |
| for (int64_t value : zero_to_nine) |
| filter_.Insert(value); |
| EXPECT_EQ(expected_value, filter_.GetPercentileValue()); |
| } |
| } |
| |
| } // namespace webrtc |