Don't reuse backing array in clear(), except for capacity 1 tables. The motivation is to save memory. PiperOrigin-RevId: 1004850661
diff --git a/absl/container/internal/raw_hash_set.cc b/absl/container/internal/raw_hash_set.cc index 82ec819..baed443 100644 --- a/absl/container/internal/raw_hash_set.cc +++ b/absl/container/internal/raw_hash_set.cc
@@ -803,9 +803,8 @@ // new_ctrl after 2nd store = EHNSEHNEEEE } -// ClearBackingArrayNoReuse clears the backing array and sets the common -// fields to the default values for empty non-allocated tables. -// REQUIRES: c.capacity > policy.soo_capacity. +// Clears the backing array and sets the common fields to the default values for +// empty non-allocated tables. REQUIRES: c.capacity > policy.soo_capacity. void ClearBackingArrayNoReuse(CommonFields& c, const PolicyFunctions& __restrict policy, void* alloc) { @@ -947,6 +946,8 @@ ABSL_ASSUME(cap > 0); } if (c.is_small()) { + // In the small case, we keep the backing array allocation because the + // memory overhead is small compared to the potential benefits of reuse. if (!c.empty()) { if (destroy_slot != nullptr) { destroy_slot(&c, SingleSlotAddress<kSooEnabled>(c)); @@ -960,12 +961,7 @@ } // 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. - ClearBackingArray(c, policy, alloc, /*reuse=*/cap < 128); + ClearBackingArrayNoReuse(c, policy, alloc); } c.set_reserved_growth(0); c.set_reservation_size(0);
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index 49e5b2e..9781b5c 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h
@@ -2265,9 +2265,8 @@ const PolicyFunctions& policy, size_t new_capacity); -// ClearBackingArray clears the backing array, either modifying it in place, -// or creating a new one based on the value of "reuse". -// REQUIRES: c.capacity > MaxSmallCapacity(). +// Clears the backing array, either modifying it in place, or creating a new one +// based on the value of "reuse". REQUIRES: c.capacity > MaxSmallCapacity(). void ClearBackingArray(CommonFields& c, const PolicyFunctions& policy, void* alloc, bool reuse);
diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc index 1268851..65c8886 100644 --- a/absl/container/internal/raw_hash_set_test.cc +++ b/absl/container/internal/raw_hash_set_test.cc
@@ -2074,7 +2074,7 @@ } ASSERT_EQ(capacity, t.capacity()); intptr_t original = reinterpret_cast<intptr_t>(&*t.find(2)); - t.clear(); + t.erase(t.begin(), t.end()); ASSERT_EQ(capacity, t.capacity()); for (size_t i = 0; i < max_size; ++i) { t.insert(i);