Skip to content

Commit

Permalink
Simplify clear() and avoid iterating when values have trivial destr…
Browse files Browse the repository at this point in the history
…uctor.

Resolves #205.
  • Loading branch information
greg7mdp committed Sep 2, 2023
1 parent df7935a commit 38ded9b
Showing 1 changed file with 16 additions and 17 deletions.
33 changes: 16 additions & 17 deletions parallel_hashmap/phmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -1268,21 +1268,15 @@ class raw_hash_set
size_t max_size() const { return (std::numeric_limits<size_t>::max)(); }

PHMAP_ATTRIBUTE_REINITIALIZES void clear() {
// Iterating over this container is O(bucket_count()). When bucket_count()
// is much greater than size(), iteration becomes prohibitively expensive.
// For clear() it is more important to reuse the allocated array when the
// container is small because allocation takes comparatively long time
// compared to destruction of the elements of the container. So we pick the
// largest bucket_count() threshold for which iteration is still fast and
// past that we simply deallocate the array.
if (empty())
return;
if (capacity_ > 127) {
destroy_slots();
} else if (capacity_) {
for (size_t i = 0; i != capacity_; ++i) {
if (IsFull(ctrl_[i])) {
PolicyTraits::destroy(&alloc_ref(), slots_ + i);
if (capacity_) {
if constexpr (!std::is_trivially_destructible<typename PolicyTraits::value_type>::value) {
// not trivially destructible... we need to iterate and destroy values one by one
for (size_t i = 0; i != capacity_; ++i) {
if (IsFull(ctrl_[i])) {
PolicyTraits::destroy(&alloc_ref(), slots_ + i);
}
}
}
size_ = 0;
Expand Down Expand Up @@ -2011,10 +2005,15 @@ class raw_hash_set
}

void destroy_slots() {
if (!capacity_) return;
for (size_t i = 0; i != capacity_; ++i) {
if (IsFull(ctrl_[i])) {
PolicyTraits::destroy(&alloc_ref(), slots_ + i);
if (!capacity_)
return;

if constexpr (!std::is_trivially_destructible<typename PolicyTraits::value_type>::value) {
// not trivially destructible... we need to iterate and destroy values one by one
for (size_t i = 0; i != capacity_; ++i) {
if (IsFull(ctrl_[i])) {
PolicyTraits::destroy(&alloc_ref(), slots_ + i);
}
}
}
auto layout = MakeLayout(capacity_);
Expand Down

0 comments on commit 38ded9b

Please sign in to comment.