Make UniqueNumberGenerator::AddKnownId() return a value

Make AddKnownId() return a value to indicate whether the ID was
known before, or has only been made known now.
This allows users of the class to RTC_DCHECK that no collisions
existed in their seed set, for instance.

This change is done for the following classes:
1. UniqueNumberGenerator
2. UniqueRandomIdGenerator
3. UniqueStringGenerator

Bug: None
Change-Id: I627d2821cb76aa333075e36575088d76dbeb3665
Reviewed-on: https://webrtc-review.googlesource.com/c/121780
Commit-Queue: Elad Alon <eladalon@webrtc.org>
Reviewed-by: Amit Hilbuch <amithi@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26621}
This commit is contained in:
Elad Alon
2019-02-08 23:35:59 +01:00
committed by Commit Bot
parent 6ba2738623
commit efc9a14a2b
3 changed files with 54 additions and 10 deletions

View File

@ -26,8 +26,8 @@ UniqueRandomIdGenerator::UniqueRandomIdGenerator(ArrayView<uint32_t> known_ids)
UniqueRandomIdGenerator::~UniqueRandomIdGenerator() = default; UniqueRandomIdGenerator::~UniqueRandomIdGenerator() = default;
uint32_t UniqueRandomIdGenerator::GenerateId() { uint32_t UniqueRandomIdGenerator::GenerateId() {
RTC_CHECK_LT(known_ids_.size(), std::numeric_limits<uint32_t>::max() - 1);
while (true) { while (true) {
RTC_CHECK_LT(known_ids_.size(), std::numeric_limits<uint32_t>::max());
auto pair = known_ids_.insert(CreateRandomNonZeroId()); auto pair = known_ids_.insert(CreateRandomNonZeroId());
if (pair.second) { if (pair.second) {
return *pair.first; return *pair.first;
@ -35,8 +35,8 @@ uint32_t UniqueRandomIdGenerator::GenerateId() {
} }
} }
void UniqueRandomIdGenerator::AddKnownId(uint32_t value) { bool UniqueRandomIdGenerator::AddKnownId(uint32_t value) {
known_ids_.insert(value); return known_ids_.insert(value).second;
} }
UniqueStringGenerator::UniqueStringGenerator() : unique_number_generator_() {} UniqueStringGenerator::UniqueStringGenerator() : unique_number_generator_() {}
@ -52,13 +52,14 @@ std::string UniqueStringGenerator::GenerateString() {
return ToString(unique_number_generator_.GenerateNumber()); return ToString(unique_number_generator_.GenerateNumber());
} }
void UniqueStringGenerator::AddKnownId(const std::string& value) { bool UniqueStringGenerator::AddKnownId(const std::string& value) {
absl::optional<uint32_t> int_value = StringToNumber<uint32_t>(value); absl::optional<uint32_t> int_value = StringToNumber<uint32_t>(value);
// The underlying generator works for uint32_t values, so if the provided // The underlying generator works for uint32_t values, so if the provided
// value is not a uint32_t it will never be generated anyway. // value is not a uint32_t it will never be generated anyway.
if (int_value.has_value()) { if (int_value.has_value()) {
unique_number_generator_.AddKnownId(int_value.value()); return unique_number_generator_.AddKnownId(int_value.value());
} }
return false;
} }
} // namespace rtc } // namespace rtc

View File

@ -43,7 +43,8 @@ class UniqueNumberGenerator {
TIntegral operator()() { return GenerateNumber(); } TIntegral operator()() { return GenerateNumber(); }
// Adds an id that this generator should no longer generate. // Adds an id that this generator should no longer generate.
void AddKnownId(TIntegral value); // Return value indicates whether the ID was hitherto unknown.
bool AddKnownId(TIntegral value);
private: private:
static_assert(std::is_integral<TIntegral>::value, "Must be integral type."); static_assert(std::is_integral<TIntegral>::value, "Must be integral type.");
@ -71,7 +72,8 @@ class UniqueRandomIdGenerator {
uint32_t operator()() { return GenerateId(); } uint32_t operator()() { return GenerateId(); }
// Adds an id that this generator should no longer generate. // Adds an id that this generator should no longer generate.
void AddKnownId(uint32_t value); // Return value indicates whether the ID was hitherto unknown.
bool AddKnownId(uint32_t value);
private: private:
std::set<uint32_t> known_ids_; std::set<uint32_t> known_ids_;
@ -93,7 +95,8 @@ class UniqueStringGenerator {
std::string operator()() { return GenerateString(); } std::string operator()() { return GenerateString(); }
// Adds an id that this generator should no longer generate. // Adds an id that this generator should no longer generate.
void AddKnownId(const std::string& value); // Return value indicates whether the ID was hitherto unknown.
bool AddKnownId(const std::string& value);
private: private:
// This implementation will be simple and will generate "0", "1", ... // This implementation will be simple and will generate "0", "1", ...
@ -123,8 +126,8 @@ TIntegral UniqueNumberGenerator<TIntegral>::GenerateNumber() {
} }
template <typename TIntegral> template <typename TIntegral>
void UniqueNumberGenerator<TIntegral>::AddKnownId(TIntegral value) { bool UniqueNumberGenerator<TIntegral>::AddKnownId(TIntegral value) {
known_ids_.insert(value); return known_ids_.insert(value).second;
} }
} // namespace rtc } // namespace rtc

View File

@ -29,6 +29,7 @@ class UniqueIdGeneratorTest : public Test {};
using test_types = ::testing::Types<UniqueNumberGenerator<uint8_t>, using test_types = ::testing::Types<UniqueNumberGenerator<uint8_t>,
UniqueNumberGenerator<uint16_t>, UniqueNumberGenerator<uint16_t>,
UniqueNumberGenerator<uint32_t>, UniqueNumberGenerator<uint32_t>,
UniqueNumberGenerator<int>,
UniqueRandomIdGenerator, UniqueRandomIdGenerator,
UniqueStringGenerator>; UniqueStringGenerator>;
@ -107,4 +108,43 @@ TYPED_TEST(UniqueIdGeneratorTest, AddedElementsAreNotGenerated) {
EXPECT_THAT(intersection, IsEmpty()); EXPECT_THAT(intersection, IsEmpty());
} }
TYPED_TEST(UniqueIdGeneratorTest, AddKnownIdOnNewIdReturnsTrue) {
typedef TypeParam Generator;
rtc::InitRandom(0);
Generator generator1;
const typename Generator::value_type id = generator1();
rtc::InitRandom(0);
Generator generator2;
EXPECT_TRUE(generator2.AddKnownId(id));
}
TYPED_TEST(UniqueIdGeneratorTest, AddKnownIdCalledAgainForSameIdReturnsFalse) {
typedef TypeParam Generator;
rtc::InitRandom(0);
Generator generator1;
const typename Generator::value_type id = generator1();
rtc::InitRandom(0);
Generator generator2;
ASSERT_TRUE(generator2.AddKnownId(id));
EXPECT_FALSE(generator2.AddKnownId(id));
}
TYPED_TEST(UniqueIdGeneratorTest,
AddKnownIdOnIdProvidedAsKnownToCtorReturnsFalse) {
typedef TypeParam Generator;
rtc::InitRandom(0);
Generator generator1;
const typename Generator::value_type id = generator1();
std::vector<typename Generator::value_type> known_values = {id};
rtc::InitRandom(0);
Generator generator2(known_values);
EXPECT_FALSE(generator2.AddKnownId(id));
}
} // namespace rtc } // namespace rtc