diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2016-09-05 08:51:38 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2016-09-05 08:51:38 +0200 |
commit | 4077050a423973c9d713f67ebf73c94e83392e17 (patch) | |
tree | 5126c83c71a92fee88648525a686a900315d1406 /lib/pure | |
parent | 147c2577200306317b5ba52335293a07b6111444 (diff) | |
download | Nim-4077050a423973c9d713f67ebf73c94e83392e17.tar.gz |
fixes a critical tables bug that caused 'enlarge' to crash after 'add'
Diffstat (limited to 'lib/pure')
-rw-r--r-- | lib/pure/collections/sharedtables.nim | 19 | ||||
-rw-r--r-- | lib/pure/collections/tables.nim | 9 |
2 files changed, 17 insertions, 11 deletions
diff --git a/lib/pure/collections/sharedtables.nim b/lib/pure/collections/sharedtables.nim index 17600b272..7dc338f4e 100644 --- a/lib/pure/collections/sharedtables.nim +++ b/lib/pure/collections/sharedtables.nim @@ -35,9 +35,12 @@ proc enlarge[A, B](t: var SharedTable[A, B]) = t.dataLen = size swap(t.data, n) for i in 0..<oldSize: - if isFilled(n[i].hcode): - var j = -1 - rawGetKnownHC(t, n[i].key, n[i].hcode) - rawInsert(t, t.data, n[i].key, n[i].val, n[i].hcode, j) + let eh = n[i].hcode + if isFilled(eh): + var j: Hash = eh and maxHash(t) + while isFilled(t.data[j].hcode): + j = nextTry(j, maxHash(t)) + rawInsert(t, t.data, n[i].key, n[i].val, eh, j) deallocShared(n) template withLock(t, x: untyped) = @@ -47,7 +50,7 @@ template withLock(t, x: untyped) = template withValue*[A, B](t: var SharedTable[A, B], key: A, value, body: untyped) = - ## retrieves the value at ``t[key]``. + ## retrieves the value at ``t[key]``. ## `value` can be modified in the scope of the ``withValue`` call. ## ## .. code-block:: nim @@ -55,7 +58,7 @@ template withValue*[A, B](t: var SharedTable[A, B], key: A, ## sharedTable.withValue(key, value) do: ## # block is executed only if ``key`` in ``t`` ## # value is threadsafe in block - ## value.name = "username" + ## value.name = "username" ## value.uid = 1000 ## acquire(t.lock) @@ -71,15 +74,15 @@ template withValue*[A, B](t: var SharedTable[A, B], key: A, template withValue*[A, B](t: var SharedTable[A, B], key: A, value, body1, body2: untyped) = - ## retrieves the value at ``t[key]``. + ## retrieves the value at ``t[key]``. ## `value` can be modified in the scope of the ``withValue`` call. - ## + ## ## .. code-block:: nim ## ## sharedTable.withValue(key, value) do: ## # block is executed only if ``key`` in ``t`` ## # value is threadsafe in block - ## value.name = "username" + ## value.name = "username" ## value.uid = 1000 ## do: ## # block is executed when ``key`` not in ``t`` diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index 3f06762ae..9fa8f5263 100644 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -270,9 +270,12 @@ proc enlarge[A, B](t: var Table[A, B]) = newSeq(n, len(t.data) * growthFactor) swap(t.data, n) for i in countup(0, high(n)): - if isFilled(n[i].hcode): - var j = -1 - rawGetKnownHC(t, n[i].key, n[i].hcode) - rawInsert(t, t.data, n[i].key, n[i].val, n[i].hcode, j) + let eh = n[i].hcode + if isFilled(eh): + var j: Hash = eh and maxHash(t) + while isFilled(t.data[j].hcode): + j = nextTry(j, maxHash(t)) + rawInsert(t, t.data, n[i].key, n[i].val, eh, j) proc mgetOrPut*[A, B](t: var Table[A, B], key: A, val: B): var B = ## retrieves value at ``t[key]`` or puts ``val`` if not present, either way |