unique_id_generator.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*
  2. * Copyright 2018 The WebRTC project authors. All Rights Reserved.
  3. *
  4. * Use of this source code is governed by a BSD-style license
  5. * that can be found in the LICENSE file in the root of the source
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #ifndef RTC_BASE_UNIQUE_ID_GENERATOR_H_
  11. #define RTC_BASE_UNIQUE_ID_GENERATOR_H_
  12. #include <limits>
  13. #include <set>
  14. #include <string>
  15. #include "api/array_view.h"
  16. namespace rtc {
  17. // This class will generate numbers. A common use case is for identifiers.
  18. // The generated numbers will be unique, in the local scope of the generator.
  19. // This means that a generator will never generate the same number twice.
  20. // The generator can also be initialized with a sequence of known ids.
  21. // In such a case, it will never generate an id from that list.
  22. // Recommendedations:
  23. // * Prefer unsigned types.
  24. // * Prefer larger types (uint8_t will run out quickly).
  25. template <typename TIntegral>
  26. class UniqueNumberGenerator {
  27. public:
  28. typedef TIntegral value_type;
  29. UniqueNumberGenerator();
  30. // Creates a generator that will never return any value from the given list.
  31. explicit UniqueNumberGenerator(ArrayView<TIntegral> known_ids);
  32. ~UniqueNumberGenerator();
  33. // Generates a number that this generator has never produced before.
  34. // If there are no available numbers to generate, this method will fail
  35. // with an |RTC_CHECK|.
  36. TIntegral GenerateNumber();
  37. TIntegral operator()() { return GenerateNumber(); }
  38. // Adds an id that this generator should no longer generate.
  39. // Return value indicates whether the ID was hitherto unknown.
  40. bool AddKnownId(TIntegral value);
  41. private:
  42. static_assert(std::is_integral<TIntegral>::value, "Must be integral type.");
  43. TIntegral counter_;
  44. std::set<TIntegral> known_ids_;
  45. };
  46. // This class will generate unique ids. Ids are 32 bit unsigned integers.
  47. // The generated ids will be unique, in the local scope of the generator.
  48. // This means that a generator will never generate the same id twice.
  49. // The generator can also be initialized with a sequence of known ids.
  50. // In such a case, it will never generate an id from that list.
  51. class UniqueRandomIdGenerator {
  52. public:
  53. typedef uint32_t value_type;
  54. UniqueRandomIdGenerator();
  55. // Create a generator that will never return any value from the given list.
  56. explicit UniqueRandomIdGenerator(ArrayView<uint32_t> known_ids);
  57. ~UniqueRandomIdGenerator();
  58. // Generates a random id that this generator has never produced before.
  59. // This method becomes more expensive with each use, as the probability of
  60. // collision for the randomly generated numbers increases.
  61. uint32_t GenerateId();
  62. uint32_t operator()() { return GenerateId(); }
  63. // Adds an id that this generator should no longer generate.
  64. // Return value indicates whether the ID was hitherto unknown.
  65. bool AddKnownId(uint32_t value);
  66. private:
  67. std::set<uint32_t> known_ids_;
  68. };
  69. // This class will generate strings. A common use case is for identifiers.
  70. // The generated strings will be unique, in the local scope of the generator.
  71. // This means that a generator will never generate the same string twice.
  72. // The generator can also be initialized with a sequence of known ids.
  73. // In such a case, it will never generate an id from that list.
  74. class UniqueStringGenerator {
  75. public:
  76. typedef std::string value_type;
  77. UniqueStringGenerator();
  78. explicit UniqueStringGenerator(ArrayView<std::string> known_ids);
  79. ~UniqueStringGenerator();
  80. std::string GenerateString();
  81. std::string operator()() { return GenerateString(); }
  82. // Adds an id that this generator should no longer generate.
  83. // Return value indicates whether the ID was hitherto unknown.
  84. bool AddKnownId(const std::string& value);
  85. private:
  86. // This implementation will be simple and will generate "0", "1", ...
  87. UniqueNumberGenerator<uint32_t> unique_number_generator_;
  88. };
  89. template <typename TIntegral>
  90. UniqueNumberGenerator<TIntegral>::UniqueNumberGenerator() : counter_(0) {}
  91. template <typename TIntegral>
  92. UniqueNumberGenerator<TIntegral>::UniqueNumberGenerator(
  93. ArrayView<TIntegral> known_ids)
  94. : counter_(0), known_ids_(known_ids.begin(), known_ids.end()) {}
  95. template <typename TIntegral>
  96. UniqueNumberGenerator<TIntegral>::~UniqueNumberGenerator() {}
  97. template <typename TIntegral>
  98. TIntegral UniqueNumberGenerator<TIntegral>::GenerateNumber() {
  99. while (true) {
  100. RTC_CHECK_LT(counter_, std::numeric_limits<TIntegral>::max());
  101. auto pair = known_ids_.insert(counter_++);
  102. if (pair.second) {
  103. return *pair.first;
  104. }
  105. }
  106. }
  107. template <typename TIntegral>
  108. bool UniqueNumberGenerator<TIntegral>::AddKnownId(TIntegral value) {
  109. return known_ids_.insert(value).second;
  110. }
  111. } // namespace rtc
  112. #endif // RTC_BASE_UNIQUE_ID_GENERATOR_H_