-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
prevent unnecessary hash
collisions for Pair
#57285
base: master
Are you sure you want to change the base?
Conversation
base/pair.jl
Outdated
const _pairhash_seed = if UInt === UInt64 | ||
0x94cb2bb20a28ce96 | ||
else | ||
0x1f60a087 | ||
end::UInt | ||
hash(p::Pair, h::UInt) = hash(p.second, hash(p.first, hash(_pairhash_seed, h))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, this also passes the new tests while being simpler/cheaper:
const _pairhash_seed = if UInt === UInt64 | |
0x94cb2bb20a28ce96 | |
else | |
0x1f60a087 | |
end::UInt | |
hash(p::Pair, h::UInt) = hash(p.second, hash(p.first, hash(_pairhash_seed, h))) | |
hash(p::Pair, h::UInt) = hash(p.second, hash(p.first, ~h)) |
I think it relies on hash(p.first, ~h) != ~hash(p.first, h)
. Not sure whether it has any other disadvantages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem with this suggestion is that another collection, unrelated to Pair
, could define a hash
method with the same body, resulting in unnecessary collisions between Pair
values and values of this other collection. That's why I used a random seed.
Issue pointed out by foobar_lv2 on Discourse.
Updates #57284