Keep rehashing if dist_from_ideal_bucket is > DIST_FROM_IDEAL_BUCKET_LIMIT during insertion (fix issue #52)

During insertion a check was done on dist_from_ideal_bucket to be sure
it doesn't becomes bigger than DIST_FROM_IDEAL_BUCKET_LIMIT but this was
only done during the robin swap. A check should also be done beforehand
if we find an empty bucket otherwise the variable could overflow and
lead to bugs. This commit adds this check.
This commit is contained in:
Tessil
2022-12-29 17:42:54 +00:00
parent 6775231bbf
commit 599df9dfc0

View File

@@ -1231,7 +1231,7 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy {
dist_from_ideal_bucket++;
}
if (rehash_on_extreme_load()) {
while (rehash_on_extreme_load(dist_from_ideal_bucket)) {
ibucket = bucket_for_hash(hash);
dist_from_ideal_bucket = 0;
@@ -1293,7 +1293,7 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy {
while (!m_buckets[ibucket].empty()) {
if (dist_from_ideal_bucket >
m_buckets[ibucket].dist_from_ideal_bucket()) {
if (dist_from_ideal_bucket >=
if (dist_from_ideal_bucket >
bucket_entry::DIST_FROM_IDEAL_BUCKET_LIMIT) {
/**
* The number of probes is really high, rehash the map on the next
@@ -1379,8 +1379,11 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy {
*
* Return true if the table has been rehashed.
*/
bool rehash_on_extreme_load() {
if (m_grow_on_next_insert || size() >= m_load_threshold) {
bool rehash_on_extreme_load(distance_type curr_dist_from_ideal_bucket) {
if (m_grow_on_next_insert ||
curr_dist_from_ideal_bucket >
bucket_entry::DIST_FROM_IDEAL_BUCKET_LIMIT ||
size() >= m_load_threshold) {
rehash_impl(GrowthPolicy::next_bucket_count());
m_grow_on_next_insert = false;