summary refs log tree commit diff stats
path: root/lib/pure/collections/sharedtables.nim
diff options
context:
space:
mode:
authorcheatfate <ka@hardcore.kiev.ua>2016-05-26 15:32:14 +0300
committercheatfate <ka@hardcore.kiev.ua>2016-05-26 15:32:14 +0300
commita2393d0593b07642a80d7ddf1486763747f4d7ff (patch)
treef0164b7bed82be0ac6cffc6dfac58e438867bfa7 /lib/pure/collections/sharedtables.nim
parent301d39b88202f5042198caf26a11d7a6257d5bd9 (diff)
downloadNim-a2393d0593b07642a80d7ddf1486763747f4d7ff.tar.gz
Introduce template withValue()
Diffstat (limited to 'lib/pure/collections/sharedtables.nim')
-rw-r--r--lib/pure/collections/sharedtables.nim53
1 files changed, 53 insertions, 0 deletions
diff --git a/lib/pure/collections/sharedtables.nim b/lib/pure/collections/sharedtables.nim
index 20e1bb7a9..17600b272 100644
--- a/lib/pure/collections/sharedtables.nim
+++ b/lib/pure/collections/sharedtables.nim
@@ -45,6 +45,59 @@ template withLock(t, x: untyped) =
   x
   release(t.lock)
 
+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 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.uid = 1000
+  ##
+  acquire(t.lock)
+  try:
+    var hc: Hash
+    var index = rawGet(t, key, hc)
+    let hasKey = index >= 0
+    if hasKey:
+      var value {.inject.} = addr(t.data[index].val)
+      body
+  finally:
+    release(t.lock)
+
+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 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.uid = 1000
+  ##   do:
+  ##     # block is executed when ``key`` not in ``t``
+  ##     raise newException(KeyError, "Key not found")
+  ##
+  acquire(t.lock)
+  try:
+    var hc: Hash
+    var index = rawGet(t, key, hc)
+    let hasKey = index >= 0
+    if hasKey:
+      var value {.inject.} = addr(t.data[index].val)
+      body1
+    else:
+      body2
+  finally:
+    release(t.lock)
+
 proc mget*[A, B](t: var SharedTable[A, B], key: A): var B =
   ## retrieves the value at ``t[key]``. The value can be modified.
   ## If `key` is not in `t`, the ``KeyError`` exception is raised.