btree_test.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // Copyright 2018 The Abseil Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #ifndef ABSL_CONTAINER_BTREE_TEST_H_
  15. #define ABSL_CONTAINER_BTREE_TEST_H_
  16. #include <algorithm>
  17. #include <cassert>
  18. #include <random>
  19. #include <string>
  20. #include <utility>
  21. #include <vector>
  22. #include "absl/container/btree_map.h"
  23. #include "absl/container/btree_set.h"
  24. #include "absl/container/flat_hash_set.h"
  25. #include "absl/strings/cord.h"
  26. #include "absl/time/time.h"
  27. namespace absl {
  28. ABSL_NAMESPACE_BEGIN
  29. namespace container_internal {
  30. // Like remove_const but propagates the removal through std::pair.
  31. template <typename T>
  32. struct remove_pair_const {
  33. using type = typename std::remove_const<T>::type;
  34. };
  35. template <typename T, typename U>
  36. struct remove_pair_const<std::pair<T, U> > {
  37. using type = std::pair<typename remove_pair_const<T>::type,
  38. typename remove_pair_const<U>::type>;
  39. };
  40. // Utility class to provide an accessor for a key given a value. The default
  41. // behavior is to treat the value as a pair and return the first element.
  42. template <typename K, typename V>
  43. struct KeyOfValue {
  44. struct type {
  45. const K& operator()(const V& p) const { return p.first; }
  46. };
  47. };
  48. // Partial specialization of KeyOfValue class for when the key and value are
  49. // the same type such as in set<> and btree_set<>.
  50. template <typename K>
  51. struct KeyOfValue<K, K> {
  52. struct type {
  53. const K& operator()(const K& k) const { return k; }
  54. };
  55. };
  56. inline char* GenerateDigits(char buf[16], unsigned val, unsigned maxval) {
  57. assert(val <= maxval);
  58. constexpr unsigned kBase = 64; // avoid integer division.
  59. unsigned p = 15;
  60. buf[p--] = 0;
  61. while (maxval > 0) {
  62. buf[p--] = ' ' + (val % kBase);
  63. val /= kBase;
  64. maxval /= kBase;
  65. }
  66. return buf + p + 1;
  67. }
  68. template <typename K>
  69. struct Generator {
  70. int maxval;
  71. explicit Generator(int m) : maxval(m) {}
  72. K operator()(int i) const {
  73. assert(i <= maxval);
  74. return K(i);
  75. }
  76. };
  77. template <>
  78. struct Generator<absl::Time> {
  79. int maxval;
  80. explicit Generator(int m) : maxval(m) {}
  81. absl::Time operator()(int i) const { return absl::FromUnixMillis(i); }
  82. };
  83. template <>
  84. struct Generator<std::string> {
  85. int maxval;
  86. explicit Generator(int m) : maxval(m) {}
  87. std::string operator()(int i) const {
  88. char buf[16];
  89. return GenerateDigits(buf, i, maxval);
  90. }
  91. };
  92. template <>
  93. struct Generator<Cord> {
  94. int maxval;
  95. explicit Generator(int m) : maxval(m) {}
  96. Cord operator()(int i) const {
  97. char buf[16];
  98. return Cord(GenerateDigits(buf, i, maxval));
  99. }
  100. };
  101. template <typename T, typename U>
  102. struct Generator<std::pair<T, U> > {
  103. Generator<typename remove_pair_const<T>::type> tgen;
  104. Generator<typename remove_pair_const<U>::type> ugen;
  105. explicit Generator(int m) : tgen(m), ugen(m) {}
  106. std::pair<T, U> operator()(int i) const {
  107. return std::make_pair(tgen(i), ugen(i));
  108. }
  109. };
  110. // Generate n values for our tests and benchmarks. Value range is [0, maxval].
  111. inline std::vector<int> GenerateNumbersWithSeed(int n, int maxval, int seed) {
  112. // NOTE: Some tests rely on generated numbers not changing between test runs.
  113. // We use std::minstd_rand0 because it is well-defined, but don't use
  114. // std::uniform_int_distribution because platforms use different algorithms.
  115. std::minstd_rand0 rng(seed);
  116. std::vector<int> values;
  117. absl::flat_hash_set<int> unique_values;
  118. if (values.size() < n) {
  119. for (int i = values.size(); i < n; i++) {
  120. int value;
  121. do {
  122. value = static_cast<int>(rng()) % (maxval + 1);
  123. } while (!unique_values.insert(value).second);
  124. values.push_back(value);
  125. }
  126. }
  127. return values;
  128. }
  129. // Generates n values in the range [0, maxval].
  130. template <typename V>
  131. std::vector<V> GenerateValuesWithSeed(int n, int maxval, int seed) {
  132. const std::vector<int> nums = GenerateNumbersWithSeed(n, maxval, seed);
  133. Generator<V> gen(maxval);
  134. std::vector<V> vec;
  135. vec.reserve(n);
  136. for (int i = 0; i < n; i++) {
  137. vec.push_back(gen(nums[i]));
  138. }
  139. return vec;
  140. }
  141. } // namespace container_internal
  142. ABSL_NAMESPACE_END
  143. } // namespace absl
  144. #endif // ABSL_CONTAINER_BTREE_TEST_H_