From 8951c59f3af9e17b94c181020d8daf2ac508c428 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Wed, 19 Feb 2020 20:45:30 -0800 Subject: [PATCH] fixup --- lib/pure/collections/hashcommon.nim | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/lib/pure/collections/hashcommon.nim b/lib/pure/collections/hashcommon.nim index ab5a4a315e701..8c2ff927894bd 100644 --- a/lib/pure/collections/hashcommon.nim +++ b/lib/pure/collections/hashcommon.nim @@ -42,7 +42,10 @@ proc nextTry(h, maxHash: Hash, perturb: var UHash): Hash {.inline.} = # and then switch to the formula below, to get "best of both worlds": good # cache locality, except when a collision cluster is detected (ie, large number # of iterations). - const PERTURB_SHIFT = 5 # consider tying this to `numBitsMask = fastLog2(t.dataLen)` + + # consider tying this to `numBitsMask = fastLog2(t.dataLen)` + const PERTURB_SHIFT = 5 + result = cast[Hash]((5*cast[uint](h) + 1 + perturb) and cast[uint](maxHash)) perturb = perturb shr PERTURB_SHIFT @@ -75,14 +78,29 @@ template getPerturb(t: typed, hc: Hash): UHash = template findCell(t: typed, hc, mustNextTry): int = let m = maxHash(t) var index: Hash = hc and m - var perturb: UHash = getPerturb(t, hc) + var perturb {.noinit.}: UHash var depth = 0 - const depthThres = 20 # PARAM + + ## PARAM: this param can affect performance and could be exposed to users whoe + ## need to optimize for their specific key distribution. If clusters are to be + ## expected, it's better to set it low; for really random data, it's better to + ## set it high. We pick a sensible default that works across a range of key + ## distributions. + ## + ## depthThres=0 will just use pseudorandom probing + ## depthThres=int.max will just use linear probing + ## depthThres in between will switch + const depthThres = 20 + while mustNextTry(t.data[index], index): depth.inc if depth <= depthThres: + ## linear probing, cache friendly index = (index + 1) and m else: + ## pseudorandom probing, "bad" case was detected + if depth == depthThres + 1: + perturb = getPerturb(t, hc) index = nextTry(index, m, perturb) index