sharedtables
Shared table support for Nim. Use plain old non GC'ed keys and values or you'll be in trouble. Uses a single lock to protect the table, lockfree implementations welcome but if lock contention is so high that you need a lockfree hash table, you're doing it wrong.
Unstable API.
Imports
Types
SharedTable[A; B] = object data: KeyValuePairSeq[A, B] counter, dataLen: int lock: Lock
- generic hash SharedTable Source Edit
Procs
proc rightSize(count: Natural): int {...}{.inline, deprecated: "Deprecated since 1.4.0", raises: [], tags: [].}
-
Deprecated since Nim v1.4.0, it is not needed anymore because picking the correct size is done internally.
Return the value of
initialSize
to supportcount
items.If more items are expected to be added, simply add that expected extra amount to the parameter before calling this.
Source Edit proc mget[A, B](t: var SharedTable[A, B]; key: A): var B
- retrieves the value at
t[key]
. The value can be modified. Ifkey
is not int
, theKeyError
exception is raised. Source Edit proc mgetOrPut[A, B](t: var SharedTable[A, B]; key: A; val: B): var B
- retrieves value at
t[key]
or putsval
if not present, either way returning a value which can be modified. Note: This is inherently unsafe in the context of multi-threading since it returns a pointer toB
. Source Edit proc hasKeyOrPut[A, B](t: var SharedTable[A, B]; key: A; val: B): bool
- returns true if
key
is in the table, otherwise insertsvalue
. Source Edit proc withKey[A, B](t: var SharedTable[A, B]; key: A; mapper: proc (key: A; val: var B; pairExists: var bool))
-
Computes a new mapping for the
key
with the specifiedmapper
procedure.The
mapper
takes 3 arguments:-
key
- the current key, if it exists, or the key passed towithKey
otherwise; -
val
- the current value, if the key exists, or default value of the type otherwise; -
pairExists
-true
if the key exists,false
otherwise.
The
mapper
can can modifyval
andpairExists
values to change the mapping of the key or delete it from the table. When adding a value, make sure to setpairExists
totrue
along with modifying theval
.The operation is performed atomically and other operations on the table will be blocked while the
mapper
is invoked, so it should be short and simple.Example usage:
# If value exists, decrement it. # If it becomes zero or less, delete the key t.withKey(1'i64) do (k: int64, v: var int, pairExists: var bool): if pairExists: dec v if v <= 0: pairExists = false
Source Edit -
proc `[]=`[A, B](t: var SharedTable[A, B]; key: A; val: B)
- puts a (key, value)-pair into
t
. Source Edit proc add[A, B](t: var SharedTable[A, B]; key: A; val: B)
- puts a new (key, value)-pair into
t
even ift[key]
already exists. This can introduce duplicate keys into the table! Source Edit proc del[A, B](t: var SharedTable[A, B]; key: A)
- deletes
key
from hash tablet
. Source Edit proc len[A, B](t: var SharedTable[A, B]): int
- number of elements in
t
Source Edit proc init[A, B](t: var SharedTable[A, B]; initialSize = 32)
-
creates a new hash table that is empty.
This proc must be called before any other usage of
Source Editt
. proc deinitSharedTable[A, B](t: var SharedTable[A, B])
- Source Edit
Templates
template withValue[A; B](t: var SharedTable[A, B]; key: A; value, body: untyped)
- retrieves the value at
t[key]
.value
can be modified in the scope of thewithValue
call.sharedTable.withValue(key, value) do: # block is executed only if ``key`` in ``t`` # value is threadsafe in block value.name = "username" value.uid = 1000
Source Edit template withValue[A; B](t: var SharedTable[A, B]; key: A; value, body1, body2: untyped)
- retrieves the value at
t[key]
.value
can be modified in the scope of thewithValue
call.sharedTable.withValue(key, value) do: # block is executed only if ``key`` in ``t`` # value is threadsafe in block value.name = "username" value.uid = 1000 do: # block is executed when ``key`` not in ``t`` raise newException(KeyError, "Key not found")
Source Edit
© 2006–2021 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/sharedtables.html