Commit 116f0af9 by Evan Brown Committed by Copybara-Service

Optimize raw_hash_set::AssertHashEqConsistent a bit to avoid having as much runtime overhead.

PiperOrigin-RevId: 664999751
Change-Id: I6f908cc1b8de8a6a11bb1e02cca761df6aae4e07
parent 8bb5dc43
...@@ -682,6 +682,7 @@ cc_library( ...@@ -682,6 +682,7 @@ cc_library(
":common", ":common",
":compressed_tuple", ":compressed_tuple",
":container_memory", ":container_memory",
":hash_function_defaults",
":hash_policy_traits", ":hash_policy_traits",
":hashtable_debug_hooks", ":hashtable_debug_hooks",
":hashtablez_sampler", ":hashtablez_sampler",
......
...@@ -755,6 +755,7 @@ absl_cc_library( ...@@ -755,6 +755,7 @@ absl_cc_library(
absl::dynamic_annotations absl::dynamic_annotations
absl::endian absl::endian
absl::hash absl::hash
absl::hash_function_defaults
absl::hash_policy_traits absl::hash_policy_traits
absl::hashtable_debug_hooks absl::hashtable_debug_hooks
absl::hashtablez_sampler absl::hashtablez_sampler
......
...@@ -190,6 +190,7 @@ ...@@ -190,6 +190,7 @@
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
#include <functional>
#include <initializer_list> #include <initializer_list>
#include <iterator> #include <iterator>
#include <limits> #include <limits>
...@@ -210,9 +211,11 @@ ...@@ -210,9 +211,11 @@
#include "absl/container/internal/common.h" // IWYU pragma: export // for node_handle #include "absl/container/internal/common.h" // IWYU pragma: export // for node_handle
#include "absl/container/internal/compressed_tuple.h" #include "absl/container/internal/compressed_tuple.h"
#include "absl/container/internal/container_memory.h" #include "absl/container/internal/container_memory.h"
#include "absl/container/internal/hash_function_defaults.h"
#include "absl/container/internal/hash_policy_traits.h" #include "absl/container/internal/hash_policy_traits.h"
#include "absl/container/internal/hashtable_debug_hooks.h" #include "absl/container/internal/hashtable_debug_hooks.h"
#include "absl/container/internal/hashtablez_sampler.h" #include "absl/container/internal/hashtablez_sampler.h"
#include "absl/hash/hash.h"
#include "absl/memory/memory.h" #include "absl/memory/memory.h"
#include "absl/meta/type_traits.h" #include "absl/meta/type_traits.h"
#include "absl/numeric/bits.h" #include "absl/numeric/bits.h"
...@@ -3893,6 +3896,16 @@ class raw_hash_set { ...@@ -3893,6 +3896,16 @@ class raw_hash_set {
// meaning that `eq(k1, k2)` implies `hash(k1)==hash(k2)`. // meaning that `eq(k1, k2)` implies `hash(k1)==hash(k2)`.
template <class K> template <class K>
void AssertHashEqConsistent(const K& key) { void AssertHashEqConsistent(const K& key) {
// If the hash/eq functors are known to be consistent, then skip validation.
if (std::is_same<hasher, absl::container_internal::StringHash>::value &&
std::is_same<key_equal, absl::container_internal::StringEq>::value) {
return;
}
if (std::is_scalar<key_type>::value &&
std::is_same<hasher, absl::Hash<key_type>>::value &&
std::is_same<key_equal, std::equal_to<key_type>>::value) {
return;
}
if (empty()) return; if (empty()) return;
const size_t hash_of_arg = hash_ref()(key); const size_t hash_of_arg = hash_ref()(key);
...@@ -3904,21 +3917,8 @@ class raw_hash_set { ...@@ -3904,21 +3917,8 @@ class raw_hash_set {
const size_t hash_of_slot = const size_t hash_of_slot =
PolicyTraits::apply(HashElement{hash_ref()}, element); PolicyTraits::apply(HashElement{hash_ref()}, element);
const bool is_hash_equal = hash_of_arg == hash_of_slot; ABSL_ATTRIBUTE_UNUSED const bool is_hash_equal =
if (!is_hash_equal) { hash_of_arg == hash_of_slot;
// In this case, we're going to crash. Do a couple of other checks for
// idempotence issues. Recalculating hash/eq here is also convenient for
// debugging with gdb/lldb.
ABSL_ATTRIBUTE_UNUSED const size_t once_more_hash_arg = hash_ref()(key);
assert(hash_of_arg == once_more_hash_arg && "hash is not idempotent.");
ABSL_ATTRIBUTE_UNUSED const size_t once_more_hash_slot =
PolicyTraits::apply(HashElement{hash_ref()}, element);
assert(hash_of_slot == once_more_hash_slot &&
"hash is not idempotent.");
ABSL_ATTRIBUTE_UNUSED const bool once_more_eq =
PolicyTraits::apply(EqualElement<K>{key, eq_ref()}, element);
assert(is_key_equal == once_more_eq && "equality is not idempotent.");
}
assert((!is_key_equal || is_hash_equal) && assert((!is_key_equal || is_hash_equal) &&
"eq(k1, k2) must imply that hash(k1) == hash(k2). " "eq(k1, k2) must imply that hash(k1) == hash(k2). "
"hash/eq functors are inconsistent."); "hash/eq functors are inconsistent.");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment