Skip to content

Commit 9f1dcc7

Browse files
ezbrcopybara-github
authored andcommitted
Add a special case for erase(begin(), end()) to reset the control bytes. The motivation is to avoid potentially expanding the table unnecessarily later.
Note: I prefer doing this as a special case in erase(iterator, iterator) rather than special casing erase(iterator) for size==1 because IIUC that changes the time complexity of erase(iterator) from O(1) to O(N) and in pathological cases, it could change loops from O(N) to O(N^2). PiperOrigin-RevId: 549661855 Change-Id: I8603324260f51a98809db32f840ff09f25cf2481
1 parent 89367c6 commit 9f1dcc7

File tree

2 files changed

+18
-4
lines changed

2 files changed

+18
-4
lines changed

absl/container/internal/raw_hash_set.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1910,8 +1910,7 @@ class raw_hash_set {
19101910
// Already guaranteed to be empty; so nothing to do.
19111911
} else {
19121912
destroy_slots();
1913-
ClearBackingArray(common(), GetPolicyFunctions(),
1914-
/*reuse=*/cap < 128);
1913+
ClearBackingArray(common(), GetPolicyFunctions(), /*reuse=*/cap < 128);
19151914
}
19161915
common().set_reserved_growth(0);
19171916
}
@@ -2165,6 +2164,14 @@ class raw_hash_set {
21652164

21662165
iterator erase(const_iterator first,
21672166
const_iterator last) ABSL_ATTRIBUTE_LIFETIME_BOUND {
2167+
// We check for empty first because ClearBackingArray requires that
2168+
// capacity() > 0 as a precondition.
2169+
if (empty()) return end();
2170+
if (first == begin() && last == end()) {
2171+
destroy_slots();
2172+
ClearBackingArray(common(), GetPolicyFunctions(), /*reuse=*/true);
2173+
return end();
2174+
}
21682175
while (first != last) {
21692176
erase(first++);
21702177
}
@@ -2224,8 +2231,7 @@ class raw_hash_set {
22242231
void rehash(size_t n) {
22252232
if (n == 0 && capacity() == 0) return;
22262233
if (n == 0 && size() == 0) {
2227-
ClearBackingArray(common(), GetPolicyFunctions(),
2228-
/*reuse=*/false);
2234+
ClearBackingArray(common(), GetPolicyFunctions(), /*reuse=*/false);
22292235
return;
22302236
}
22312237

absl/container/internal/raw_hash_set_test.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,6 +1093,14 @@ TEST(Table, EraseMaintainsValidIterator) {
10931093
EXPECT_EQ(num_erase_calls, kNumElements);
10941094
}
10951095

1096+
TEST(Table, EraseBeginEnd) {
1097+
IntTable t;
1098+
for (int i = 0; i < 10; ++i) t.insert(i);
1099+
EXPECT_EQ(t.size(), 10);
1100+
t.erase(t.begin(), t.end());
1101+
EXPECT_EQ(t.size(), 0);
1102+
}
1103+
10961104
// Collect N bad keys by following algorithm:
10971105
// 1. Create an empty table and reserve it to 2 * N.
10981106
// 2. Insert N random elements.

0 commit comments

Comments
 (0)