aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbseil Team <absl-team@google.com>2024-01-03 11:41:38 -0800
committerCopybara-Service <copybara-worker@google.com>2024-01-03 11:42:50 -0800
commit98156bb8e0337cc8c2e0480ebc14fee208a2f08c (patch)
tree270a4a1d4aa97a7b71ca32954e90e84e102ce2fc
parent4038192a57cb75f7ee671f81a3378ff4c74c4f8e (diff)
downloadabseil-cpp-98156bb8e0337cc8c2e0480ebc14fee208a2f08c.tar.gz
Speed up `raw_hash_set::contains()` when ABSL hardening is enabled by removing the iterator invalidation check from the comparison that contains performs.
PiperOrigin-RevId: 595460301 Change-Id: I9a5d6c81385e38184f4848c58209adc5d32bb7be
-rw-r--r--absl/container/internal/raw_hash_set.h16
1 files changed, 15 insertions, 1 deletions
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index b7295c84..9c65984d 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -2016,6 +2016,12 @@ class raw_hash_set {
union {
slot_type* slot_;
};
+
+ // An equality check which skips ABSL Hardening iterator invalidation
+ // checks.
+ // Should be used when the lifetimes of the iterators are well-enough
+ // understood to prove that they cannot be invalid.
+ bool unchecked_equals(const iterator& b) { return ctrl_ == b.control(); }
};
class const_iterator {
@@ -2060,6 +2066,10 @@ class raw_hash_set {
slot_type* slot() const { return inner_.slot(); }
iterator inner_;
+
+ bool unchecked_equals(const const_iterator& b) {
+ return inner_.unchecked_equals(b.inner_);
+ }
};
using node_type = node_handle<Policy, hash_policy_traits<Policy>, Alloc>;
@@ -2707,7 +2717,11 @@ class raw_hash_set {
template <class K = key_type>
bool contains(const key_arg<K>& key) const {
- return find(key) != end();
+ // Here neither the iterator returned by `find()` nor `end()` can be invalid
+ // outside of potential thread-safety issues.
+ // `find()`'s return value is constructed, used, and then destructed
+ // all in this context.
+ return !find(key).unchecked_equals(end());
}
template <class K = key_type>