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