faster CountTable sort(), optional SortOrder (#11010)

* use existing sort for CountTable, and
add SortOrder options to CountTable, OrderedTable sort(s)

* add some tests, runnables, etc.

* fix runnable imports
This commit is contained in:
Andy Davidoff 2019-04-16 03:42:54 -04:00 • committed by Andreas Rumpf
commit 01f09567c4
2 changed files with 60 additions and 42 deletions

View file

@ -8,7 +8,7 @@ And we get here
'''
joinable: false
"""
import hashes, sequtils, tables
import hashes, sequtils, tables, algorithm
# test should not be joined because it takes too long.
block tableadds:
@ -274,22 +274,30 @@ block tablesref:
block countTableTest1:
var s = data.toTable
var t = newCountTable[string]()
for k in s.keys: t.inc(k)
for k in t.keys: assert t[k] == 1
t.inc("90", 3)
t.inc("12", 2)
t.inc("34", 1)
var r = newCountTable[string]()
for x in [t, r]:
for k in s.keys:
x.inc(k)
assert x[k] == 1
x.inc("90", 3)
x.inc("12", 2)
x.inc("34", 1)
assert t.largest()[0] == "90"
t.sort()
var i = 0
for k, v in t.pairs:
case i
of 0: assert k == "90" and v == 4
of 1: assert k == "12" and v == 3
of 2: assert k == "34" and v == 2
else: break
inc i
r.sort(SortOrder.Ascending)
var ps1 = toSeq t.pairs
var ps2 = toSeq r.pairs
ps2.reverse()
for ps in [ps1, ps2]:
var i = 0
for (k, v) in ps:
case i
of 0: assert k == "90" and v == 4
of 1: assert k == "12" and v == 3
of 2: assert k == "34" and v == 2
else: break
inc i
block SyntaxTest:
var x = newTable[int, string]({:})
@ -308,13 +316,20 @@ block tablesref:
var t = newOrderedTable[string, int](2)
for key, val in items(data): t[key] = val
for key, val in items(data): assert t[key] == val
t.sort(proc (x, y: tuple[key: string, val: int]): int = cmp(x.key, y.key))
proc cmper(x, y: tuple[key: string, val: int]): int = cmp(x.key, y.key)
t.sort(cmper)
var i = 0
# `pairs` needs to yield in sorted order:
for key, val in pairs(t):
doAssert key == sorteddata[i][0]
doAssert val == sorteddata[i][1]
inc(i)
t.sort(cmper, order=SortOrder.Descending)
i = 0
for key, val in pairs(t):
doAssert key == sorteddata[high(data)-i][0]
doAssert val == sorteddata[high(data)-i][1]
inc(i)
# check that lookup still works:
for key, val in pairs(t):