@@ -30,8 +30,13 @@ julia> hash(10, a) # only use the output of another hash function as the second
30
30
31
31
See also: [`objectid`](@ref), [`Dict`](@ref), [`Set`](@ref).
32
32
"""
33
- hash (data) = hash (data, HASH_SEED)
34
- hash (@nospecialize (data), h:: UInt64 ) = hash (objectid (data), h)
33
+ hash (data:: Any ) = hash (data, HASH_SEED)
34
+ hash (w:: WeakRef , h:: UInt ) = hash (w. value, h)
35
+
36
+ # Types can't be deleted, so marking as total allows the compiler to look up the hash
37
+ hash (T:: Type , h:: UInt ) =
38
+ hash ((Base. @assume_effects :total ccall (:jl_type_hash , UInt, (Any,), T)), h)
39
+ hash (@nospecialize (data), h:: UInt ) = hash (objectid (data), h)
35
40
36
41
function mul_parts (a:: UInt64 , b:: UInt64 )
37
42
p = widemul (a, b)
40
45
hash_mix (a:: UInt64 , b:: UInt64 ) = ⊻ (mul_parts (a, b)... )
41
46
42
47
48
+ function hash_64_64 (data:: UInt64 , seed:: UInt64 , secret:: NTuple{3, UInt64} )
49
+ return data ⊻ hash_mix (data ⊻ hash_mix (seed, secret[1 ]), secret[2 ])
50
+ end
51
+
52
+ hash_64_32 (data:: UInt64 , seed:: UInt64 , secret:: NTuple{3, UInt64} ) =
53
+ hash_64_64 (data, seed, secret) % UInt32
54
+ hash_32_32 (data:: UInt32 , seed:: UInt64 , secret:: NTuple{3, UInt64} ) =
55
+ hash_64_32 (UInt64 (data), seed, secret)
56
+
57
+ if UInt === UInt64
58
+ const hash_uint64 = hash_64_64
59
+ const hash_uint = hash_64_64
60
+ else
61
+ const hash_uint64 = hash_64_32
62
+ const hash_uint = hash_32_32
63
+ end
64
+
65
+ hash (x:: UInt64 , h:: UInt ) = hash_uint64 (promote (x, h)... , HASH_SECRET)
66
+ hash (x:: Int64 , h:: UInt ) = hash (bitcast (UInt64, x), h)
67
+ hash (x:: Union{Bool, Int8, UInt8, Int16, UInt16, Int32, UInt32} , h:: UInt ) = hash (Int64 (x), h)
68
+
69
+ function hash_integer (n:: Integer , h:: UInt )
70
+ h ⊻= hash ((n % UInt) ⊻ h)
71
+ n = abs (n)
72
+ n >>>= sizeof (UInt) << 3
73
+ while n != 0
74
+ h ⊻= hash ((n % UInt) ⊻ h)
75
+ n >>>= sizeof (UInt) << 3
76
+ end
77
+ return h
78
+ end
79
+
80
+ # # symbol & expression hashing ##
81
+ if UInt === UInt64
82
+ hash (x:: Expr , h:: UInt ) = hash (x. args, hash (x. head, h + 0x83c7900696d26dc6 ))
83
+ hash (x:: QuoteNode , h:: UInt ) = hash (x. value, h + 0x2c97bf8b3de87020 )
84
+ else
85
+ hash (x:: Expr , h:: UInt ) = hash (x. args, hash (x. head, h + 0x96d26dc6 ))
86
+ hash (x:: QuoteNode , h:: UInt ) = hash (x. value, h + 0x469d72af )
87
+ end
88
+
89
+ hash (x:: Symbol ) = objectid (x)
90
+
91
+
43
92
load_le (:: Type{T} , ptr:: Ptr{UInt8} , i) where {T <: Union{UInt32, UInt64} } =
44
93
unsafe_load (convert (Ptr{T}, ptr + i - 1 ))
45
94
@@ -49,7 +98,7 @@ function read_small(ptr::Ptr{UInt8}, n::Int)
49
98
UInt64 (unsafe_load (ptr, n))
50
99
end
51
100
52
- function hash (
101
+ function hash_bytes (
53
102
ptr:: Ptr{UInt8} ,
54
103
n:: Int ,
55
104
seed:: UInt64 ,
@@ -119,54 +168,5 @@ function hash(
119
168
return hash_mix (a ⊻ secret[1 ] ⊻ buflen, b ⊻ secret[2 ])
120
169
end
121
170
122
-
123
- function hash_64_64 (data:: UInt64 , seed:: UInt64 , secret:: NTuple{3, UInt64} )
124
- return data ⊻ hash_mix (data ⊻ hash_mix (seed, secret[1 ]), secret[2 ])
125
- end
126
-
127
- hash_64_32 (data:: UInt64 , seed:: UInt64 , secret:: NTuple{3, UInt64} ) =
128
- hash_64_64 (data, seed, secret) % UInt32
129
- hash_32_32 (data:: UInt32 , seed:: UInt64 , secret:: NTuple{3, UInt64} ) =
130
- hash_64_32 (UInt64 (data), seed, secret)
131
-
132
- if UInt === UInt64
133
- const hash_uint64 = hash_64_64
134
- const hash_uint = hash_64_64
135
- else
136
- const hash_uint64 = hash_64_32
137
- const hash_uint = hash_32_32
138
- end
139
-
140
- hash (x:: UInt64 , h:: UInt ) = hash_uint64 (x, h, HASH_SECRET)
141
- hash (x:: Int64 , h:: UInt ) = hash (bitcast (UInt64, x), h)
142
- hash (x:: Union{Bool, Int8, UInt8, Int16, UInt16, Int32, UInt32} , h:: UInt ) = hash (Int64 (x), h)
143
-
144
- function hash_integer (n:: Integer , h:: UInt )
145
- h ⊻= hash ((n % UInt) ⊻ h)
146
- n = abs (n)
147
- n >>>= sizeof (UInt) << 3
148
- while n != 0
149
- h ⊻= hash ((n % UInt) ⊻ h)
150
- n >>>= sizeof (UInt) << 3
151
- end
152
- return h
153
- end
154
-
155
-
156
- if UInt === UInt64
157
- hash (x:: Expr , h:: UInt ) = hash (x. args, hash (x. head, h + 0x83c7900696d26dc6 ))
158
- hash (x:: QuoteNode , h:: UInt ) = hash (x. value, h + 0x2c97bf8b3de87020 )
159
- else
160
- hash (x:: Expr , h:: UInt ) = hash (x. args, hash (x. head, h + 0x96d26dc6 ))
161
- hash (x:: QuoteNode , h:: UInt ) = hash (x. value, h + 0x469d72af )
162
- end
163
-
164
- # hash(data::String, h::UInt64) = hash(length(data), h)
165
- hash (data:: String , h:: UInt64 ) = @assume_effects :total GC. @preserve data hash (pointer (data), sizeof (data), h, HASH_SECRET)
166
-
167
- hash (w:: WeakRef , h:: UInt64 ) = hash (w. value, h)
168
- function hash (T:: Type , h:: UInt64 )
169
- return hash ((Base. @assume_effects :total ccall (:jl_type_hash , UInt, (Any,), T)), h)
170
- end
171
-
172
- hash (x:: Symbol ) = objectid (x)
171
+ hash (data:: String , h:: UInt ) =
172
+ @assume_effects :total GC. @preserve data hash_bytes (pointer (data), sizeof (data), UInt64 (h), HASH_SECRET)
0 commit comments