You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

btree_test.h 6.3 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  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. {
  29. ABSL_NAMESPACE_BEGIN
  30. namespace container_internal
  31. {
  32. // Like remove_const but propagates the removal through std::pair.
  33. template<typename T>
  34. struct remove_pair_const
  35. {
  36. using type = typename std::remove_const<T>::type;
  37. };
  38. template<typename T, typename U>
  39. struct remove_pair_const<std::pair<T, U>>
  40. {
  41. using type = std::pair<typename remove_pair_const<T>::type, typename remove_pair_const<U>::type>;
  42. };
  43. // Utility class to provide an accessor for a key given a value. The default
  44. // behavior is to treat the value as a pair and return the first element.
  45. template<typename K, typename V>
  46. struct KeyOfValue
  47. {
  48. struct type
  49. {
  50. const K& operator()(const V& p) const
  51. {
  52. return p.first;
  53. }
  54. };
  55. };
  56. // Partial specialization of KeyOfValue class for when the key and value are
  57. // the same type such as in set<> and btree_set<>.
  58. template<typename K>
  59. struct KeyOfValue<K, K>
  60. {
  61. struct type
  62. {
  63. const K& operator()(const K& k) const
  64. {
  65. return k;
  66. }
  67. };
  68. };
  69. inline char* GenerateDigits(char buf[16], unsigned val, unsigned maxval)
  70. {
  71. assert(val <= maxval);
  72. constexpr unsigned kBase = 64; // avoid integer division.
  73. unsigned p = 15;
  74. buf[p--] = 0;
  75. while (maxval > 0)
  76. {
  77. buf[p--] = ' ' + (val % kBase);
  78. val /= kBase;
  79. maxval /= kBase;
  80. }
  81. return buf + p + 1;
  82. }
  83. template<typename K>
  84. struct Generator
  85. {
  86. int maxval;
  87. explicit Generator(int m) :
  88. maxval(m)
  89. {
  90. }
  91. K operator()(int i) const
  92. {
  93. assert(i <= maxval);
  94. return K(i);
  95. }
  96. };
  97. template<>
  98. struct Generator<absl::Time>
  99. {
  100. int maxval;
  101. explicit Generator(int m) :
  102. maxval(m)
  103. {
  104. }
  105. absl::Time operator()(int i) const
  106. {
  107. return absl::FromUnixMillis(i);
  108. }
  109. };
  110. template<>
  111. struct Generator<std::string>
  112. {
  113. int maxval;
  114. explicit Generator(int m) :
  115. maxval(m)
  116. {
  117. }
  118. std::string operator()(int i) const
  119. {
  120. char buf[16];
  121. return GenerateDigits(buf, i, maxval);
  122. }
  123. };
  124. template<>
  125. struct Generator<Cord>
  126. {
  127. int maxval;
  128. explicit Generator(int m) :
  129. maxval(m)
  130. {
  131. }
  132. Cord operator()(int i) const
  133. {
  134. char buf[16];
  135. return Cord(GenerateDigits(buf, i, maxval));
  136. }
  137. };
  138. template<typename T, typename U>
  139. struct Generator<std::pair<T, U>>
  140. {
  141. Generator<typename remove_pair_const<T>::type> tgen;
  142. Generator<typename remove_pair_const<U>::type> ugen;
  143. explicit Generator(int m) :
  144. tgen(m),
  145. ugen(m)
  146. {
  147. }
  148. std::pair<T, U> operator()(int i) const
  149. {
  150. return std::make_pair(tgen(i), ugen(i));
  151. }
  152. };
  153. // Generate n values for our tests and benchmarks. Value range is [0, maxval].
  154. inline std::vector<int> GenerateNumbersWithSeed(int n, int maxval, int seed)
  155. {
  156. // NOTE: Some tests rely on generated numbers not changing between test runs.
  157. // We use std::minstd_rand0 because it is well-defined, but don't use
  158. // std::uniform_int_distribution because platforms use different algorithms.
  159. std::minstd_rand0 rng(seed);
  160. std::vector<int> values;
  161. absl::flat_hash_set<int> unique_values;
  162. if (values.size() < n)
  163. {
  164. for (int i = values.size(); i < n; i++)
  165. {
  166. int value;
  167. do
  168. {
  169. value = static_cast<int>(rng()) % (maxval + 1);
  170. } while (!unique_values.insert(value).second);
  171. values.push_back(value);
  172. }
  173. }
  174. return values;
  175. }
  176. // Generates n values in the range [0, maxval].
  177. template<typename V>
  178. std::vector<V> GenerateValuesWithSeed(int n, int maxval, int seed)
  179. {
  180. const std::vector<int> nums = GenerateNumbersWithSeed(n, maxval, seed);
  181. Generator<V> gen(maxval);
  182. std::vector<V> vec;
  183. vec.reserve(n);
  184. for (int i = 0; i < n; i++)
  185. {
  186. vec.push_back(gen(nums[i]));
  187. }
  188. return vec;
  189. }
  190. } // namespace container_internal
  191. ABSL_NAMESPACE_END
  192. } // namespace absl
  193. #endif // ABSL_CONTAINER_BTREE_TEST_H_