From 9a9b8e0a7bf5d26977c5a955b7a596a349625da9 Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Thu, 1 Sep 2022 15:12:06 -0700 Subject: [PATCH] Update rehashing implementation to better reflect STL conformance --- include/boost/unordered/detail/fca.hpp | 8 ++++++ .../boost/unordered/detail/implementation.hpp | 25 ++++++++++++------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/include/boost/unordered/detail/fca.hpp b/include/boost/unordered/detail/fca.hpp index 174ff4be..e88faab1 100644 --- a/include/boost/unordered/detail/fca.hpp +++ b/include/boost/unordered/detail/fca.hpp @@ -494,6 +494,14 @@ namespace boost { group_pointer groups; public: + static std::size_t bucket_count_for(std::size_t num_buckets) + { + if (num_buckets == 0) { + return 0; + } + return size_policy::size(size_policy::size_index(num_buckets)); + } + grouped_bucket_array() : empty_value( empty_init_t(), node_allocator_type()), diff --git a/include/boost/unordered/detail/implementation.hpp b/include/boost/unordered/detail/implementation.hpp index 81872612..1dd11ecb 100644 --- a/include/boost/unordered/detail/implementation.hpp +++ b/include/boost/unordered/detail/implementation.hpp @@ -2524,6 +2524,17 @@ namespace boost { new_buckets.insert_node(itnewb, p); } + static std::size_t min_buckets(std::size_t num_elements, float mlf) + { + std::size_t num_buckets = static_cast( + std::ceil(static_cast(num_elements) / mlf)); + + if (num_buckets == 0 && num_elements > 0) { // mlf == inf + num_buckets = 1; + } + return num_buckets; + } + void rehash(std::size_t); void reserve(std::size_t); void reserve_for_insert(std::size_t); @@ -3432,22 +3443,18 @@ namespace boost { template inline void table::rehash(std::size_t num_buckets) { - std::size_t bc = (std::max)(num_buckets, - static_cast(1.0f + static_cast(size_) / mlf_)); + num_buckets = (std::max)( + min_buckets(size_, mlf_), buckets_.bucket_count_for(num_buckets)); - if (bc <= buckets_.bucket_count()) { - return; + if (num_buckets != this->bucket_count()) { + this->rehash_impl(num_buckets); } - - this->rehash_impl(bc); } template inline void table::reserve(std::size_t num_elements) { - std::size_t const num_buckets = static_cast( - std::ceil(static_cast(num_elements) / mlf_)); - + std::size_t num_buckets = min_buckets(num_elements, mlf_); this->rehash(num_buckets); }