@@ -2002,7 +2002,7 @@ setindex!(b::Ref, x, ::CartesianIndex{0}) = setindex!(b, x)
2002
2002
2003
2003
# # hashing AbstractArray ## can't be put in abstractarray.jl due to bootstrapping problems with the use of @nexpr
2004
2004
2005
- function _hash_fib (A:: AbstractArray , h:: UInt )
2005
+ function _hash_fib (A, h:: UInt )
2006
2006
# Goal: Hash approximately log(N) entries with a higher density of hashed elements
2007
2007
# weighted towards the end and special consideration for repeated values. Colliding
2008
2008
# hashes will often subsequently be compared by equality -- and equality between arrays
@@ -2029,16 +2029,16 @@ function _hash_fib(A::AbstractArray, h::UInt)
2029
2029
linidx = key_to_linear[keyidx]
2030
2030
fibskip = prevfibskip = oneunit (linidx)
2031
2031
first_linear = first (LinearIndices (linear_to_key))
2032
- @nexprs 8 i -> p_i = h
2032
+ @nexprs 4 i -> p_i = h
2033
2033
2034
2034
n = 0
2035
2035
while true
2036
2036
n += 1
2037
2037
# Hash the element
2038
2038
elt = A[keyidx]
2039
2039
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) ))
2042
2042
2043
2043
# Skip backwards a Fibonacci number of indices -- this is a linear index operation
2044
2044
linidx = key_to_linear[keyidx]
@@ -2061,18 +2061,15 @@ function _hash_fib(A::AbstractArray, h::UInt)
2061
2061
keyidx === nothing && break
2062
2062
end
2063
2063
2064
- @nexprs 8 i -> h = hash_mix_linear (p_i, h)
2064
+ @nexprs 4 i -> h = hash_mix_linear (p_i, h)
2065
2065
return hash_uint (h)
2066
2066
end
2067
2067
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 )
2071
2069
# Axes are themselves AbstractArrays, so hashing them directly would stack overflow
2072
2070
# Instead hash the tuple of firsts and lasts along each dimension
2073
2071
h = hash (map (first, axes (A)), h)
2074
2072
h = hash (map (last, axes (A)), h)
2075
-
2076
2073
len = length (A)
2077
2074
2078
2075
if len < 8
@@ -2101,3 +2098,6 @@ function hash(A::AbstractArray, h::UInt)
2101
2098
return _hash_fib (A, h)
2102
2099
end
2103
2100
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