From 29b6dd6196ae73c96cf8beeace9e4ee2d3433bde Mon Sep 17 00:00:00 2001 From: narimiran Date: Tue, 14 Jan 2020 06:23:08 +0100 Subject: [PATCH] Correctly remove a key from CountTable when it is set to zero. (fixes #12813 and #13079) (cherry picked from commit e40dee6162a1ca364da1da2ecab546e0a28778f0) --- lib/pure/collections/tables.nim | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index 6d71774435..c0322394cb 100644 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -2170,6 +2170,19 @@ proc enlarge[A](t: var CountTable[A]) = if t.data[i].val != 0: ctRawInsert(t, n, t.data[i].key, t.data[i].val) swap(t.data, n) +proc remove[A](t: var CountTable[A], key: A) = + var n: seq[tuple[key: A, val: int]] + newSeq(n, len(t.data)) + var removed: bool + for i in countup(0, high(t.data)): + if t.data[i].val != 0: + if t.data[i].key != key: + ctRawInsert(t, n, t.data[i].key, t.data[i].val) + else: + removed = true + swap(t.data, n) + if removed: dec(t.counter) + proc rawGet[A](t: CountTable[A], key: A): int = if t.data.len == 0: return -1 @@ -2242,11 +2255,14 @@ proc `[]=`*[A](t: var CountTable[A], key: A, val: int) = ## value of a key assert(not t.isSorted, "CountTable must not be used after sorting") assert val >= 0 - let h = rawGet(t, key) - if h >= 0: - t.data[h].val = val + if val == 0: + t.remove(key) else: - insertImpl() + let h = rawGet(t, key) + if h >= 0: + t.data[h].val = val + else: + insertImpl() proc inc*[A](t: var CountTable[A], key: A, val: Positive = 1) = ## Increments ``t[key]`` by ``val`` (default: 1). @@ -2959,6 +2975,13 @@ when isMainModule: doAssert t_mut['z'] == 1 doAssert t_mut.hasKey('z') == true + block: #12813 #13079 + var t = toCountTable("abracadabra") + doAssert len(t) == 5 + + t['a'] = 0 # remove a key + doAssert len(t) == 4 + block: var tp: Table[string, string] = initTable[string, string]() doAssert "test1" == tp.getOrDefault("test1", "test1")