74 lines
1.8 KiB
Julia
74 lines
1.8 KiB
Julia
# This file is a part of Julia. License is MIT: https://julialang.org/license
|
|
|
|
## hashing a single value ##
|
|
|
|
hash(x::Any) = hash(x, zero(UInt))
|
|
hash(w::WeakRef, h::UInt) = hash(w.value, h)
|
|
|
|
## hashing general objects ##
|
|
|
|
hash(x::ANY, h::UInt) = hash_uint(3h - object_id(x))
|
|
|
|
## core data hashing functions ##
|
|
|
|
function hash_64_64(n::UInt64)
|
|
local a::UInt64 = n
|
|
a = ~a + a << 21
|
|
a = a ⊻ a >> 24
|
|
a = a + a << 3 + a << 8
|
|
a = a ⊻ a >> 14
|
|
a = a + a << 2 + a << 4
|
|
a = a ⊻ a >> 28
|
|
a = a + a << 31
|
|
return a
|
|
end
|
|
|
|
function hash_64_32(n::UInt64)
|
|
local a::UInt64 = n
|
|
a = ~a + a << 18
|
|
a = a ⊻ a >> 31
|
|
a = a * 21
|
|
a = a ⊻ a >> 11
|
|
a = a + a << 6
|
|
a = a ⊻ a >> 22
|
|
return a % UInt32
|
|
end
|
|
|
|
function hash_32_32(n::UInt32)
|
|
local a::UInt32 = n
|
|
a = a + 0x7ed55d16 + a << 12
|
|
a = a ⊻ 0xc761c23c ⊻ a >> 19
|
|
a = a + 0x165667b1 + a << 5
|
|
a = a + 0xd3a2646c ⊻ a << 9
|
|
a = a + 0xfd7046c5 + a << 3
|
|
a = a ⊻ 0xb55a4f09 ⊻ a >> 16
|
|
return a
|
|
end
|
|
|
|
if UInt === UInt64
|
|
hash_uint64(x::UInt64) = hash_64_64(x)
|
|
hash_uint(x::UInt) = hash_64_64(x)
|
|
else
|
|
hash_uint64(x::UInt64) = hash_64_32(x)
|
|
hash_uint(x::UInt) = hash_32_32(x)
|
|
end
|
|
|
|
## symbol & expression hashing ##
|
|
|
|
if UInt === UInt64
|
|
hash(x::Expr, h::UInt) = hash(x.args, hash(x.head, h + 0x83c7900696d26dc6))
|
|
else
|
|
hash(x::Expr, h::UInt) = hash(x.args, hash(x.head, h + 0x96d26dc6))
|
|
end
|
|
|
|
hash(x::QuoteNode, h::UInt) = hash(x.value, hash(QuoteNode, h))
|
|
|
|
# hashing ranges by component at worst leads to collisions for very similar ranges
|
|
const hashr_seed = UInt === UInt64 ? 0x80707b6821b70087 : 0x21b70087
|
|
function hash(r::Range, h::UInt)
|
|
h += hashr_seed
|
|
h = hash(first(r), h)
|
|
h = hash(step(r), h)
|
|
h = hash(last(r), h)
|
|
end
|