Unordered: Set max_load_ to 0 when there are no buckets.

[SVN r80559]
This commit is contained in:
Daniel James
2012-09-17 18:57:58 +00:00
parent 37d58e84e3
commit c2e7221bf9
2 changed files with 13 additions and 26 deletions

View File

@ -187,7 +187,7 @@ namespace boost { namespace unordered { namespace detail {
std::size_t bucket_count_; std::size_t bucket_count_;
std::size_t size_; std::size_t size_;
float mlf_; float mlf_;
std::size_t max_load_; // Only use if buckets_. std::size_t max_load_;
bucket_pointer buckets_; bucket_pointer buckets_;
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -292,10 +292,10 @@ namespace boost { namespace unordered { namespace detail {
// From 6.3.1/13: // From 6.3.1/13:
// Only resize when size >= mlf_ * count // Only resize when size >= mlf_ * count
max_load_ = boost::unordered::detail::double_to_size(ceil( max_load_ = buckets_ ? boost::unordered::detail::double_to_size(ceil(
static_cast<double>(mlf_) * static_cast<double>(mlf_) *
static_cast<double>(bucket_count_) static_cast<double>(bucket_count_)
)); )) : 0;
} }
@ -303,7 +303,7 @@ namespace boost { namespace unordered { namespace detail {
{ {
BOOST_ASSERT(z > 0); BOOST_ASSERT(z > 0);
mlf_ = (std::max)(z, minimum_max_load_factor); mlf_ = (std::max)(z, minimum_max_load_factor);
if (buckets_) recalculate_max_load(); recalculate_max_load();
} }
std::size_t min_buckets_for_size(std::size_t size) const std::size_t min_buckets_for_size(std::size_t size) const
@ -362,6 +362,7 @@ namespace boost { namespace unordered { namespace detail {
{ {
x.buckets_ = bucket_pointer(); x.buckets_ = bucket_pointer();
x.size_ = 0; x.size_ = 0;
x.max_load_ = 0;
} }
table(table& x, node_allocator const& a, table(table& x, node_allocator const& a,
@ -487,6 +488,7 @@ namespace boost { namespace unordered { namespace detail {
size_ = other.size_; size_ = other.size_;
other.buckets_ = bucket_pointer(); other.buckets_ = bucket_pointer();
other.size_ = 0; other.size_ = 0;
other.max_load_ = 0;
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -536,6 +538,7 @@ namespace boost { namespace unordered { namespace detail {
destroy_buckets(); destroy_buckets();
buckets_ = bucket_pointer(); buckets_ = bucket_pointer();
max_load_ = 0;
} }
BOOST_ASSERT(!size_); BOOST_ASSERT(!size_);
@ -680,7 +683,7 @@ namespace boost { namespace unordered { namespace detail {
if (!size_ && !x.size_) return; if (!size_ && !x.size_) return;
if (!buckets_ || x.size_ >= max_load_) { if (x.size_ >= max_load_) {
create_buckets(min_buckets_for_size(x.size_)); create_buckets(min_buckets_for_size(x.size_));
} }
else { else {
@ -760,7 +763,7 @@ namespace boost { namespace unordered { namespace detail {
if (!size_ && !x.size_) return; if (!size_ && !x.size_) return;
if (!buckets_ || x.size_ >= max_load_) { if (x.size_ >= max_load_) {
create_buckets(min_buckets_for_size(x.size_)); create_buckets(min_buckets_for_size(x.size_));
} }
else { else {
@ -784,9 +787,9 @@ namespace boost { namespace unordered { namespace detail {
boost::unordered::detail::set_hash_functions<hasher, key_equal> boost::unordered::detail::set_hash_functions<hasher, key_equal>
new_func_this(*this, x); new_func_this(*this, x);
// No throw from here. // No throw from here.
move_buckets_from(x);
mlf_ = x.mlf_; mlf_ = x.mlf_;
max_load_ = x.max_load_; max_load_ = x.max_load_;
move_buckets_from(x);
new_func_this.commit(); new_func_this.commit();
} }

View File

@ -466,14 +466,9 @@ namespace boost { namespace unordered { namespace detail {
{ {
node_constructor a(this->node_alloc()); node_constructor a(this->node_alloc());
// Special case for empty buckets so that we can use insert_range_impl2(a, k, i, j);
// max_load_ (which isn't valid when buckets_ is null).
if (!this->buckets_) {
insert_range_empty(a, k, i, j);
if (++i == j) return;
}
do { while(++i != j) {
// Note: can't use get_key as '*i' might not be value_type - it // Note: can't use get_key as '*i' might not be value_type - it
// could be a pair with first_types as key_type without const or // could be a pair with first_types as key_type without const or
// a different second_type. // a different second_type.
@ -483,18 +478,7 @@ namespace boost { namespace unordered { namespace detail {
// be less efficient if copying the full value_type is // be less efficient if copying the full value_type is
// expensive. // expensive.
insert_range_impl2(a, extractor::extract(*i), i, j); insert_range_impl2(a, extractor::extract(*i), i, j);
} while(++i != j); }
}
template <class InputIt>
void insert_range_empty(node_constructor& a, key_type const& k,
InputIt i, InputIt j)
{
std::size_t key_hash = this->hash(k);
a.construct_with_value2(*i);
this->reserve_for_insert(this->size_ +
boost::unordered::detail::insert_size(i, j));
this->add_node(a, key_hash);
} }
template <class InputIt> template <class InputIt>