CountTable: check for usages after sorting (#11189)
This commit is contained in:
parent
d24585c49e
commit
a5fb0acf5f
1 changed files with 10 additions and 1 deletions
|
|
@ -2133,6 +2133,7 @@ type
|
||||||
## <#initCountTable,int>`_.
|
## <#initCountTable,int>`_.
|
||||||
data: seq[tuple[key: A, val: int]]
|
data: seq[tuple[key: A, val: int]]
|
||||||
counter: int
|
counter: int
|
||||||
|
isSorted: bool
|
||||||
CountTableRef*[A] = ref CountTable[A] ## Ref version of
|
CountTableRef*[A] = ref CountTable[A] ## Ref version of
|
||||||
## `CountTable<#CountTable>`_.
|
## `CountTable<#CountTable>`_.
|
||||||
##
|
##
|
||||||
|
|
@ -2209,12 +2210,14 @@ proc `[]`*[A](t: CountTable[A], key: A): int =
|
||||||
## (key, value) pair in the table
|
## (key, value) pair in the table
|
||||||
## * `hasKey proc<#hasKey,CountTable[A],A>`_ for checking if a key
|
## * `hasKey proc<#hasKey,CountTable[A],A>`_ for checking if a key
|
||||||
## is in the table
|
## is in the table
|
||||||
|
assert(not t.isSorted, "CountTable must not be used after sorting")
|
||||||
ctget(t, key, 0)
|
ctget(t, key, 0)
|
||||||
|
|
||||||
proc mget*[A](t: var CountTable[A], key: A): var int =
|
proc mget*[A](t: var CountTable[A], key: A): var int =
|
||||||
## Retrieves the value at ``t[key]``. The value can be modified.
|
## Retrieves the value at ``t[key]``. The value can be modified.
|
||||||
##
|
##
|
||||||
## If ``key`` is not in ``t``, the ``KeyError`` exception is raised.
|
## If ``key`` is not in ``t``, the ``KeyError`` exception is raised.
|
||||||
|
assert(not t.isSorted, "CountTable must not be used after sorting")
|
||||||
get(t, key)
|
get(t, key)
|
||||||
|
|
||||||
proc `[]=`*[A](t: var CountTable[A], key: A, val: int) =
|
proc `[]=`*[A](t: var CountTable[A], key: A, val: int) =
|
||||||
|
|
@ -2224,6 +2227,7 @@ proc `[]=`*[A](t: var CountTable[A], key: A, val: int) =
|
||||||
## * `[] proc<#[],CountTable[A],A>`_ for retrieving a value of a key
|
## * `[] proc<#[],CountTable[A],A>`_ for retrieving a value of a key
|
||||||
## * `inc proc<#inc,CountTable[A],A,int>`_ for incrementing a
|
## * `inc proc<#inc,CountTable[A],A,int>`_ for incrementing a
|
||||||
## value of a key
|
## value of a key
|
||||||
|
assert(not t.isSorted, "CountTable must not be used after sorting")
|
||||||
assert val >= 0
|
assert val >= 0
|
||||||
let h = rawGet(t, key)
|
let h = rawGet(t, key)
|
||||||
if h >= 0:
|
if h >= 0:
|
||||||
|
|
@ -2239,6 +2243,7 @@ proc inc*[A](t: var CountTable[A], key: A, val = 1) =
|
||||||
a.inc('b', 10)
|
a.inc('b', 10)
|
||||||
doAssert a == toCountTable("aaabbbbbbbbbbb")
|
doAssert a == toCountTable("aaabbbbbbbbbbb")
|
||||||
|
|
||||||
|
assert(not t.isSorted, "CountTable must not be used after sorting")
|
||||||
var index = rawGet(t, key)
|
var index = rawGet(t, key)
|
||||||
if index >= 0:
|
if index >= 0:
|
||||||
inc(t.data[index].val, val)
|
inc(t.data[index].val, val)
|
||||||
|
|
@ -2280,6 +2285,7 @@ proc hasKey*[A](t: CountTable[A], key: A): bool =
|
||||||
## * `[] proc<#[],CountTable[A],A>`_ for retrieving a value of a key
|
## * `[] proc<#[],CountTable[A],A>`_ for retrieving a value of a key
|
||||||
## * `getOrDefault proc<#getOrDefault,CountTable[A],A,int>`_ to return
|
## * `getOrDefault proc<#getOrDefault,CountTable[A],A,int>`_ to return
|
||||||
## a custom value if the key doesn't exist
|
## a custom value if the key doesn't exist
|
||||||
|
assert(not t.isSorted, "CountTable must not be used after sorting")
|
||||||
result = rawGet(t, key) >= 0
|
result = rawGet(t, key) >= 0
|
||||||
|
|
||||||
proc contains*[A](t: CountTable[A], key: A): bool =
|
proc contains*[A](t: CountTable[A], key: A): bool =
|
||||||
|
|
@ -2304,6 +2310,7 @@ proc len*[A](t: CountTable[A]): int =
|
||||||
proc clear*[A](t: var CountTable[A]) =
|
proc clear*[A](t: var CountTable[A]) =
|
||||||
## Resets the table so that it is empty.
|
## Resets the table so that it is empty.
|
||||||
clearImpl()
|
clearImpl()
|
||||||
|
t.isSorted = false
|
||||||
|
|
||||||
func ctCmp[T](a, b: tuple[key: T, val: int]): int =
|
func ctCmp[T](a, b: tuple[key: T, val: int]): int =
|
||||||
result = system.cmp(a.val, b.val)
|
result = system.cmp(a.val, b.val)
|
||||||
|
|
@ -2312,7 +2319,7 @@ proc sort*[A](t: var CountTable[A], order = SortOrder.Descending) =
|
||||||
## Sorts the count table so that, by default, the entry with the
|
## Sorts the count table so that, by default, the entry with the
|
||||||
## highest counter comes first.
|
## highest counter comes first.
|
||||||
##
|
##
|
||||||
## **This is destructive! You must not modify ``t`` afterwards!**
|
## **WARNING:** This is destructive! Once sorted, you must not modify ``t`` afterwards!
|
||||||
##
|
##
|
||||||
## You can use the iterators `pairs<#pairs.i,CountTable[A]>`_,
|
## You can use the iterators `pairs<#pairs.i,CountTable[A]>`_,
|
||||||
## `keys<#keys.i,CountTable[A]>`_, and `values<#values.i,CountTable[A]>`_
|
## `keys<#keys.i,CountTable[A]>`_, and `values<#values.i,CountTable[A]>`_
|
||||||
|
|
@ -2327,6 +2334,7 @@ proc sort*[A](t: var CountTable[A], order = SortOrder.Descending) =
|
||||||
doAssert toSeq(a.values) == @[1, 1, 2, 2, 5]
|
doAssert toSeq(a.values) == @[1, 1, 2, 2, 5]
|
||||||
|
|
||||||
t.data.sort(cmp=ctCmp, order=order)
|
t.data.sort(cmp=ctCmp, order=order)
|
||||||
|
t.isSorted = true
|
||||||
|
|
||||||
proc merge*[A](s: var CountTable[A], t: CountTable[A]) =
|
proc merge*[A](s: var CountTable[A], t: CountTable[A]) =
|
||||||
## Merges the second table into the first one (must be declared as `var`).
|
## Merges the second table into the first one (must be declared as `var`).
|
||||||
|
|
@ -2336,6 +2344,7 @@ proc merge*[A](s: var CountTable[A], t: CountTable[A]) =
|
||||||
a.merge(b)
|
a.merge(b)
|
||||||
doAssert a == toCountTable("aaabbbccc")
|
doAssert a == toCountTable("aaabbbccc")
|
||||||
|
|
||||||
|
assert(not s.isSorted, "CountTable must not be used after sorting")
|
||||||
for key, value in t:
|
for key, value in t:
|
||||||
s.inc(key, value)
|
s.inc(key, value)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue