New hash seeding approach.

There didn't seem to be any issues in practice with the last
approach, but I thought of some other ways things could in theory
interact badly.  This fixes that.
This commit is contained in:
Nathan Vegdahl 2022-07-21 14:18:55 -07:00
parent 570878d052
commit 0df18ce908

View File

@ -1,7 +1,9 @@
/// A fast seedable 32-bit hash function.
pub fn hash_u32(mut n: u32, seed: u32) -> u32 {
n ^= 0xe6fe3beb; // So zero doesn't map to zero.
n ^= seed;
// We rotate the bits of `seed` so it's unlikely to interact with `n`
// in bad ways if they're both e.g. incrementing. The particular
// rotation constant used here isn't special.
n ^= seed.rotate_left(23);
// From https://github.com/skeeto/hash-prospector
n ^= n >> 16;
@ -10,15 +12,17 @@ pub fn hash_u32(mut n: u32, seed: u32) -> u32 {
n = n.wrapping_mul(0xd35a2d97);
n ^= n >> 15;
// We xor by `seed` again in case the first time cancelled out our
// "zero doesn't map to zero" precaution.
n ^ seed
// Xor by a random number so input zero doesn't map to output zero.
// The particular number used here isn't special.
n ^ 0xe6fe3beb
}
/// A fast seedable 64-bit hash function.
pub fn hash_u64(mut n: u64, seed: u64) -> u64 {
n ^= 0x4acc3f27cc712c9d; // So zero doesn't map to zero.
n ^= seed;
// We rotate the bits of `seed` so it's unlikely to interact with `n`
// in bad ways if they're both e.g. incrementing. The particular
// rotation constant used here isn't special.
n ^= seed.rotate_left(47);
// From https://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html
n ^= n >> 30;
@ -27,9 +31,9 @@ pub fn hash_u64(mut n: u64, seed: u64) -> u64 {
n = n.wrapping_mul(0x94d049bb133111eb);
n ^= n >> 31;
// We xor by `seed` again in case the first time cancelled out our
// "zero doesn't map to zero" precaution.
n ^ seed
// Xor by a random number so input zero doesn't map to output zero.
// The particular number used here isn't special.
n ^ 0x4acc3f27cc712c9d
}
/// Returns a random float in [0, 1] based on 'n' and a seed.