24 #ifndef PXR_TSL_ROBIN_GROWTH_POLICY_H
25 #define PXR_TSL_ROBIN_GROWTH_POLICY_H
42 #define pxr_tsl_rh_assert(expr) assert(expr)
44 #define pxr_tsl_rh_assert(expr) (static_cast<void>(0))
51 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || \
52 (defined(_MSC_VER) && defined(_CPPUNWIND))) && \
53 !defined(PXR_TSL_NO_EXCEPTIONS)
54 #define PXR_TSL_RH_THROW_OR_TERMINATE(ex, msg) throw ex(msg)
56 #define PXR_TSL_RH_NO_EXCEPTIONS
58 #define PXR_TSL_RH_THROW_OR_TERMINATE(ex, msg) std::terminate()
61 #define PXR_TSL_RH_THROW_OR_TERMINATE(ex, msg) \
63 std::cerr << msg << std::endl; \
69 #if defined(__GNUC__) || defined(__clang__)
70 #define PXR_TSL_RH_LIKELY(exp) (__builtin_expect(!!(exp), true))
72 #define PXR_TSL_RH_LIKELY(exp) (exp)
75 #define PXR_TSL_RH_UNUSED(x) static_cast<void>(x)
89 template <std::
size_t GrowthFactor>
103 "The hash table exceeds its maximum size.");
106 if (min_bucket_count_in_out > 0) {
107 min_bucket_count_in_out =
108 round_up_to_power_of_two(min_bucket_count_in_out);
109 m_mask = min_bucket_count_in_out - 1;
129 "The hash table exceeds its maximum size.");
132 return (
m_mask + 1) * GrowthFactor;
151 static std::size_t round_up_to_power_of_two(std::size_t
value) {
152 if (is_power_of_two(value)) {
161 for (std::size_t i = 1; i <
sizeof(std::size_t) * CHAR_BIT; i *= 2) {
168 static constexpr
bool is_power_of_two(std::size_t value) {
169 return value != 0 && (value & (value - 1)) == 0;
173 static_assert(is_power_of_two(GrowthFactor) && GrowthFactor >= 2,
174 "GrowthFactor must be a power of two >= 2.");
184 template <
class GrowthFactor = std::ratio<3, 2>>
190 "The hash table exceeds its maximum size.");
193 if (min_bucket_count_in_out > 0) {
194 m_mod = min_bucket_count_in_out;
207 "The hash table exceeds its maximum size.");
211 std::ceil(
double(m_mod) * REHASH_SIZE_MULTIPLICATION_FACTOR);
212 if (!std::isnormal(next_bucket_count)) {
214 "The hash table exceeds its maximum size.");
220 return std::size_t(next_bucket_count);
226 void clear() noexcept { m_mod = 1; }
229 static constexpr
double REHASH_SIZE_MULTIPLICATION_FACTOR =
230 1.0 * GrowthFactor::num / GrowthFactor::den;
231 static const std::size_t MAX_BUCKET_COUNT =
233 REHASH_SIZE_MULTIPLICATION_FACTOR));
235 static_assert(REHASH_SIZE_MULTIPLICATION_FACTOR >= 1.1,
236 "Growth factor should be >= 1.1.");
243 #if SIZE_MAX >= ULLONG_MAX
244 #define PXR_TSL_RH_NB_PRIMES 51
245 #elif SIZE_MAX >= ULONG_MAX
246 #define PXR_TSL_RH_NB_PRIMES 40
248 #define PXR_TSL_RH_NB_PRIMES 23
251 static constexpr
const std::array<std::size_t, PXR_TSL_RH_NB_PRIMES> PRIMES = {{
275 #if SIZE_MAX >= ULONG_MAX
294 #if SIZE_MAX >= ULLONG_MAX
309 template <
unsigned int IPrime>
310 static constexpr std::size_t mod(std::size_t hash) {
311 return hash % PRIMES[IPrime];
317 static constexpr
const std::array<std::size_t (*)(std::size_t),
320 &mod<0>, &mod<1>, &mod<2>, &mod<3>, &mod<4>, &mod<5>,
321 &mod<6>, &mod<7>, &mod<8>, &mod<9>, &mod<10>, &mod<11>,
322 &mod<12>, &mod<13>, &mod<14>, &mod<15>, &mod<16>, &mod<17>,
323 &mod<18>, &mod<19>, &mod<20>, &mod<21>, &mod<22>,
324 #if SIZE_MAX >= ULONG_MAX
325 &mod<23>, &mod<24>, &mod<25>, &mod<26>, &mod<27>, &mod<28>,
326 &mod<29>, &mod<30>, &mod<31>, &mod<32>, &mod<33>, &mod<34>,
327 &mod<35>, &mod<36>, &mod<37>, &mod<38>, &mod<39>,
329 #if SIZE_MAX >= ULLONG_MAX
330 &mod<40>, &mod<41>, &mod<42>, &mod<43>, &mod<44>, &mod<45>,
331 &mod<46>, &mod<47>, &mod<48>, &mod<49>, &mod<50>,
367 auto it_prime = std::lower_bound(
368 detail::PRIMES.
begin(), detail::PRIMES.
end(), min_bucket_count_in_out);
369 if (it_prime == detail::PRIMES.
end()) {
371 "The hash table exceeds its maximum size.");
374 m_iprime =
static_cast<unsigned int>(
376 if (min_bucket_count_in_out > 0) {
377 min_bucket_count_in_out = *it_prime;
379 min_bucket_count_in_out = 0;
384 return detail::MOD_PRIME[m_iprime](hash);
388 if (m_iprime + 1 >= detail::PRIMES.
size()) {
390 "The hash table exceeds its maximum size.");
393 return detail::PRIMES[m_iprime + 1];
398 void clear() noexcept { m_iprime = 0; }
401 unsigned int m_iprime;
403 static_assert(std::numeric_limits<decltype(m_iprime)>::
max() >=
404 detail::PRIMES.
size(),
405 "The type of m_iprime is not big enough.");
std::size_t next_bucket_count() const
std::size_t max_bucket_count() const
std::size_t next_bucket_count() const
GLsizei const GLfloat * value
std::size_t bucket_for_hash(std::size_t hash) const noexcept
std::size_t bucket_for_hash(std::size_t hash) const noexcept
std::size_t next_bucket_count() const
#define PXR_TSL_RH_THROW_OR_TERMINATE(ex, msg)
std::size_t bucket_for_hash(std::size_t hash) const noexcept
power_of_two_growth_policy(std::size_t &min_bucket_count_in_out)
IMATH_HOSTDEVICE constexpr int ceil(T x) IMATH_NOEXCEPT
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
std::size_t max_bucket_count() const
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
#define PXR_NAMESPACE_CLOSE_SCOPE
prime_growth_policy(std::size_t &min_bucket_count_in_out)
std::size_t max_bucket_count() const
SIM_API const UT_StringHolder distance
mod_growth_policy(std::size_t &min_bucket_count_in_out)
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.
#define PXR_TSL_RH_NB_PRIMES