Skip to content

Commit 29c9ddc

Browse files
committed
Update files
1 parent c340172 commit 29c9ddc

39 files changed

+9639
-9446
lines changed

external/tsl/robin_growth_policy.h

+166-162
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,10 @@
5757
#else
5858
#include <iostream>
5959
#define TSL_RH_THROW_OR_TERMINATE(ex, msg) \
60-
do { \
61-
std::cerr << msg << std::endl; \
62-
std::terminate(); \
63-
} while (0)
60+
do { \
61+
std::cerr << msg << std::endl; \
62+
std::terminate(); \
63+
} while (0)
6464
#endif
6565
#endif
6666

@@ -82,95 +82,96 @@ namespace rh {
8282
*/
8383
template <std::size_t GrowthFactor>
8484
class power_of_two_growth_policy {
85-
public:
86-
/**
87-
* Called on the hash table creation and on rehash. The number of buckets for
88-
* the table is passed in parameter. This number is a minimum, the policy may
89-
* update this value with a higher value if needed (but not lower).
90-
*
91-
* If 0 is given, min_bucket_count_in_out must still be 0 after the policy
92-
* creation and bucket_for_hash must always return 0 in this case.
93-
*/
94-
explicit power_of_two_growth_policy(std::size_t& min_bucket_count_in_out) {
95-
if (min_bucket_count_in_out > max_bucket_count()) {
96-
TSL_RH_THROW_OR_TERMINATE(
97-
std::length_error, "The hash table exceeds its maximum size.");
85+
public:
86+
/**
87+
* Called on the hash table creation and on rehash. The number of buckets
88+
* for the table is passed in parameter. This number is a minimum, the
89+
* policy may update this value with a higher value if needed (but not
90+
* lower).
91+
*
92+
* If 0 is given, min_bucket_count_in_out must still be 0 after the policy
93+
* creation and bucket_for_hash must always return 0 in this case.
94+
*/
95+
explicit power_of_two_growth_policy(std::size_t& min_bucket_count_in_out) {
96+
if (min_bucket_count_in_out > max_bucket_count()) {
97+
TSL_RH_THROW_OR_TERMINATE(
98+
std::length_error, "The hash table exceeds its maximum size.");
99+
}
100+
101+
if (min_bucket_count_in_out > 0) {
102+
min_bucket_count_in_out = round_up_to_power_of_two(
103+
min_bucket_count_in_out);
104+
m_mask = min_bucket_count_in_out - 1;
105+
} else {
106+
m_mask = 0;
107+
}
98108
}
99109

100-
if (min_bucket_count_in_out > 0) {
101-
min_bucket_count_in_out =
102-
round_up_to_power_of_two(min_bucket_count_in_out);
103-
m_mask = min_bucket_count_in_out - 1;
104-
} else {
105-
m_mask = 0;
106-
}
107-
}
108-
109-
/**
110-
* Return the bucket [0, bucket_count()) to which the hash belongs.
111-
* If bucket_count() is 0, it must always return 0.
112-
*/
113-
std::size_t bucket_for_hash(std::size_t hash) const noexcept {
114-
return hash & m_mask;
115-
}
116-
117-
/**
118-
* Return the number of buckets that should be used on next growth.
119-
*/
120-
std::size_t next_bucket_count() const {
121-
if ((m_mask + 1) > max_bucket_count() / GrowthFactor) {
122-
TSL_RH_THROW_OR_TERMINATE(
123-
std::length_error, "The hash table exceeds its maximum size.");
110+
/**
111+
* Return the bucket [0, bucket_count()) to which the hash belongs.
112+
* If bucket_count() is 0, it must always return 0.
113+
*/
114+
std::size_t bucket_for_hash(std::size_t hash) const noexcept {
115+
return hash & m_mask;
124116
}
125117

126-
return (m_mask + 1) * GrowthFactor;
127-
}
128-
129-
/**
130-
* Return the maximum number of buckets supported by the policy.
131-
*/
132-
std::size_t max_bucket_count() const {
133-
// Largest power of two.
134-
return (std::numeric_limits<std::size_t>::max() / 2) + 1;
135-
}
136-
137-
/**
138-
* Reset the growth policy as if it was created with a bucket count of 0.
139-
* After a clear, the policy must always return 0 when bucket_for_hash is
140-
* called.
141-
*/
142-
void clear() noexcept {
143-
m_mask = 0;
144-
}
145-
146-
private:
147-
static std::size_t round_up_to_power_of_two(std::size_t value) {
148-
if (is_power_of_two(value)) {
149-
return value;
118+
/**
119+
* Return the number of buckets that should be used on next growth.
120+
*/
121+
std::size_t next_bucket_count() const {
122+
if ((m_mask + 1) > max_bucket_count() / GrowthFactor) {
123+
TSL_RH_THROW_OR_TERMINATE(
124+
std::length_error, "The hash table exceeds its maximum size.");
125+
}
126+
127+
return (m_mask + 1) * GrowthFactor;
150128
}
151129

152-
if (value == 0) {
153-
return 1;
130+
/**
131+
* Return the maximum number of buckets supported by the policy.
132+
*/
133+
std::size_t max_bucket_count() const {
134+
// Largest power of two.
135+
return (std::numeric_limits<std::size_t>::max() / 2) + 1;
154136
}
155137

156-
--value;
157-
for (std::size_t i = 1; i < sizeof(std::size_t) * CHAR_BIT; i *= 2) {
158-
value |= value >> i;
138+
/**
139+
* Reset the growth policy as if it was created with a bucket count of 0.
140+
* After a clear, the policy must always return 0 when bucket_for_hash is
141+
* called.
142+
*/
143+
void clear() noexcept {
144+
m_mask = 0;
159145
}
160146

161-
return value + 1;
162-
}
147+
private:
148+
static std::size_t round_up_to_power_of_two(std::size_t value) {
149+
if (is_power_of_two(value)) {
150+
return value;
151+
}
152+
153+
if (value == 0) {
154+
return 1;
155+
}
156+
157+
--value;
158+
for (std::size_t i = 1; i < sizeof(std::size_t) * CHAR_BIT; i *= 2) {
159+
value |= value >> i;
160+
}
163161

164-
static constexpr bool is_power_of_two(std::size_t value) {
165-
return value != 0 && (value & (value - 1)) == 0;
166-
}
162+
return value + 1;
163+
}
164+
165+
static constexpr bool is_power_of_two(std::size_t value) {
166+
return value != 0 && (value & (value - 1)) == 0;
167+
}
167168

168-
protected:
169-
static_assert(
170-
is_power_of_two(GrowthFactor) && GrowthFactor >= 2,
171-
"GrowthFactor must be a power of two >= 2.");
169+
protected:
170+
static_assert(
171+
is_power_of_two(GrowthFactor) && GrowthFactor >= 2,
172+
"GrowthFactor must be a power of two >= 2.");
172173

173-
std::size_t m_mask;
174+
std::size_t m_mask;
174175
};
175176

176177
/**
@@ -180,64 +181,65 @@ class power_of_two_growth_policy {
180181
*/
181182
template <class GrowthFactor = std::ratio<3, 2>>
182183
class mod_growth_policy {
183-
public:
184-
explicit mod_growth_policy(std::size_t& min_bucket_count_in_out) {
185-
if (min_bucket_count_in_out > max_bucket_count()) {
186-
TSL_RH_THROW_OR_TERMINATE(
187-
std::length_error, "The hash table exceeds its maximum size.");
184+
public:
185+
explicit mod_growth_policy(std::size_t& min_bucket_count_in_out) {
186+
if (min_bucket_count_in_out > max_bucket_count()) {
187+
TSL_RH_THROW_OR_TERMINATE(
188+
std::length_error, "The hash table exceeds its maximum size.");
189+
}
190+
191+
if (min_bucket_count_in_out > 0) {
192+
m_mod = min_bucket_count_in_out;
193+
} else {
194+
m_mod = 1;
195+
}
188196
}
189197

190-
if (min_bucket_count_in_out > 0) {
191-
m_mod = min_bucket_count_in_out;
192-
} else {
193-
m_mod = 1;
198+
std::size_t bucket_for_hash(std::size_t hash) const noexcept {
199+
return hash % m_mod;
194200
}
195-
}
196201

197-
std::size_t bucket_for_hash(std::size_t hash) const noexcept {
198-
return hash % m_mod;
199-
}
200-
201-
std::size_t next_bucket_count() const {
202-
if (m_mod == max_bucket_count()) {
203-
TSL_RH_THROW_OR_TERMINATE(
204-
std::length_error, "The hash table exceeds its maximum size.");
202+
std::size_t next_bucket_count() const {
203+
if (m_mod == max_bucket_count()) {
204+
TSL_RH_THROW_OR_TERMINATE(
205+
std::length_error, "The hash table exceeds its maximum size.");
206+
}
207+
208+
const double next_bucket_count = std::ceil(
209+
double(m_mod) * REHASH_SIZE_MULTIPLICATION_FACTOR);
210+
if (!std::isnormal(next_bucket_count)) {
211+
TSL_RH_THROW_OR_TERMINATE(
212+
std::length_error, "The hash table exceeds its maximum size.");
213+
}
214+
215+
if (next_bucket_count > double(max_bucket_count())) {
216+
return max_bucket_count();
217+
} else {
218+
return std::size_t(next_bucket_count);
219+
}
205220
}
206221

207-
const double next_bucket_count =
208-
std::ceil(double(m_mod) * REHASH_SIZE_MULTIPLICATION_FACTOR);
209-
if (!std::isnormal(next_bucket_count)) {
210-
TSL_RH_THROW_OR_TERMINATE(
211-
std::length_error, "The hash table exceeds its maximum size.");
222+
std::size_t max_bucket_count() const {
223+
return MAX_BUCKET_COUNT;
212224
}
213225

214-
if (next_bucket_count > double(max_bucket_count())) {
215-
return max_bucket_count();
216-
} else {
217-
return std::size_t(next_bucket_count);
226+
void clear() noexcept {
227+
m_mod = 1;
218228
}
219-
}
220-
221-
std::size_t max_bucket_count() const {
222-
return MAX_BUCKET_COUNT;
223-
}
224-
225-
void clear() noexcept {
226-
m_mod = 1;
227-
}
228229

229-
private:
230-
static constexpr double REHASH_SIZE_MULTIPLICATION_FACTOR =
231-
1.0 * GrowthFactor::num / GrowthFactor::den;
232-
static const std::size_t MAX_BUCKET_COUNT = std::size_t(double(
233-
std::numeric_limits<std::size_t>::max() /
234-
REHASH_SIZE_MULTIPLICATION_FACTOR));
230+
private:
231+
static constexpr double
232+
REHASH_SIZE_MULTIPLICATION_FACTOR = 1.0 * GrowthFactor::num /
233+
GrowthFactor::den;
234+
static const std::size_t MAX_BUCKET_COUNT = std::size_t(double(
235+
std::numeric_limits<std::size_t>::max() /
236+
REHASH_SIZE_MULTIPLICATION_FACTOR));
235237

236-
static_assert(
237-
REHASH_SIZE_MULTIPLICATION_FACTOR >= 1.1,
238-
"Growth factor should be >= 1.1.");
238+
static_assert(
239+
REHASH_SIZE_MULTIPLICATION_FACTOR >= 1.1,
240+
"Growth factor should be >= 1.1.");
239241

240-
std::size_t m_mod;
242+
std::size_t m_mod;
241243
};
242244

243245
namespace detail {
@@ -310,7 +312,7 @@ static constexpr const std::array<std::size_t, TSL_RH_NB_PRIMES> PRIMES = {{
310312

311313
template <unsigned int IPrime>
312314
static constexpr std::size_t mod(std::size_t hash) {
313-
return hash % PRIMES[IPrime];
315+
return hash % PRIMES[IPrime];
314316
}
315317

316318
// MOD_PRIME[iprime](hash) returns hash % PRIMES[iprime]. This table allows for
@@ -364,51 +366,53 @@ static constexpr const std::
364366
* * 5' in a 64 bits environment.
365367
*/
366368
class prime_growth_policy {
367-
public:
368-
explicit prime_growth_policy(std::size_t& min_bucket_count_in_out) {
369-
auto it_prime = std::lower_bound(
370-
detail::PRIMES.begin(), detail::PRIMES.end(), min_bucket_count_in_out);
371-
if (it_prime == detail::PRIMES.end()) {
372-
TSL_RH_THROW_OR_TERMINATE(
373-
std::length_error, "The hash table exceeds its maximum size.");
369+
public:
370+
explicit prime_growth_policy(std::size_t& min_bucket_count_in_out) {
371+
auto it_prime = std::lower_bound(
372+
detail::PRIMES.begin(),
373+
detail::PRIMES.end(),
374+
min_bucket_count_in_out);
375+
if (it_prime == detail::PRIMES.end()) {
376+
TSL_RH_THROW_OR_TERMINATE(
377+
std::length_error, "The hash table exceeds its maximum size.");
378+
}
379+
380+
m_iprime = static_cast<unsigned int>(
381+
std::distance(detail::PRIMES.begin(), it_prime));
382+
if (min_bucket_count_in_out > 0) {
383+
min_bucket_count_in_out = *it_prime;
384+
} else {
385+
min_bucket_count_in_out = 0;
386+
}
374387
}
375388

376-
m_iprime = static_cast<unsigned int>(
377-
std::distance(detail::PRIMES.begin(), it_prime));
378-
if (min_bucket_count_in_out > 0) {
379-
min_bucket_count_in_out = *it_prime;
380-
} else {
381-
min_bucket_count_in_out = 0;
389+
std::size_t bucket_for_hash(std::size_t hash) const noexcept {
390+
return detail::MOD_PRIME[m_iprime](hash);
382391
}
383-
}
384392

385-
std::size_t bucket_for_hash(std::size_t hash) const noexcept {
386-
return detail::MOD_PRIME[m_iprime](hash);
387-
}
393+
std::size_t next_bucket_count() const {
394+
if (m_iprime + 1 >= detail::PRIMES.size()) {
395+
TSL_RH_THROW_OR_TERMINATE(
396+
std::length_error, "The hash table exceeds its maximum size.");
397+
}
388398

389-
std::size_t next_bucket_count() const {
390-
if (m_iprime + 1 >= detail::PRIMES.size()) {
391-
TSL_RH_THROW_OR_TERMINATE(
392-
std::length_error, "The hash table exceeds its maximum size.");
399+
return detail::PRIMES[m_iprime + 1];
393400
}
394401

395-
return detail::PRIMES[m_iprime + 1];
396-
}
397-
398-
std::size_t max_bucket_count() const {
399-
return detail::PRIMES.back();
400-
}
402+
std::size_t max_bucket_count() const {
403+
return detail::PRIMES.back();
404+
}
401405

402-
void clear() noexcept {
403-
m_iprime = 0;
404-
}
406+
void clear() noexcept {
407+
m_iprime = 0;
408+
}
405409

406-
private:
407-
unsigned int m_iprime;
410+
private:
411+
unsigned int m_iprime;
408412

409-
static_assert(
410-
std::numeric_limits<decltype(m_iprime)>::max() >= detail::PRIMES.size(),
411-
"The type of m_iprime is not big enough.");
413+
static_assert(
414+
std::numeric_limits<decltype(m_iprime)>::max() >= detail::PRIMES.size(),
415+
"The type of m_iprime is not big enough.");
412416
};
413417

414418
} // namespace rh

0 commit comments

Comments
 (0)