aboutsummaryrefslogtreecommitdiff
path: root/absl/container/internal/raw_hash_set.cc
diff options
context:
space:
mode:
authorAbseil Team <absl-team@google.com>2023-12-19 10:19:12 -0800
committerCopybara-Service <copybara-worker@google.com>2023-12-19 10:20:04 -0800
commit46223c8620c98be44628037e0a21c56182bf4f64 (patch)
tree2d45061b25240c4b03821669196548477ffaa778 /absl/container/internal/raw_hash_set.cc
parent78c2f64873cdff76f6790413b98ed47937b7f2c4 (diff)
downloadabseil-46223c8620c98be44628037e0a21c56182bf4f64.tar.gz
abseil-46223c8620c98be44628037e0a21c56182bf4f64.tar.bz2
abseil-46223c8620c98be44628037e0a21c56182bf4f64.zip
Refactor `EraseMetaOnly` to speed up single group tables.
PiperOrigin-RevId: 592272653 Change-Id: I895c5786555227bdc88ab0a4cce8cf5ba65222a1
Diffstat (limited to 'absl/container/internal/raw_hash_set.cc')
-rw-r--r--absl/container/internal/raw_hash_set.cc35
1 files changed, 22 insertions, 13 deletions
diff --git a/absl/container/internal/raw_hash_set.cc b/absl/container/internal/raw_hash_set.cc
index 6bc5f7bd..9f8ea519 100644
--- a/absl/container/internal/raw_hash_set.cc
+++ b/absl/container/internal/raw_hash_set.cc
@@ -221,26 +221,35 @@ void DropDeletesWithoutResize(CommonFields& common,
common.infoz().RecordRehash(total_probe_length);
}
-void EraseMetaOnly(CommonFields& c, ctrl_t* it, size_t slot_size) {
- assert(IsFull(*it) && "erasing a dangling iterator");
- c.decrement_size();
- const auto index = static_cast<size_t>(it - c.control());
+static bool WasNeverFull(CommonFields& c, size_t index) {
+ if (is_single_group(c.capacity())) {
+ return true;
+ }
const size_t index_before = (index - Group::kWidth) & c.capacity();
- const auto empty_after = Group(it).MaskEmpty();
+ const auto empty_after = Group(c.control() + index).MaskEmpty();
const auto empty_before = Group(c.control() + index_before).MaskEmpty();
// We count how many consecutive non empties we have to the right and to the
// left of `it`. If the sum is >= kWidth then there is at least one probe
// window that might have seen a full group.
- bool was_never_full = empty_before && empty_after &&
- static_cast<size_t>(empty_after.TrailingZeros()) +
- empty_before.LeadingZeros() <
- Group::kWidth;
-
- SetCtrl(c, index, was_never_full ? ctrl_t::kEmpty : ctrl_t::kDeleted,
- slot_size);
- c.set_growth_left(c.growth_left() + (was_never_full ? 1 : 0));
+ return empty_before && empty_after &&
+ static_cast<size_t>(empty_after.TrailingZeros()) +
+ empty_before.LeadingZeros() <
+ Group::kWidth;
+}
+
+void EraseMetaOnly(CommonFields& c, size_t index, size_t slot_size) {
+ assert(IsFull(c.control()[index]) && "erasing a dangling iterator");
+ c.decrement_size();
c.infoz().RecordErase();
+
+ if (WasNeverFull(c, index)) {
+ SetCtrl(c, index, ctrl_t::kEmpty, slot_size);
+ c.set_growth_left(c.growth_left() + 1);
+ return;
+ }
+
+ SetCtrl(c, index, ctrl_t::kDeleted, slot_size);
}
void ClearBackingArray(CommonFields& c, const PolicyFunctions& policy,