diff options
author | 2024-01-03 11:41:38 -0800 | |
---|---|---|
committer | 2024-01-03 11:42:50 -0800 | |
commit | 98156bb8e0337cc8c2e0480ebc14fee208a2f08c (patch) | |
tree | 270a4a1d4aa97a7b71ca32954e90e84e102ce2fc | |
parent | 4038192a57cb75f7ee671f81a3378ff4c74c4f8e (diff) |
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.h | 16 |
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> |