Skip to content

Commit ccef362

Browse files
committed
slightly improve _hash_fib and extract hash_shaped
1 parent 1c1fbff commit ccef362

File tree

1 file changed

+9
-9
lines changed

1 file changed

+9
-9
lines changed

base/multidimensional.jl

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2002,7 +2002,7 @@ setindex!(b::Ref, x, ::CartesianIndex{0}) = setindex!(b, x)
20022002

20032003
## hashing AbstractArray ## can't be put in abstractarray.jl due to bootstrapping problems with the use of @nexpr
20042004

2005-
function _hash_fib(A::AbstractArray, h::UInt)
2005+
function _hash_fib(A, h::UInt)
20062006
# Goal: Hash approximately log(N) entries with a higher density of hashed elements
20072007
# weighted towards the end and special consideration for repeated values. Colliding
20082008
# hashes will often subsequently be compared by equality -- and equality between arrays
@@ -2029,16 +2029,16 @@ function _hash_fib(A::AbstractArray, h::UInt)
20292029
linidx = key_to_linear[keyidx]
20302030
fibskip = prevfibskip = oneunit(linidx)
20312031
first_linear = first(LinearIndices(linear_to_key))
2032-
@nexprs 8 i -> p_i = h
2032+
@nexprs 4 i -> p_i = h
20332033

20342034
n = 0
20352035
while true
20362036
n += 1
20372037
# Hash the element
20382038
elt = A[keyidx]
20392039

2040-
stream_idx = mod1(n, 8)
2041-
@nexprs 8 i -> stream_idx == i && (p_i = hash(keyidx => elt, p_i))
2040+
stream_idx = mod1(n, 4)
2041+
@nexprs 4 i -> stream_idx == i && (p_i = hash_mix_linear(hash(keyidx, p_i), hash(elt, p_i)))
20422042

20432043
# Skip backwards a Fibonacci number of indices -- this is a linear index operation
20442044
linidx = key_to_linear[keyidx]
@@ -2061,18 +2061,15 @@ function _hash_fib(A::AbstractArray, h::UInt)
20612061
keyidx === nothing && break
20622062
end
20632063

2064-
@nexprs 8 i -> h = hash_mix_linear(p_i, h)
2064+
@nexprs 4 i -> h = hash_mix_linear(p_i, h)
20652065
return hash_uint(h)
20662066
end
20672067

2068-
const hash_abstractarray_seed = UInt === UInt64 ? 0x7e2d6fb6448beb77 : 0xd4514ce5
2069-
function hash(A::AbstractArray, h::UInt)
2070-
h ⊻= hash_abstractarray_seed
2068+
function hash_shaped(A, h::UInt)
20712069
# Axes are themselves AbstractArrays, so hashing them directly would stack overflow
20722070
# Instead hash the tuple of firsts and lasts along each dimension
20732071
h = hash(map(first, axes(A)), h)
20742072
h = hash(map(last, axes(A)), h)
2075-
20762073
len = length(A)
20772074

20782075
if len < 8
@@ -2101,3 +2098,6 @@ function hash(A::AbstractArray, h::UInt)
21012098
return _hash_fib(A, h)
21022099
end
21032100
end
2101+
2102+
const hash_abstractarray_seed = UInt === UInt64 ? 0x7e2d6fb6448beb77 : 0xd4514ce5
2103+
hash(A::AbstractArray, h::UInt) = hash_shaped(A, h hash_abstractarray_seed)

0 commit comments

Comments
 (0)