255 lines
6.4 KiB
Go
255 lines
6.4 KiB
Go
package cursors
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
)
|
|
|
|
func makeIntegerArray(count int, min, max int64) *IntegerArray {
|
|
vals := NewIntegerArrayLen(count)
|
|
|
|
ts := min
|
|
inc := (max - min) / int64(count)
|
|
|
|
for i := 0; i < count; i++ {
|
|
vals.Timestamps[i] = ts
|
|
ts += inc
|
|
}
|
|
|
|
return vals
|
|
}
|
|
|
|
func makeIntegerArrayFromSlice(t []int64) *IntegerArray {
|
|
iv := NewIntegerArrayLen(len(t))
|
|
copy(iv.Timestamps, t)
|
|
return iv
|
|
}
|
|
|
|
func TestIntegerArray_FindRangeNoValues(t *testing.T) {
|
|
var vals IntegerArray
|
|
l, r := vals.FindRange(0, 100)
|
|
if exp := -1; l != exp {
|
|
t.Errorf("invalid l; exp=%d, got=%d", exp, l)
|
|
}
|
|
if exp := -1; r != exp {
|
|
t.Errorf("invalid r; exp=%d, got=%d", exp, r)
|
|
}
|
|
}
|
|
|
|
func TestIntegerArray_FindRange(t *testing.T) {
|
|
vals := makeIntegerArrayFromSlice([]int64{10, 11, 13, 15, 17, 20, 21})
|
|
|
|
cases := []struct {
|
|
min, max int64
|
|
l, r int
|
|
}{
|
|
{12, 20, 2, 5},
|
|
{22, 40, -1, -1},
|
|
{1, 9, -1, -1},
|
|
{1, 10, 0, 0},
|
|
{1, 11, 0, 1},
|
|
{15, 15, 3, 3},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(fmt.Sprintf("%d→%d", tc.min, tc.max), func(t *testing.T) {
|
|
l, r := vals.FindRange(tc.min, tc.max)
|
|
if l != tc.l {
|
|
t.Errorf("left: got %d, exp %d", l, tc.l)
|
|
}
|
|
if r != tc.r {
|
|
t.Errorf("right: got %d, exp %d", r, tc.r)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIntegerArray_Exclude(t *testing.T) {
|
|
cases := []struct {
|
|
n string
|
|
min, max int64
|
|
exp []int64
|
|
}{
|
|
{"excl bad range", 18, 11, []int64{10, 12, 14, 16, 18}},
|
|
{"excl none-lo", 0, 9, []int64{10, 12, 14, 16, 18}},
|
|
{"excl none-hi", 19, 30, []int64{10, 12, 14, 16, 18}},
|
|
{"excl first", 0, 10, []int64{12, 14, 16, 18}},
|
|
{"excl last", 18, 20, []int64{10, 12, 14, 16}},
|
|
{"excl all but first and last", 12, 16, []int64{10, 18}},
|
|
{"excl none in middle", 13, 13, []int64{10, 12, 14, 16, 18}},
|
|
{"excl middle", 14, 14, []int64{10, 12, 16, 18}},
|
|
{"excl suffix", 14, 18, []int64{10, 12}},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(fmt.Sprintf("%s[%d,%d]", tc.n, tc.min, tc.max), func(t *testing.T) {
|
|
vals := makeIntegerArray(5, 10, 20)
|
|
vals.Exclude(tc.min, tc.max)
|
|
got := vals.Timestamps
|
|
if !cmp.Equal(got, tc.exp) {
|
|
t.Errorf("unexpected values -got/+exp\n%s", cmp.Diff(got, tc.exp))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIntegerArray_Include(t *testing.T) {
|
|
cases := []struct {
|
|
n string
|
|
min, max int64
|
|
exp []int64
|
|
}{
|
|
{"incl none-lo", 0, 9, []int64{}},
|
|
{"incl none-hi", 19, 30, []int64{}},
|
|
{"incl first", 0, 10, []int64{10}},
|
|
{"incl last", 18, 20, []int64{18}},
|
|
{"incl all but first and last", 12, 16, []int64{12, 14, 16}},
|
|
{"incl none in middle", 13, 13, []int64{}},
|
|
{"incl middle", 14, 14, []int64{14}},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(fmt.Sprintf("%s[%d,%d]", tc.n, tc.min, tc.max), func(t *testing.T) {
|
|
vals := makeIntegerArray(5, 10, 20)
|
|
vals.Include(tc.min, tc.max)
|
|
got := vals.Timestamps
|
|
if !cmp.Equal(got, tc.exp) {
|
|
t.Errorf("unexpected values -got/+exp\n%s", cmp.Diff(got, tc.exp))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func makeTimestampArray(count int, min, max int64) *TimestampArray {
|
|
vals := NewTimestampArrayLen(count)
|
|
|
|
ts := min
|
|
inc := (max - min) / int64(count)
|
|
|
|
for i := 0; i < count; i++ {
|
|
vals.Timestamps[i] = ts
|
|
ts += inc
|
|
}
|
|
|
|
return vals
|
|
}
|
|
|
|
func TestTimestampArray_Contains(t *testing.T) {
|
|
cases := []struct {
|
|
n string
|
|
min, max int64
|
|
exp bool
|
|
}{
|
|
{"no/lo", 0, 9, false},
|
|
{"no/hi", 19, 30, false},
|
|
{"no/middle", 13, 13, false},
|
|
|
|
{"yes/first", 0, 10, true},
|
|
{"yes/first-eq", 10, 10, true},
|
|
{"yes/last", 18, 20, true},
|
|
{"yes/last-eq", 18, 18, true},
|
|
{"yes/all but first and last", 12, 16, true},
|
|
{"yes/middle-eq", 14, 14, true},
|
|
{"yes/middle-overlap", 13, 15, true},
|
|
{"yes/covers", 8, 22, true},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(fmt.Sprintf("%s[%d,%d]", tc.n, tc.min, tc.max), func(t *testing.T) {
|
|
vals := makeTimestampArray(5, 10, 20)
|
|
if got := vals.Contains(tc.min, tc.max); got != tc.exp {
|
|
t.Errorf("Contains -got/+exp\n%s", cmp.Diff(got, tc.exp))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func benchExclude(b *testing.B, vals *IntegerArray, min, max int64) {
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
vals.Exclude(min, max)
|
|
}
|
|
}
|
|
|
|
func BenchmarkIntegerArray_ExcludeNone_1000(b *testing.B) {
|
|
benchExclude(b, makeIntegerArray(1000, 1000, 2000), 0, 500)
|
|
}
|
|
|
|
func BenchmarkIntegerArray_ExcludeMiddleHalf_1000(b *testing.B) {
|
|
benchExclude(b, makeIntegerArray(1000, 1000, 2000), 1250, 1750)
|
|
}
|
|
|
|
func BenchmarkIntegerArray_ExcludeFirst_1000(b *testing.B) {
|
|
benchExclude(b, makeIntegerArray(1000, 1000, 2000), 0, 1000)
|
|
}
|
|
|
|
func BenchmarkIntegerArray_ExcludeLast_1000(b *testing.B) {
|
|
benchExclude(b, makeIntegerArray(1000, 1000, 2000), 1999, 2000)
|
|
}
|
|
|
|
func BenchmarkIntegerArray_ExcludeNone_10000(b *testing.B) {
|
|
benchExclude(b, makeIntegerArray(10000, 10000, 20000), 00, 5000)
|
|
}
|
|
|
|
func BenchmarkIntegerArray_ExcludeMiddleHalf_10000(b *testing.B) {
|
|
benchExclude(b, makeIntegerArray(10000, 10000, 20000), 12500, 17500)
|
|
}
|
|
|
|
func BenchmarkIntegerArray_ExcludeFirst_10000(b *testing.B) {
|
|
benchExclude(b, makeIntegerArray(10000, 10000, 20000), 0, 10000)
|
|
}
|
|
|
|
func BenchmarkIntegerArray_ExcludeLast_10000(b *testing.B) {
|
|
benchExclude(b, makeIntegerArray(10000, 10000, 20000), 19999, 20000)
|
|
}
|
|
|
|
func benchInclude(b *testing.B, vals *IntegerArray, min, max int64) {
|
|
src := *vals
|
|
tmp := NewIntegerArrayLen(vals.Len())
|
|
copy(tmp.Timestamps, vals.Timestamps)
|
|
copy(tmp.Values, vals.Values)
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
vals.Include(min, max)
|
|
*vals = src
|
|
copy(vals.Timestamps, tmp.Timestamps)
|
|
copy(vals.Values, tmp.Values)
|
|
}
|
|
}
|
|
|
|
func BenchmarkIntegerArray_IncludeNone_1000(b *testing.B) {
|
|
benchInclude(b, makeIntegerArray(1000, 1000, 2000), 0, 500)
|
|
}
|
|
|
|
func BenchmarkIntegerArray_IncludeMiddleHalf_1000(b *testing.B) {
|
|
benchInclude(b, makeIntegerArray(1000, 1000, 2000), 1250, 1750)
|
|
}
|
|
|
|
func BenchmarkIntegerArray_IncludeFirst_1000(b *testing.B) {
|
|
benchInclude(b, makeIntegerArray(1000, 1000, 2000), 0, 1000)
|
|
}
|
|
|
|
func BenchmarkIntegerArray_IncludeLast_1000(b *testing.B) {
|
|
benchInclude(b, makeIntegerArray(1000, 1000, 2000), 1999, 2000)
|
|
}
|
|
|
|
func BenchmarkIntegerArray_IncludeNone_10000(b *testing.B) {
|
|
benchInclude(b, makeIntegerArray(10000, 10000, 20000), 00, 5000)
|
|
}
|
|
|
|
func BenchmarkIntegerArray_IncludeMiddleHalf_10000(b *testing.B) {
|
|
benchInclude(b, makeIntegerArray(10000, 10000, 20000), 12500, 17500)
|
|
}
|
|
|
|
func BenchmarkIntegerArray_IncludeFirst_10000(b *testing.B) {
|
|
benchInclude(b, makeIntegerArray(10000, 10000, 20000), 0, 10000)
|
|
}
|
|
|
|
func BenchmarkIntegerArray_IncludeLast_10000(b *testing.B) {
|
|
benchInclude(b, makeIntegerArray(10000, 10000, 20000), 19999, 20000)
|
|
}
|