From ae108f7a567a87188b144d3fe4f99ddf808750de Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Thu, 13 Feb 2020 08:02:20 -0700 Subject: [PATCH] WIP 4 --- lib/pure/collections/hashcommon.nim | 2 +- lib/pure/hashes.nim | 14 +++++++------- tests/collections/thashsets.nim | 12 +++++++++++- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/lib/pure/collections/hashcommon.nim b/lib/pure/collections/hashcommon.nim index ce5ab5809..6281074af 100644 --- a/lib/pure/collections/hashcommon.nim +++ b/lib/pure/collections/hashcommon.nim @@ -52,7 +52,7 @@ proc rawGetKnownHC[X, A](t: X, key: A, hc: Hash): int {.inline.} = rawGetKnownHCImpl() 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. hc = 314159265 # Value doesn't matter; Any non-zero favorite is fine. diff --git a/lib/pure/hashes.nim b/lib/pure/hashes.nim index 111e25382..9a511ce9d 100644 --- a/lib/pure/hashes.nim +++ b/lib/pure/hashes.nim @@ -117,11 +117,11 @@ const defaultSeedB = (1734880652122947187'u64).uint 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*( x: int, - targetBits = sizeof(uint).uint32, + targetBits: SomeUnsignedInt = sizeof(uint), seedA = defaultSeedA, seedB = defaultSeedB ): Hash {.inline.} = @@ -130,7 +130,7 @@ proc hash*( proc hash*( x: int64, - targetBits = sizeof(uint).uint32, + targetBits: SomeUnsignedInt = sizeof(uint), seedA = defaultSeedA, seedB = defaultSeedB ): Hash {.inline.} = @@ -139,7 +139,7 @@ proc hash*( proc hash*( x: uint, - targetBits = sizeof(uint).uint32, + targetBits: SomeUnsignedInt = sizeof(uint), seedA = defaultSeedA, seedB = defaultSeedB ): Hash {.inline.} = @@ -148,7 +148,7 @@ proc hash*( proc hash*( x: uint64, - targetBits = sizeof(uint).uint32, + targetBits: SomeUnsignedInt = sizeof(uint), seedA = defaultSeedA, seedB = defaultSeedB ): Hash {.inline.} = @@ -157,7 +157,7 @@ proc hash*( proc hash*( x: char, - targetBits = sizeof(uint).uint32, + targetBits: SomeUnsignedInt = sizeof(uint), seedA = defaultSeedA, seedB = defaultSeedB ): Hash {.inline.} = @@ -166,7 +166,7 @@ proc hash*( proc hash*[T: Ordinal]( x: T, - targetBits = sizeof(uint).uint32, + targetBits: SomeUnsignedInt = sizeof(uint), seedA = defaultSeedA, seedB = defaultSeedB ): Hash {.inline.} = diff --git a/tests/collections/thashsets.nim b/tests/collections/thashsets.nim index cd4401511..bccf4654f 100644 --- a/tests/collections/thashsets.nim +++ b/tests/collections/thashsets.nim @@ -1,4 +1,4 @@ -import sets, hashes, algorithm +import sets, hashes, algorithm, bitops block setEquality: @@ -120,3 +120,13 @@ block hashForOrderdSet: reversed = !$reversed doAssert hash(r) == 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)