Skip to content

Commit

Permalink
added tests for smallseq
Browse files Browse the repository at this point in the history
  • Loading branch information
Nimaoth committed Mar 19, 2024
1 parent 747d2de commit 5c8d160
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 10 deletions.
20 changes: 10 additions & 10 deletions src/misc/smallseq.nim
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func getInlineData[T; Count: static int](s: ptr SmallSeq[T, Count]): ptr Uncheck
else:
return cast[ptr UncheckedArray[T]](s.data.inline.arr.addr)

func isInline[T; Count: static int](s: SmallSeq[T, Count]): bool {.inline, raises: [].} =
func isInline*[T; Count: static int](s: SmallSeq[T, Count]): bool {.inline, raises: [].} =
## Returns true if the sequence is stored inline
let tag = cast[ptr uint8](s.addr)[]
return (tag and 1) == 0
Expand Down Expand Up @@ -76,7 +76,7 @@ func `high`*[T; Count: static int](s: SmallSeq[T, Count]): int {.inline, raises:
## Returns the highest valid index of the sequence, or -1 if the sequence is empty
s.len - 1

func `len=`[T; Count: static int](s: var SmallSeq[T, Count], len: int) {.inline, raises: [].} =
func `len=`*[T; Count: static int](s: var SmallSeq[T, Count], len: int) {.inline, raises: [].} =
## Internal: set the length of the sequence
if s.isInline:
when sizeof(T) == 1 and Count <= MAX_COUNT8:
Expand Down Expand Up @@ -174,29 +174,29 @@ proc moveToHeap[T; Count: static int](s: var SmallSeq[T, Count], slack: int) {.r
s.data.heap.arr = heapArr
s.data.heap.capacity = capacity

proc shrink[T; Count: static int](s: var SmallSeq[T, Count], slack: int = 0) {.raises: [].} =
proc shrink*[T; Count: static int](s: var SmallSeq[T, Count], slack: int = 0) {.raises: [].} =
## Try to shrink the capacity of the sequence to fit the current length + `slack`
if s.isInline:
return

let len = s.len
let newCapacity = len + slack
let oldLen = s.len
let newCapacity = oldLen + slack
let capacity = s.data.heap.capacity

if newCapacity <= inlineCapacity(T, Count):
# move to inline
let arr = s.data.heap.arr

s.setInline true
s.len = len
s.len = oldLen
let inlineArr = s.addr.getInlineData

for i in 0..<len:
for i in 0..<oldLen:
inlineArr[i] = arr[i]

dealloc(arr)
assert s.isInline
assert s.len == len
assert s.len == oldLen

elif newCapacity < capacity:
let heapArr = s.data.heap.arr
Expand Down Expand Up @@ -320,7 +320,7 @@ proc delete*[T; Count: static int](s: var SmallSeq[T, Count], slice: Slice[int],
assert newLen >= 0

if s.isInline:
s.shiftLeft(slice.a, reduction)
s.shiftLeft(slice.b + 1, reduction)
s.len = newLen

elif shrink and newLen <= inlineCapacity(T, Count):
Expand All @@ -333,7 +333,7 @@ proc delete*[T; Count: static int](s: var SmallSeq[T, Count], slice: Slice[int],
s.len = newLen

else:
s.shiftLeft(slice.a, reduction)
s.shiftLeft(slice.b + 1, reduction)
s.len = newLen
if shrink:
s.shrink()
Expand Down
139 changes: 139 additions & 0 deletions tests/unit/tsmallseq.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
discard """
action: "run"
cmd: "nim $target --nimblePath:./nimbleDir/simplePkgs $options $file"
timeout: 60
targets: "c"
matrix: ""
"""

import std/[tables, unittest, strformat]
import input

import misc/smallseq


suite "SmallSeq":

proc testAdd[T]() =
var s = initSmallSeq(T, 23)

assert s.isInline
assert s.len == 0

s.add 0

assert s.isInline
assert s.len == 1

for i in 1..22:
s.add i.T

assert s.isInline

assert s.len == 23
assert @(s[0..<23]) == @[0.T, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]

s.add 23

assert not s.isInline
assert s.len == 24

for i in 0..<24:
assert s[i] == i.T

assert @(s[0..<24]) == @[0.T, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]

for i in 24..256:
s.add i.T
assert s[i] == i.T

test "add int8":
testAdd[uint8]()

test "add int32":
testAdd[int32]()

test "inline capacity":
assert initSmallSeq(int8, 10).capacity == 23
assert initSmallSeq(int32, 10).capacity == 10
assert initSmallSeq(int8, 23).capacity == 23
assert initSmallSeq(int32, 23).capacity == 23
assert initSmallSeq(int8, 24).capacity == 24
assert initSmallSeq(int32, 24).capacity == 24

proc testShrink[T]() =
var s = initSmallSeq(T, 30)
for i in 0..<40:
s.add i.T

assert not s.isInline
assert s.len == 40
assert s.capacity == 60

s.shrink(1)

assert not s.isInline
assert s.len == 40
assert s.capacity == 41

s.delete(0..<15, shrink=true)

assert s.isInline
assert s.len == 25
assert s.capacity == 30

test "shrink int8":
testShrink[int8]()

test "shrink int32":
testShrink[int32]()

proc testDelete[T]() =
var s = initSmallSeq(T, 30)
for i in 0..<50:
s.add i.T

assert s.len == 50

for i in 0..s.high:
assert s[i] == i.T

s.delete 10..<15
assert s.len == 45
assert not s.isInline

for i in 0..<10:
assert s[i] == i.T

for i in 10..<45:
assert s[i] == i.T + 5

s.delete 25..<44
assert s.len == 26
assert s.isInline

for i in 0..<10:
assert s[i] == i.T

for i in 10..<25:
assert s[i] == i.T + 5

for i in 25..<s.len:
assert s[i] == i.T + 24

s.delete 0..<10
echo s
assert s.len == 16
assert s.isInline

for i in 0..<15:
assert s[i] == i.T + 15

for i in 15..<s.len:
assert s[i] == i.T + 34

test "delete int8":
testDelete[int8]()

test "delete int32":
testDelete[int32]()

0 comments on commit 5c8d160

Please sign in to comment.