Get rid of delete_nodes

This commit is contained in:
Daniel James
2017-05-06 04:58:57 +01:00
parent 0489069419
commit 6e074d7165
3 changed files with 69 additions and 74 deletions

View File

@ -3021,44 +3021,30 @@ struct table : boost::unordered::detail::functions<typename Types::hasher,
node_allocator_traits::deallocate(node_alloc(), n, 1);
}
std::size_t delete_nodes(link_pointer prev, node_pointer end)
{
BOOST_ASSERT(prev->next_ != end);
std::size_t count = 0;
node_pointer n = next_node(prev);
prev->next_ = end;
do {
node_pointer next = next_node(n);
destroy_node(n);
n = next;
++count;
} while (n != end);
size_ -= count;
return count;
}
void delete_buckets()
{
if (buckets_) {
if (size_)
delete_nodes(get_previous_start(), node_pointer());
node_pointer n =
static_cast<node_pointer>(get_bucket(bucket_count_)->next_);
if (bucket::extra_node) {
node_pointer n =
static_cast<node_pointer>(get_bucket(bucket_count_)->next_);
node_pointer next = next_node(n);
boost::unordered::detail::func::destroy(boost::addressof(*n));
node_allocator_traits::deallocate(node_alloc(), n, 1);
n = next;
}
while (n) {
node_pointer next = next_node(n);
destroy_node(n);
n = next;
}
destroy_buckets();
buckets_ = bucket_pointer();
max_load_ = 0;
size_ = 0;
}
BOOST_ASSERT(!size_);
}
void destroy_buckets()
@ -3104,6 +3090,11 @@ struct table : boost::unordered::detail::functions<typename Types::hasher,
return bucket_index2;
}
////////////////////////////////////////////////////////////////////////
// Clear
void clear_impl();
////////////////////////////////////////////////////////////////////////
// Assignment
@ -3701,9 +3692,12 @@ struct table : boost::unordered::detail::functions<typename Types::hasher,
link_pointer prev = this->find_previous_node(k, bucket_index);
if (!prev)
return 0;
node_pointer end = next_node(next_node(prev));
this->delete_nodes(prev, end);
this->fix_bucket(bucket_index, prev, end);
node_pointer n = next_node(prev);
node_pointer n2 = next_node(n);
prev->next_ = n2;
--size_;
this->fix_bucket(bucket_index, prev, n2);
this->destroy_node(n);
return 1;
}
@ -4082,11 +4076,17 @@ struct table : boost::unordered::detail::functions<typename Types::hasher,
if (!prev)
return 0;
node_pointer first_node = next_node(prev);
node_pointer end = next_group(first_node);
std::size_t deleted_count = this->delete_nodes(prev, end);
this->fix_bucket(bucket_index, prev, end);
std::size_t deleted_count = 0;
node_pointer n = next_node(prev);
do {
node_pointer n2 = next_node(n);
destroy_node(n);
++deleted_count;
n = n2;
} while (n && !n->is_first_in_group());
size_ -= deleted_count;
prev->next_ = n;
this->fix_bucket(bucket_index, prev, n);
return deleted_count;
}
@ -4191,6 +4191,30 @@ struct table : boost::unordered::detail::functions<typename Types::hasher,
}
};
////////////////////////////////////////////////////////////////////////////
// Clear
template <typename Types> inline void table<Types>::clear_impl()
{
if (size_) {
bucket_pointer end = get_bucket(bucket_count_);
for (bucket_pointer it = buckets_; it != end; ++it) {
it->next_ = node_pointer();
}
link_pointer prev = end->first_from_start();
node_pointer n = next_node(prev);
prev->next_ = node_pointer();
size_ = 0;
while (n) {
node_pointer next = next_node(n);
destroy_node(n);
n = next;
}
}
}
////////////////////////////////////////////////////////////////////////////
// Reserve & Rehash
@ -4275,7 +4299,14 @@ inline void table<Types>::rehash_impl(std::size_t num_buckets)
}
BOOST_CATCH(...)
{
delete_nodes(prev, node_pointer());
node_pointer n = next_node(prev);
prev->next_ = node_pointer();
while (n) {
node_pointer next = next_node(n);
destroy_node(n);
--size_;
n = next;
}
BOOST_RETHROW
}
BOOST_CATCH_END

View File

@ -728,7 +728,7 @@ template <class K, class T, class H, class P, class A> class unordered_map
// value_allocator_traits::is_always_equal::value &&
// is_nothrow_move_assignable_v<H> &&
// is_nothrow_move_assignable_v<P>)
void clear() BOOST_NOEXCEPT;
void clear() BOOST_NOEXCEPT { table_.clear_impl(); }
template <typename H2, typename P2>
void merge(boost::unordered_map<K, T, H2, P2, A>& source);
@ -1263,7 +1263,7 @@ template <class K, class T, class H, class P, class A> class unordered_multimap
// value_allocator_traits::is_always_equal::value &&
// is_nothrow_move_assignable_v<H> &&
// is_nothrow_move_assignable_v<P>)
void clear() BOOST_NOEXCEPT;
void clear() BOOST_NOEXCEPT { table_.clear_impl(); }
template <typename H2, typename P2>
void merge(boost::unordered_multimap<K, T, H2, P2, A>& source);
@ -1611,15 +1611,6 @@ void unordered_map<K, T, H, P, A>::swap(unordered_map& other)
table_.swap(other.table_);
}
template <class K, class T, class H, class P, class A>
void unordered_map<K, T, H, P, A>::clear() BOOST_NOEXCEPT
{
if (table_.size_) {
table_.clear_buckets();
table_.delete_nodes(table_.get_previous_start(), node_pointer());
}
}
template <class K, class T, class H, class P, class A>
template <typename H2, typename P2>
void unordered_map<K, T, H, P, A>::merge(
@ -2096,15 +2087,6 @@ void unordered_multimap<K, T, H, P, A>::swap(unordered_multimap& other)
table_.swap(other.table_);
}
template <class K, class T, class H, class P, class A>
void unordered_multimap<K, T, H, P, A>::clear() BOOST_NOEXCEPT
{
if (table_.size_) {
table_.clear_buckets();
table_.delete_nodes(table_.get_previous_start(), node_pointer());
}
}
// observers
template <class K, class T, class H, class P, class A>

View File

@ -447,7 +447,7 @@ template <class T, class H, class P, class A> class unordered_set
// value_allocator_traits::is_always_equal::value &&
// is_nothrow_move_assignable_v<H> &&
// is_nothrow_move_assignable_v<P>)
void clear() BOOST_NOEXCEPT;
void clear() BOOST_NOEXCEPT { table_.clear_impl(); }
template <typename H2, typename P2>
void merge(boost::unordered_set<T, H2, P2, A>& source);
@ -950,7 +950,7 @@ template <class T, class H, class P, class A> class unordered_multiset
// value_allocator_traits::is_always_equal::value &&
// is_nothrow_move_assignable_v<H> &&
// is_nothrow_move_assignable_v<P>)
void clear() BOOST_NOEXCEPT;
void clear() BOOST_NOEXCEPT { table_.clear_impl(); }
template <typename H2, typename P2>
void merge(boost::unordered_multiset<T, H2, P2, A>& source);
@ -1275,15 +1275,6 @@ void unordered_set<T, H, P, A>::swap(unordered_set& other)
table_.swap(other.table_);
}
template <class T, class H, class P, class A>
void unordered_set<T, H, P, A>::clear() BOOST_NOEXCEPT
{
if (table_.size_) {
table_.clear_buckets();
table_.delete_nodes(table_.get_previous_start(), node_pointer());
}
}
// observers
template <class T, class H, class P, class A>
@ -1679,15 +1670,6 @@ void unordered_multiset<T, H, P, A>::swap(unordered_multiset& other)
table_.swap(other.table_);
}
template <class T, class H, class P, class A>
void unordered_multiset<T, H, P, A>::clear() BOOST_NOEXCEPT
{
if (table_.size_) {
table_.clear_buckets();
table_.delete_nodes(table_.get_previous_start(), node_pointer());
}
}
// observers
template <class T, class H, class P, class A>