2020-10-01 20:56:46 +00:00
|
|
|
// Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
package uniq_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"reflect"
|
|
|
|
"strconv"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"tailscale.com/util/uniq"
|
|
|
|
)
|
|
|
|
|
2022-08-30 21:56:51 +00:00
|
|
|
func runTests(t *testing.T, cb func(*[]int)) {
|
2020-10-01 20:56:46 +00:00
|
|
|
tests := []struct {
|
|
|
|
in []int
|
|
|
|
want []int
|
|
|
|
}{
|
|
|
|
{in: []int{0, 1, 2}, want: []int{0, 1, 2}},
|
|
|
|
{in: []int{0, 1, 2, 2}, want: []int{0, 1, 2}},
|
|
|
|
{in: []int{0, 0, 1, 2}, want: []int{0, 1, 2}},
|
|
|
|
{in: []int{0, 1, 0, 2}, want: []int{0, 1, 0, 2}},
|
|
|
|
{in: []int{0}, want: []int{0}},
|
|
|
|
{in: []int{0, 0}, want: []int{0}},
|
|
|
|
{in: []int{}, want: []int{}},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range tests {
|
|
|
|
in := make([]int, len(test.in))
|
|
|
|
copy(in, test.in)
|
2022-08-30 21:56:51 +00:00
|
|
|
cb(&test.in)
|
2020-10-01 20:56:46 +00:00
|
|
|
if !reflect.DeepEqual(test.in, test.want) {
|
|
|
|
t.Errorf("uniq.Slice(%v) = %v, want %v", in, test.in, test.want)
|
|
|
|
}
|
|
|
|
start := len(test.in)
|
|
|
|
test.in = test.in[:cap(test.in)]
|
|
|
|
for i := start; i < len(in); i++ {
|
|
|
|
if test.in[i] != 0 {
|
|
|
|
t.Errorf("uniq.Slice(%v): non-0 in tail of %v at index %v", in, test.in, i)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-30 21:56:51 +00:00
|
|
|
func TestModifySlice(t *testing.T) {
|
|
|
|
runTests(t, func(slice *[]int) {
|
|
|
|
uniq.ModifySlice(slice)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-10-01 20:56:46 +00:00
|
|
|
func Benchmark(b *testing.B) {
|
|
|
|
benches := []struct {
|
|
|
|
name string
|
|
|
|
reset func(s []byte)
|
|
|
|
}{
|
|
|
|
{name: "AllDups",
|
|
|
|
reset: func(s []byte) {
|
|
|
|
for i := range s {
|
|
|
|
s[i] = '*'
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{name: "NoDups",
|
|
|
|
reset: func(s []byte) {
|
|
|
|
for i := range s {
|
|
|
|
s[i] = byte(i)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, bb := range benches {
|
|
|
|
b.Run(bb.name, func(b *testing.B) {
|
|
|
|
for size := 1; size <= 4096; size *= 16 {
|
|
|
|
b.Run(strconv.Itoa(size), func(b *testing.B) {
|
|
|
|
benchmark(b, 64, bb.reset)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func benchmark(b *testing.B, size int64, reset func(s []byte)) {
|
|
|
|
b.ReportAllocs()
|
|
|
|
b.SetBytes(size)
|
|
|
|
s := make([]byte, size)
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
s = s[:size]
|
|
|
|
reset(s)
|
2022-08-30 21:56:51 +00:00
|
|
|
uniq.ModifySlice(&s)
|
2020-10-01 20:56:46 +00:00
|
|
|
}
|
|
|
|
}
|