fixes a critical tables bug that caused 'enlarge' to crash after 'add'
This commit is contained in:
parent
147c257720
commit
4077050a42
3 changed files with 30 additions and 11 deletions
|
|
@ -35,9 +35,12 @@ proc enlarge[A, B](t: var SharedTable[A, B]) =
|
||||||
t.dataLen = size
|
t.dataLen = size
|
||||||
swap(t.data, n)
|
swap(t.data, n)
|
||||||
for i in 0..<oldSize:
|
for i in 0..<oldSize:
|
||||||
if isFilled(n[i].hcode):
|
let eh = n[i].hcode
|
||||||
var j = -1 - rawGetKnownHC(t, n[i].key, n[i].hcode)
|
if isFilled(eh):
|
||||||
rawInsert(t, t.data, n[i].key, n[i].val, n[i].hcode, j)
|
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)
|
deallocShared(n)
|
||||||
|
|
||||||
template withLock(t, x: untyped) =
|
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,
|
template withValue*[A, B](t: var SharedTable[A, B], key: A,
|
||||||
value, body: untyped) =
|
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.
|
## `value` can be modified in the scope of the ``withValue`` call.
|
||||||
##
|
##
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
|
|
@ -55,7 +58,7 @@ template withValue*[A, B](t: var SharedTable[A, B], key: A,
|
||||||
## sharedTable.withValue(key, value) do:
|
## sharedTable.withValue(key, value) do:
|
||||||
## # block is executed only if ``key`` in ``t``
|
## # block is executed only if ``key`` in ``t``
|
||||||
## # value is threadsafe in block
|
## # value is threadsafe in block
|
||||||
## value.name = "username"
|
## value.name = "username"
|
||||||
## value.uid = 1000
|
## value.uid = 1000
|
||||||
##
|
##
|
||||||
acquire(t.lock)
|
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,
|
template withValue*[A, B](t: var SharedTable[A, B], key: A,
|
||||||
value, body1, body2: untyped) =
|
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.
|
## `value` can be modified in the scope of the ``withValue`` call.
|
||||||
##
|
##
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
##
|
##
|
||||||
## sharedTable.withValue(key, value) do:
|
## sharedTable.withValue(key, value) do:
|
||||||
## # block is executed only if ``key`` in ``t``
|
## # block is executed only if ``key`` in ``t``
|
||||||
## # value is threadsafe in block
|
## # value is threadsafe in block
|
||||||
## value.name = "username"
|
## value.name = "username"
|
||||||
## value.uid = 1000
|
## value.uid = 1000
|
||||||
## do:
|
## do:
|
||||||
## # block is executed when ``key`` not in ``t``
|
## # block is executed when ``key`` not in ``t``
|
||||||
|
|
|
||||||
|
|
@ -270,9 +270,12 @@ proc enlarge[A, B](t: var Table[A, B]) =
|
||||||
newSeq(n, len(t.data) * growthFactor)
|
newSeq(n, len(t.data) * growthFactor)
|
||||||
swap(t.data, n)
|
swap(t.data, n)
|
||||||
for i in countup(0, high(n)):
|
for i in countup(0, high(n)):
|
||||||
if isFilled(n[i].hcode):
|
let eh = n[i].hcode
|
||||||
var j = -1 - rawGetKnownHC(t, n[i].key, n[i].hcode)
|
if isFilled(eh):
|
||||||
rawInsert(t, t.data, n[i].key, n[i].val, n[i].hcode, j)
|
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 =
|
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
|
## retrieves value at ``t[key]`` or puts ``val`` if not present, either way
|
||||||
|
|
|
||||||
13
tests/collections/tableadds.nim
Normal file
13
tests/collections/tableadds.nim
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
discard """
|
||||||
|
output: '''done'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
import tables
|
||||||
|
|
||||||
|
proc main =
|
||||||
|
var tab = newTable[string, string]()
|
||||||
|
for i in 0..1000:
|
||||||
|
tab.add "key", "value " & $i
|
||||||
|
|
||||||
|
main()
|
||||||
|
echo "done"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue