Fixes #75 ("Bug: Rehashing an empty unordered_set with cache_begin set to true hits an assert")

This commit is contained in:
Ion Gaztañaga
2022-06-25 18:32:27 +02:00
parent 05bb58091e
commit 27c00ae498
2 changed files with 21 additions and 7 deletions

View File

@ -1546,6 +1546,9 @@ struct bucket_hash_equal_t
BOOST_INTRUSIVE_FORCEINLINE void priv_set_cache(bucket_ptr)
{}
BOOST_INTRUSIVE_FORCEINLINE void priv_set_cache_bucket_num(std::size_t)
{}
BOOST_INTRUSIVE_FORCEINLINE std::size_t priv_get_cache_bucket_num()
{ return 0u; }
@ -1638,6 +1641,12 @@ struct bucket_hash_equal_t<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrK
BOOST_INTRUSIVE_FORCEINLINE void priv_set_cache(bucket_ptr p)
{ cached_begin_ = p; }
BOOST_INTRUSIVE_FORCEINLINE void priv_set_cache_bucket_num(std::size_t insertion_bucket)
{
BOOST_INTRUSIVE_INVARIANT_ASSERT(insertion_bucket <= this->priv_usable_bucket_count());
this->cached_begin_ = this->priv_bucket_pointer() + std::ptrdiff_t(insertion_bucket);
}
BOOST_INTRUSIVE_FORCEINLINE std::size_t priv_get_cache_bucket_num()
{ return std::size_t(this->cached_begin_ - this->priv_bucket_pointer()); }
@ -3602,9 +3611,8 @@ class hashtable_impl
slist_node_ptr old_bucket_node_ptr = old_buckets[difference_type(n)].get_node_ptr();
slist_node_algorithms::transfer_after(new_bucket_nodeptr, old_bucket_node_ptr);
}
//Put cache to safe position
this->priv_init_cache();
this->priv_insertion_update_cache(ini_n);
//Reset cache to safe position
this->priv_set_cache_bucket_num(ini_n);
}
this->priv_set_sentinel_bucket();
@ -3759,7 +3767,6 @@ class hashtable_impl
this->priv_size_traits().set_size(0);
//Put cache to safe position
this->priv_init_cache();
this->priv_insertion_update_cache(size_type(0u));
this->priv_unset_sentinel_bucket();
const size_type split = this->rehash_split_from_bucket_count(new_bucket_count);
@ -3824,8 +3831,7 @@ class hashtable_impl
if(&new_bucket_traits != &this->priv_bucket_traits())
this->priv_bucket_traits() = new_bucket_traits;
this->priv_set_sentinel_bucket();
this->priv_init_cache();
this->priv_insertion_update_cache(new_first_bucket_num);
this->priv_set_cache_bucket_num(new_first_bucket_num);
rollback1.release();
rollback2.release();
}
@ -3923,7 +3929,7 @@ class hashtable_impl
rollback.release();
this->priv_size_traits().set_size(src.priv_size_traits().get_size());
this->priv_split_traits().set_size(dst_bucket_count);
this->priv_insertion_update_cache(0u);
this->priv_set_cache_bucket_num(0u);
this->priv_erasure_update_cache();
}

View File

@ -635,6 +635,14 @@ void test_unordered<ContainerDefiner>::test_rehash(value_cont_type& values, deta
testset1.full_rehash();
{ int init_values [] = { 1, 2, 2, 3, 4, 5 };
TEST_INTRUSIVE_SEQUENCE_MAYBEUNIQUE( init_values, testset1 ); }
//Test empty rehash
testset1.clear();
testset1.rehash(bucket_traits(
pointer_traits<bucket_ptr>::pointer_to(buckets1[0]), sizeof(buckets1) / sizeof(*buckets1)));
BOOST_TEST(testset1.empty());
testset1.full_rehash();
BOOST_TEST(testset1.empty());
}
//test: find, equal_range (lower_bound, upper_bound):