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(
":common",
":compressed_tuple",
":container_memory",
":hash_function_defaults",
":hash_policy_traits",
":hashtable_debug_hooks",
":hashtablez_sampler",
......
......@@ -755,6 +755,7 @@ absl_cc_library(
absl::dynamic_annotations
absl::endian
absl::hash
absl::hash_function_defaults
absl::hash_policy_traits
absl::hashtable_debug_hooks
absl::hashtablez_sampler
......
......@@ -190,6 +190,7 @@
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <functional>
#include <initializer_list>
#include <iterator>
#include <limits>
......@@ -210,9 +211,11 @@
#include "absl/container/internal/common.h" // IWYU pragma: export // for node_handle
#include "absl/container/internal/compressed_tuple.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/hashtable_debug_hooks.h"
#include "absl/container/internal/hashtablez_sampler.h"
#include "absl/hash/hash.h"
#include "absl/memory/memory.h"
#include "absl/meta/type_traits.h"
#include "absl/numeric/bits.h"
......@@ -3893,6 +3896,16 @@ class raw_hash_set {
// meaning that `eq(k1, k2)` implies `hash(k1)==hash(k2)`.
template <class K>
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;
const size_t hash_of_arg = hash_ref()(key);
......@@ -3904,21 +3917,8 @@ class raw_hash_set {
const size_t hash_of_slot =
PolicyTraits::apply(HashElement{hash_ref()}, element);
const bool is_hash_equal = hash_of_arg == hash_of_slot;
if (!is_hash_equal) {
// 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.");
}
ABSL_ATTRIBUTE_UNUSED const bool is_hash_equal =
hash_of_arg == hash_of_slot;
assert((!is_key_equal || is_hash_equal) &&
"eq(k1, k2) must imply that hash(k1) == hash(k2). "
"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