WIP 4
This commit is contained in:
parent
b3dad3007c
commit
ae108f7a56
3 changed files with 19 additions and 9 deletions
|
|
@ -52,7 +52,7 @@ proc rawGetKnownHC[X, A](t: X, key: A, hc: Hash): int {.inline.} =
|
||||||
rawGetKnownHCImpl()
|
rawGetKnownHCImpl()
|
||||||
|
|
||||||
template genHashImpl(key, hc: typed) =
|
template genHashImpl(key, hc: typed) =
|
||||||
hc = hash(key, targetBits=lastSetBit(maxHash(t)))
|
hc = hash(key, targetBits=lastSetBit(maxHash(t).uint))
|
||||||
if hc == 0: # This almost never taken branch should be very predictable.
|
if hc == 0: # This almost never taken branch should be very predictable.
|
||||||
hc = 314159265 # Value doesn't matter; Any non-zero favorite is fine.
|
hc = 314159265 # Value doesn't matter; Any non-zero favorite is fine.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -117,11 +117,11 @@ const
|
||||||
defaultSeedB = (1734880652122947187'u64).uint
|
defaultSeedB = (1734880652122947187'u64).uint
|
||||||
|
|
||||||
template computeIntegerHash(x, numBits, seedA, seedB): Hash =
|
template computeIntegerHash(x, numBits, seedA, seedB): Hash =
|
||||||
cast[Hash]((seedA*cast[uint](x) + seedB) shr (sizeof(x)*8 - targetBits*8))
|
cast[Hash]((seedA*cast[uint](x) + seedB) shr (sizeof(x)*8 - numBits*8))
|
||||||
|
|
||||||
proc hash*(
|
proc hash*(
|
||||||
x: int,
|
x: int,
|
||||||
targetBits = sizeof(uint).uint32,
|
targetBits: SomeUnsignedInt = sizeof(uint),
|
||||||
seedA = defaultSeedA,
|
seedA = defaultSeedA,
|
||||||
seedB = defaultSeedB
|
seedB = defaultSeedB
|
||||||
): Hash {.inline.} =
|
): Hash {.inline.} =
|
||||||
|
|
@ -130,7 +130,7 @@ proc hash*(
|
||||||
|
|
||||||
proc hash*(
|
proc hash*(
|
||||||
x: int64,
|
x: int64,
|
||||||
targetBits = sizeof(uint).uint32,
|
targetBits: SomeUnsignedInt = sizeof(uint),
|
||||||
seedA = defaultSeedA,
|
seedA = defaultSeedA,
|
||||||
seedB = defaultSeedB
|
seedB = defaultSeedB
|
||||||
): Hash {.inline.} =
|
): Hash {.inline.} =
|
||||||
|
|
@ -139,7 +139,7 @@ proc hash*(
|
||||||
|
|
||||||
proc hash*(
|
proc hash*(
|
||||||
x: uint,
|
x: uint,
|
||||||
targetBits = sizeof(uint).uint32,
|
targetBits: SomeUnsignedInt = sizeof(uint),
|
||||||
seedA = defaultSeedA,
|
seedA = defaultSeedA,
|
||||||
seedB = defaultSeedB
|
seedB = defaultSeedB
|
||||||
): Hash {.inline.} =
|
): Hash {.inline.} =
|
||||||
|
|
@ -148,7 +148,7 @@ proc hash*(
|
||||||
|
|
||||||
proc hash*(
|
proc hash*(
|
||||||
x: uint64,
|
x: uint64,
|
||||||
targetBits = sizeof(uint).uint32,
|
targetBits: SomeUnsignedInt = sizeof(uint),
|
||||||
seedA = defaultSeedA,
|
seedA = defaultSeedA,
|
||||||
seedB = defaultSeedB
|
seedB = defaultSeedB
|
||||||
): Hash {.inline.} =
|
): Hash {.inline.} =
|
||||||
|
|
@ -157,7 +157,7 @@ proc hash*(
|
||||||
|
|
||||||
proc hash*(
|
proc hash*(
|
||||||
x: char,
|
x: char,
|
||||||
targetBits = sizeof(uint).uint32,
|
targetBits: SomeUnsignedInt = sizeof(uint),
|
||||||
seedA = defaultSeedA,
|
seedA = defaultSeedA,
|
||||||
seedB = defaultSeedB
|
seedB = defaultSeedB
|
||||||
): Hash {.inline.} =
|
): Hash {.inline.} =
|
||||||
|
|
@ -166,7 +166,7 @@ proc hash*(
|
||||||
|
|
||||||
proc hash*[T: Ordinal](
|
proc hash*[T: Ordinal](
|
||||||
x: T,
|
x: T,
|
||||||
targetBits = sizeof(uint).uint32,
|
targetBits: SomeUnsignedInt = sizeof(uint),
|
||||||
seedA = defaultSeedA,
|
seedA = defaultSeedA,
|
||||||
seedB = defaultSeedB
|
seedB = defaultSeedB
|
||||||
): Hash {.inline.} =
|
): Hash {.inline.} =
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import sets, hashes, algorithm
|
import sets, hashes, algorithm, bitops
|
||||||
|
|
||||||
|
|
||||||
block setEquality:
|
block setEquality:
|
||||||
|
|
@ -120,3 +120,13 @@ block hashForOrderdSet:
|
||||||
reversed = !$reversed
|
reversed = !$reversed
|
||||||
doAssert hash(r) == reversed
|
doAssert hash(r) == reversed
|
||||||
doAssert hash(s1) != reversed
|
doAssert hash(s1) != reversed
|
||||||
|
|
||||||
|
block hashDoesntHaveLowerBitsCleared:
|
||||||
|
let num32 = 0xFFFF.uint32
|
||||||
|
let bits = num32.lastBitSet
|
||||||
|
|
||||||
|
let h1 = hash(0xFFFFFFFF00000000'u64, targetBits=bits)
|
||||||
|
let h2 = hash(0x2345123400000000'u64, targetBits=bits)
|
||||||
|
|
||||||
|
|
||||||
|
doAssert (h1 and num32) != (h2 and num32)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue