Skip to content
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

Switch to FxHasher hash function in int64hash and bitmix #52496

Closed
wants to merge 10 commits into from
2 changes: 1 addition & 1 deletion base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2593,8 +2593,8 @@ julia> findall(!iszero, A)
julia> d = Dict(:A => 10, :B => -1, :C => 0)
Dict{Symbol, Int64} with 3 entries:
:A => 10
:B => -1
:C => 0
:B => -1

julia> findall(x -> x >= 0, d)
2-element Vector{Symbol}:
Expand Down
6 changes: 3 additions & 3 deletions base/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -393,8 +393,8 @@ julia> let x = 1, y = 2
Base.@locals
end
Dict{Symbol, Any} with 2 entries:
:y => 2
:x => 1
:y => 2

julia> function f(x)
local y
Expand All @@ -409,8 +409,8 @@ julia> function f(x)

julia> f(42)
Dict{Symbol, Any}(:x => 42)
Dict{Symbol, Any}(:i => 1, :x => 42)
Dict{Symbol, Any}(:y => 2, :x => 42)
Dict{Symbol, Any}(:x => 42, :i => 1)
Dict{Symbol, Any}(:x => 42, :y => 2)
```
"""
macro locals()
Expand Down
10 changes: 2 additions & 8 deletions src/support/hashing.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,10 @@ uint32_t int32hash(uint32_t a)
return a;
}

// FxHasher
uint64_t int64hash(uint64_t key)
{
key = (~key) + (key << 21); // key = (key << 21) - key - 1;
key = key ^ (key >> 24);
key = (key + (key << 3)) + (key << 8); // key * 265
key = key ^ (key >> 14);
key = (key + (key << 2)) + (key << 4); // key * 21
key = key ^ (key >> 28);
key = key + (key << 31);
return key;
return key * 0x517cc1b727220a95;
}

uint32_t int64to32hash(uint64_t key)
Expand Down
17 changes: 12 additions & 5 deletions src/support/hashing.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,25 @@ JL_DLLEXPORT uint64_t memhash_seed(const char *buf, size_t n, uint32_t seed) JL_
JL_DLLEXPORT uint32_t memhash32(const char *buf, size_t n) JL_NOTSAFEPOINT;
JL_DLLEXPORT uint32_t memhash32_seed(const char *buf, size_t n, uint32_t seed) JL_NOTSAFEPOINT;

// FxHasher
#ifdef _P64
STATIC_INLINE uint64_t bitmix(uint64_t a, uint64_t b) JL_NOTSAFEPOINT
STATIC_INLINE uint64_t bitmix(uint64_t h, uint64_t a) JL_NOTSAFEPOINT
{
return int64hash(a^bswap_64(b));
h = (h << 5) | (h >> (8*sizeof(h) - 5)); // rotate 5 bits to the left
h ^= a;
h *= 0x517cc1b727220a95;
return h;
}
#else
STATIC_INLINE uint32_t bitmix(uint32_t a, uint32_t b) JL_NOTSAFEPOINT
STATIC_INLINE uint32_t bitmix(uint32_t h, uint32_t a) JL_NOTSAFEPOINT
{
return int64to32hash((((uint64_t)a) << 32) | (uint64_t)b);
h = (h << 5) | (h >> (8*sizeof(h) - 5)); // rotate 5 bits to the left
h ^= a;
h *= 0x9e3779b9;
return h;
}
#endif
#define bitmix(a, b) (bitmix)((uintptr_t)(a), (uintptr_t)(b))
#define bitmix(h, a) (bitmix)((uintptr_t)(h), (uintptr_t)(a))

#ifdef __cplusplus
}
Expand Down