summary refs log tree commit diff stats
path: root/lib/pure/collections/tables.nim
diff options
context:
space:
mode:
authorCharles Blake <cblake@csail.mit.edu>2015-02-15 10:03:41 -0500
committerCharles Blake <cblake@csail.mit.edu>2015-02-15 10:03:41 -0500
commit7c1c9a6a9d264feb47b5346c1953b8a72862292e (patch)
tree83c5874bf01df0cd0ea72295b7a13d5c7f26cfcb /lib/pure/collections/tables.nim
parentd8c4c576372f63219b90203a71855c93a10ddda3 (diff)
downloadNim-7c1c9a6a9d264feb47b5346c1953b8a72862292e.tar.gz
Add mgetOrPut to support just one probe chase for the common
pattern of either updating or initializing table entries.
Diffstat (limited to 'lib/pure/collections/tables.nim')
-rw-r--r--lib/pure/collections/tables.nim14
1 files changed, 14 insertions, 0 deletions
diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim
index 25fe306c0..96189baff 100644
--- a/lib/pure/collections/tables.nim
+++ b/lib/pure/collections/tables.nim
@@ -257,6 +257,20 @@ when false:
       inc(t.counter)
       result = false
 
+proc mgetOrPut*[A, B](t: var Table[A, B], key: A, value: B): var B =
+  ## retrieves value at ``t[key]`` or puts ``value`` if not present, either way
+  ## returning a value which can be modified.
+  var hc: THash     # If also desired in OrderedTable, lift this into a template
+  var index = rawGet(t, key, hc)
+  if index < 0:                             # not present: insert
+    if mustRehash(len(t.data), t.counter):
+      enlarge(t)
+      index = rawGet(t, key, hc)
+    index = -1 - index
+    rawInsert(t, t.data, key, value, hc, index)
+    inc(t.counter)
+  result = t.data[index].val                # either way return modifiable val
+
 proc `[]=`*[A, B](t: var Table[A, B], key: A, val: B) =
   ## puts a (key, value)-pair into `t`.
   putImpl()