From b3dad3007c5c534b79edcfbe2438bed389f50a03 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Thu, 13 Feb 2020 06:28:16 -0700 Subject: [PATCH] WIP 3 --- lib/pure/bitops.nim | 9 +++++++++ lib/pure/collections/hashcommon.nim | 11 ++--------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/pure/bitops.nim b/lib/pure/bitops.nim index 9ebdabb7b..e00ea3109 100644 --- a/lib/pure/bitops.nim +++ b/lib/pure/bitops.nim @@ -355,6 +355,15 @@ proc firstSetBit*(x: SomeInteger): int {.inline, noSideEffect.} = when sizeof(x) <= 4: result = firstSetBitNim(x.uint32) else: result = firstSetBitNim(x.uint64) +proc lastSetBit*(x: SomeUnsignedInt): uint {.inline, noSideEffect.} = + ## Returns the 1-based index of the most significant set bit of x. + ## If x == 0, the result will also be 0 + var temp = x + result = 0 + while temp != 0: + temp = temp shr 1 + result += 1 + proc fastLog2*(x: SomeInteger): int {.inline, noSideEffect.} = ## Quickly find the log base 2 of an integer. ## If `x` is zero, when ``noUndefinedBitOpts`` is set, result is -1, diff --git a/lib/pure/collections/hashcommon.nim b/lib/pure/collections/hashcommon.nim index b97b67cb2..ce5ab5809 100644 --- a/lib/pure/collections/hashcommon.nim +++ b/lib/pure/collections/hashcommon.nim @@ -9,6 +9,7 @@ # An ``include`` file which contains common code for # hash sets and tables. +from bitops import lastSetBit const growthFactor = 2 @@ -50,16 +51,8 @@ template rawGetKnownHCImpl() {.dirty.} = proc rawGetKnownHC[X, A](t: X, key: A, hc: Hash): int {.inline.} = rawGetKnownHCImpl() -template bits(n): uint32 = - var temp = n - var bits = 0.uint32 - while temp != 0: - temp = temp shr 1 - bits += 1 - bits - template genHashImpl(key, hc: typed) = - hc = hash(key, targetBits=bits(maxHash(t))) + hc = hash(key, targetBits=lastSetBit(maxHash(t))) if hc == 0: # This almost never taken branch should be very predictable. hc = 314159265 # Value doesn't matter; Any non-zero favorite is fine.