1897 lines
43 KiB
Go
1897 lines
43 KiB
Go
package tsm1_test
|
|
|
|
import (
|
|
"fmt"
|
|
"math/rand"
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/davecgh/go-spew/spew"
|
|
"github.com/influxdata/platform/tsdb/tsm1"
|
|
)
|
|
|
|
func TestEncoding_FloatBlock(t *testing.T) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
values := make([]tsm1.Value, len(times))
|
|
for i, t := range times {
|
|
values[i] = tsm1.NewValue(t, float64(i))
|
|
}
|
|
|
|
b, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
var decodedValues []tsm1.Value
|
|
decodedValues, err = tsm1.DecodeBlock(b, decodedValues)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
|
|
if !reflect.DeepEqual(decodedValues, values) {
|
|
t.Fatalf("unexpected results:\n\tgot: %s\n\texp: %s\n", spew.Sdump(decodedValues), spew.Sdump(values))
|
|
}
|
|
}
|
|
|
|
func TestEncoding_FloatBlock_ZeroTime(t *testing.T) {
|
|
values := make([]tsm1.Value, 3)
|
|
for i := 0; i < 3; i++ {
|
|
values[i] = tsm1.NewValue(0, float64(i))
|
|
}
|
|
|
|
b, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
var decodedValues []tsm1.Value
|
|
decodedValues, err = tsm1.DecodeBlock(b, decodedValues)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
|
|
if !reflect.DeepEqual(decodedValues, values) {
|
|
t.Fatalf("unexpected results:\n\tgot: %v\n\texp: %v\n", decodedValues, values)
|
|
}
|
|
}
|
|
|
|
func TestEncoding_FloatBlock_SimilarFloats(t *testing.T) {
|
|
values := make([]tsm1.Value, 5)
|
|
values[0] = tsm1.NewValue(1444238178437870000, 6.00065e+06)
|
|
values[1] = tsm1.NewValue(1444238185286830000, 6.000656e+06)
|
|
values[2] = tsm1.NewValue(1444238188441501000, 6.000657e+06)
|
|
values[3] = tsm1.NewValue(1444238195286811000, 6.000659e+06)
|
|
values[4] = tsm1.NewValue(1444238198439917000, 6.000661e+06)
|
|
|
|
b, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
var decodedValues []tsm1.Value
|
|
decodedValues, err = tsm1.DecodeBlock(b, decodedValues)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
|
|
if !reflect.DeepEqual(decodedValues, values) {
|
|
t.Fatalf("unexpected results:\n\tgot: %v\n\texp: %v\n", decodedValues, values)
|
|
}
|
|
}
|
|
|
|
func TestEncoding_IntBlock_Basic(t *testing.T) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
values := make([]tsm1.Value, len(times))
|
|
for i, t := range times {
|
|
values[i] = tsm1.NewValue(t, int64(i))
|
|
}
|
|
|
|
b, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
var decodedValues []tsm1.Value
|
|
decodedValues, err = tsm1.DecodeBlock(b, decodedValues)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
|
|
if len(decodedValues) != len(values) {
|
|
t.Fatalf("unexpected results length:\n\tgot: %v\n\texp: %v\n", len(decodedValues), len(values))
|
|
}
|
|
|
|
for i := 0; i < len(decodedValues); i++ {
|
|
if decodedValues[i].UnixNano() != values[i].UnixNano() {
|
|
t.Fatalf("unexpected results:\n\tgot: %v\n\texp: %v\n", decodedValues[i].UnixNano(), values[i].UnixNano())
|
|
}
|
|
|
|
if decodedValues[i].Value() != values[i].Value() {
|
|
t.Fatalf("unexpected results:\n\tgot: %v\n\texp: %v\n", decodedValues[i].Value(), values[i].Value())
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestEncoding_IntBlock_Negatives(t *testing.T) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
values := make([]tsm1.Value, len(times))
|
|
for i, t := range times {
|
|
v := int64(i)
|
|
if i%2 == 0 {
|
|
v = -v
|
|
}
|
|
values[i] = tsm1.NewValue(t, int64(v))
|
|
}
|
|
|
|
b, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
var decodedValues []tsm1.Value
|
|
decodedValues, err = tsm1.DecodeBlock(b, decodedValues)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
|
|
if !reflect.DeepEqual(decodedValues, values) {
|
|
t.Fatalf("unexpected results:\n\tgot: %v\n\texp: %v\n", decodedValues, values)
|
|
}
|
|
}
|
|
|
|
func TestEncoding_UIntBlock_Basic(t *testing.T) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
values := make([]tsm1.Value, len(times))
|
|
for i, t := range times {
|
|
values[i] = tsm1.NewValue(t, uint64(i))
|
|
}
|
|
|
|
b, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
var decodedValues []tsm1.Value
|
|
decodedValues, err = tsm1.DecodeBlock(b, decodedValues)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
|
|
if len(decodedValues) != len(values) {
|
|
t.Fatalf("unexpected results length:\n\tgot: %v\n\texp: %v\n", len(decodedValues), len(values))
|
|
}
|
|
|
|
for i := 0; i < len(decodedValues); i++ {
|
|
if decodedValues[i].UnixNano() != values[i].UnixNano() {
|
|
t.Fatalf("unexpected results:\n\tgot: %v\n\texp: %v\n", decodedValues[i].UnixNano(), values[i].UnixNano())
|
|
}
|
|
|
|
if decodedValues[i].Value() != values[i].Value() {
|
|
t.Fatalf("unexpected results:\n\tgot: %v\n\texp: %v\n", decodedValues[i].Value(), values[i].Value())
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestEncoding_UIntBlock_MaxValues encodes uint64 numbers starting at max (18446744073709551615)
|
|
// down to 18446744073709550616
|
|
func TestEncoding_UIntBlock_MaxValues(t *testing.T) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
values := make([]tsm1.Value, len(times))
|
|
for i, t := range times {
|
|
values[i] = tsm1.NewValue(t, ^uint64(i))
|
|
}
|
|
|
|
b, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
var decodedValues []tsm1.Value
|
|
decodedValues, err = tsm1.DecodeBlock(b, decodedValues)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
|
|
if !reflect.DeepEqual(decodedValues, values) {
|
|
t.Fatalf("unexpected results:\n\tgot: %v\n\texp: %v\n", decodedValues, values)
|
|
}
|
|
}
|
|
|
|
func TestEncoding_BooleanBlock_Basic(t *testing.T) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
values := make([]tsm1.Value, len(times))
|
|
for i, t := range times {
|
|
v := true
|
|
if i%2 == 0 {
|
|
v = false
|
|
}
|
|
values[i] = tsm1.NewValue(t, v)
|
|
}
|
|
|
|
b, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
var decodedValues []tsm1.Value
|
|
decodedValues, err = tsm1.DecodeBlock(b, decodedValues)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
|
|
if !reflect.DeepEqual(decodedValues, values) {
|
|
t.Fatalf("unexpected results:\n\tgot: %v\n\texp: %v\n", decodedValues, values)
|
|
}
|
|
}
|
|
|
|
func TestEncoding_StringBlock_Basic(t *testing.T) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
values := make([]tsm1.Value, len(times))
|
|
for i, t := range times {
|
|
values[i] = tsm1.NewValue(t, fmt.Sprintf("value %d", i))
|
|
}
|
|
|
|
b, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
var decodedValues []tsm1.Value
|
|
decodedValues, err = tsm1.DecodeBlock(b, decodedValues)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
|
|
if !reflect.DeepEqual(decodedValues, values) {
|
|
t.Fatalf("unexpected results:\n\tgot: %v\n\texp: %v\n", decodedValues, values)
|
|
}
|
|
}
|
|
|
|
func TestEncoding_BlockType(t *testing.T) {
|
|
tests := []struct {
|
|
value interface{}
|
|
blockType byte
|
|
}{
|
|
{value: float64(1.0), blockType: tsm1.BlockFloat64},
|
|
{value: int64(1), blockType: tsm1.BlockInteger},
|
|
{value: uint64(1), blockType: tsm1.BlockUnsigned},
|
|
{value: true, blockType: tsm1.BlockBoolean},
|
|
{value: "string", blockType: tsm1.BlockString},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
var values []tsm1.Value
|
|
values = append(values, tsm1.NewValue(0, test.value))
|
|
|
|
b, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
bt, err := tsm1.BlockType(b)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error decoding block type: %v", err)
|
|
}
|
|
|
|
if got, exp := bt, test.blockType; got != exp {
|
|
t.Fatalf("block type mismatch: got %v, exp %v", got, exp)
|
|
}
|
|
}
|
|
|
|
_, err := tsm1.BlockType([]byte{10})
|
|
if err == nil {
|
|
t.Fatalf("expected error decoding block type, got nil")
|
|
}
|
|
}
|
|
|
|
func TestEncoding_Count(t *testing.T) {
|
|
tests := []struct {
|
|
value interface{}
|
|
blockType byte
|
|
}{
|
|
{value: float64(1.0), blockType: tsm1.BlockFloat64},
|
|
{value: int64(1), blockType: tsm1.BlockInteger},
|
|
{value: uint64(1), blockType: tsm1.BlockUnsigned},
|
|
{value: true, blockType: tsm1.BlockBoolean},
|
|
{value: "string", blockType: tsm1.BlockString},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
var values []tsm1.Value
|
|
values = append(values, tsm1.NewValue(0, test.value))
|
|
|
|
b, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
if got, exp := tsm1.BlockCount(b), 1; got != exp {
|
|
t.Fatalf("block count mismatch: got %v, exp %v", got, exp)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestValues_MergeFloat(t *testing.T) {
|
|
tests := []struct {
|
|
a, b, exp []tsm1.Value
|
|
}{
|
|
|
|
{ // empty a
|
|
a: []tsm1.Value{},
|
|
|
|
b: []tsm1.Value{
|
|
tsm1.NewValue(1, 1.2),
|
|
tsm1.NewValue(2, 2.2),
|
|
},
|
|
exp: []tsm1.Value{
|
|
tsm1.NewValue(1, 1.2),
|
|
tsm1.NewValue(2, 2.2),
|
|
},
|
|
},
|
|
{ // empty b
|
|
a: []tsm1.Value{
|
|
tsm1.NewValue(1, 1.1),
|
|
tsm1.NewValue(2, 2.1),
|
|
},
|
|
|
|
b: []tsm1.Value{},
|
|
exp: []tsm1.Value{
|
|
tsm1.NewValue(1, 1.1),
|
|
tsm1.NewValue(2, 2.1),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.Value{
|
|
tsm1.NewValue(0, 0.0),
|
|
tsm1.NewValue(1, 1.1),
|
|
tsm1.NewValue(2, 2.1),
|
|
},
|
|
b: []tsm1.Value{
|
|
tsm1.NewValue(2, 2.2),
|
|
tsm1.NewValue(2, 2.2), // duplicate data
|
|
},
|
|
exp: []tsm1.Value{
|
|
tsm1.NewValue(0, 0.0),
|
|
tsm1.NewValue(1, 1.1),
|
|
tsm1.NewValue(2, 2.2),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.Value{
|
|
tsm1.NewValue(0, 0.0),
|
|
tsm1.NewValue(1, 1.1),
|
|
tsm1.NewValue(1, 1.1), // duplicate data
|
|
tsm1.NewValue(2, 2.1),
|
|
},
|
|
b: []tsm1.Value{
|
|
tsm1.NewValue(2, 2.2),
|
|
tsm1.NewValue(2, 2.2), // duplicate data
|
|
},
|
|
exp: []tsm1.Value{
|
|
tsm1.NewValue(0, 0.0),
|
|
tsm1.NewValue(1, 1.1),
|
|
tsm1.NewValue(2, 2.2),
|
|
},
|
|
},
|
|
|
|
{
|
|
a: []tsm1.Value{
|
|
tsm1.NewValue(1, 1.1),
|
|
},
|
|
b: []tsm1.Value{
|
|
tsm1.NewValue(0, 0.0),
|
|
tsm1.NewValue(1, 1.2), // overwrites a
|
|
tsm1.NewValue(2, 2.2),
|
|
tsm1.NewValue(3, 3.2),
|
|
tsm1.NewValue(4, 4.2),
|
|
},
|
|
exp: []tsm1.Value{
|
|
tsm1.NewValue(0, 0.0),
|
|
tsm1.NewValue(1, 1.2),
|
|
tsm1.NewValue(2, 2.2),
|
|
tsm1.NewValue(3, 3.2),
|
|
tsm1.NewValue(4, 4.2),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.Value{
|
|
tsm1.NewValue(1, 1.1),
|
|
tsm1.NewValue(2, 2.1),
|
|
tsm1.NewValue(3, 3.1),
|
|
tsm1.NewValue(4, 4.1),
|
|
},
|
|
|
|
b: []tsm1.Value{
|
|
tsm1.NewValue(1, 1.2), // overwrites a
|
|
tsm1.NewValue(2, 2.2), // overwrites a
|
|
},
|
|
exp: []tsm1.Value{
|
|
tsm1.NewValue(1, 1.2),
|
|
tsm1.NewValue(2, 2.2),
|
|
tsm1.NewValue(3, 3.1),
|
|
tsm1.NewValue(4, 4.1),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.Value{
|
|
tsm1.NewValue(1, 1.1),
|
|
tsm1.NewValue(2, 2.1),
|
|
tsm1.NewValue(3, 3.1),
|
|
tsm1.NewValue(4, 4.1),
|
|
},
|
|
|
|
b: []tsm1.Value{
|
|
tsm1.NewValue(1, 1.2), // overwrites a
|
|
tsm1.NewValue(2, 2.2), // overwrites a
|
|
tsm1.NewValue(3, 3.2),
|
|
tsm1.NewValue(4, 4.2),
|
|
},
|
|
exp: []tsm1.Value{
|
|
tsm1.NewValue(1, 1.2),
|
|
tsm1.NewValue(2, 2.2),
|
|
tsm1.NewValue(3, 3.2),
|
|
tsm1.NewValue(4, 4.2),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.Value{
|
|
tsm1.NewValue(0, 0.0),
|
|
tsm1.NewValue(1, 1.1),
|
|
tsm1.NewValue(2, 2.1),
|
|
tsm1.NewValue(3, 3.1),
|
|
tsm1.NewValue(4, 4.1),
|
|
},
|
|
b: []tsm1.Value{
|
|
tsm1.NewValue(0, 0.0),
|
|
tsm1.NewValue(2, 2.2),
|
|
tsm1.NewValue(4, 4.2),
|
|
},
|
|
exp: []tsm1.Value{
|
|
tsm1.NewValue(0, 0.0),
|
|
tsm1.NewValue(1, 1.1),
|
|
tsm1.NewValue(2, 2.2),
|
|
tsm1.NewValue(3, 3.1),
|
|
tsm1.NewValue(4, 4.2),
|
|
},
|
|
},
|
|
|
|
{
|
|
a: []tsm1.Value{
|
|
tsm1.NewValue(1462498658242869207, 0.0),
|
|
tsm1.NewValue(1462498658288956853, 1.1),
|
|
},
|
|
b: []tsm1.Value{
|
|
tsm1.NewValue(1462498658242870810, 0.0),
|
|
tsm1.NewValue(1462498658262911238, 2.2),
|
|
tsm1.NewValue(1462498658282415038, 4.2),
|
|
tsm1.NewValue(1462498658282417760, 4.2),
|
|
},
|
|
exp: []tsm1.Value{
|
|
tsm1.NewValue(1462498658242869207, 0.0),
|
|
tsm1.NewValue(1462498658242870810, 0.0),
|
|
tsm1.NewValue(1462498658262911238, 2.2),
|
|
tsm1.NewValue(1462498658282415038, 4.2),
|
|
tsm1.NewValue(1462498658282417760, 4.2),
|
|
tsm1.NewValue(1462498658288956853, 1.1),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.Value{
|
|
tsm1.NewValue(4, 4.0),
|
|
tsm1.NewValue(5, 5.0),
|
|
tsm1.NewValue(6, 6.0),
|
|
},
|
|
b: []tsm1.Value{
|
|
tsm1.NewValue(1, 1.0),
|
|
tsm1.NewValue(2, 2.0),
|
|
tsm1.NewValue(3, 3.0),
|
|
},
|
|
exp: []tsm1.Value{
|
|
tsm1.NewValue(1, 1.0),
|
|
tsm1.NewValue(2, 2.0),
|
|
tsm1.NewValue(3, 3.0),
|
|
tsm1.NewValue(4, 4.0),
|
|
tsm1.NewValue(5, 5.0),
|
|
tsm1.NewValue(6, 6.0),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.Value{
|
|
tsm1.NewValue(5, 5.0),
|
|
tsm1.NewValue(6, 6.0),
|
|
},
|
|
b: []tsm1.Value{
|
|
tsm1.NewValue(1, 1.0),
|
|
tsm1.NewValue(2, 2.0),
|
|
tsm1.NewValue(3, 3.0),
|
|
tsm1.NewValue(4, 4.0),
|
|
tsm1.NewValue(7, 7.0),
|
|
tsm1.NewValue(8, 8.0),
|
|
},
|
|
exp: []tsm1.Value{
|
|
tsm1.NewValue(1, 1.0),
|
|
tsm1.NewValue(2, 2.0),
|
|
tsm1.NewValue(3, 3.0),
|
|
tsm1.NewValue(4, 4.0),
|
|
tsm1.NewValue(5, 5.0),
|
|
tsm1.NewValue(6, 6.0),
|
|
tsm1.NewValue(7, 7.0),
|
|
tsm1.NewValue(8, 8.0),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.Value{
|
|
tsm1.NewValue(1, 1.0),
|
|
tsm1.NewValue(2, 2.0),
|
|
tsm1.NewValue(3, 3.0),
|
|
},
|
|
b: []tsm1.Value{
|
|
tsm1.NewValue(4, 4.0),
|
|
tsm1.NewValue(5, 5.0),
|
|
tsm1.NewValue(6, 6.0),
|
|
},
|
|
exp: []tsm1.Value{
|
|
tsm1.NewValue(1, 1.0),
|
|
tsm1.NewValue(2, 2.0),
|
|
tsm1.NewValue(3, 3.0),
|
|
tsm1.NewValue(4, 4.0),
|
|
tsm1.NewValue(5, 5.0),
|
|
tsm1.NewValue(6, 6.0),
|
|
},
|
|
},
|
|
}
|
|
|
|
for i, test := range tests {
|
|
got := tsm1.Values(test.a).Merge(test.b)
|
|
if exp, got := len(test.exp), len(got); exp != got {
|
|
t.Fatalf("test(%d): value length mismatch: exp %v, got %v", i, exp, got)
|
|
}
|
|
|
|
dedup := tsm1.Values(append(test.a, test.b...)).Deduplicate()
|
|
|
|
for i := range test.exp {
|
|
if exp, got := test.exp[i].String(), got[i].String(); exp != got {
|
|
t.Fatalf("value mismatch:\n exp %v\n got %v", exp, got)
|
|
}
|
|
|
|
if exp, got := test.exp[i].String(), dedup[i].String(); exp != got {
|
|
t.Fatalf("value mismatch:\n exp %v\n got %v", exp, got)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestIntegerValues_Merge(t *testing.T) {
|
|
integerValue := func(t int64, f int64) tsm1.IntegerValue {
|
|
return tsm1.NewValue(t, f).(tsm1.IntegerValue)
|
|
}
|
|
|
|
tests := []struct {
|
|
a, b, exp []tsm1.IntegerValue
|
|
}{
|
|
|
|
{ // empty a
|
|
a: []tsm1.IntegerValue{},
|
|
|
|
b: []tsm1.IntegerValue{
|
|
integerValue(1, 10),
|
|
integerValue(2, 20),
|
|
},
|
|
exp: []tsm1.IntegerValue{
|
|
integerValue(1, 10),
|
|
integerValue(2, 20),
|
|
},
|
|
},
|
|
{ // empty b
|
|
a: []tsm1.IntegerValue{
|
|
integerValue(1, 1),
|
|
integerValue(2, 2),
|
|
},
|
|
|
|
b: []tsm1.IntegerValue{},
|
|
exp: []tsm1.IntegerValue{
|
|
integerValue(1, 1),
|
|
integerValue(2, 2),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.IntegerValue{
|
|
integerValue(1, 1),
|
|
},
|
|
b: []tsm1.IntegerValue{
|
|
integerValue(0, 0),
|
|
integerValue(1, 10), // overwrites a
|
|
integerValue(2, 20),
|
|
integerValue(3, 30),
|
|
integerValue(4, 40),
|
|
},
|
|
exp: []tsm1.IntegerValue{
|
|
integerValue(0, 0),
|
|
integerValue(1, 10),
|
|
integerValue(2, 20),
|
|
integerValue(3, 30),
|
|
integerValue(4, 40),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.IntegerValue{
|
|
integerValue(1, 1),
|
|
integerValue(2, 2),
|
|
integerValue(3, 3),
|
|
integerValue(4, 4),
|
|
},
|
|
|
|
b: []tsm1.IntegerValue{
|
|
integerValue(1, 10), // overwrites a
|
|
integerValue(2, 20), // overwrites a
|
|
},
|
|
exp: []tsm1.IntegerValue{
|
|
integerValue(1, 10),
|
|
integerValue(2, 20),
|
|
integerValue(3, 3),
|
|
integerValue(4, 4),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.IntegerValue{
|
|
integerValue(1, 1),
|
|
integerValue(2, 2),
|
|
integerValue(3, 3),
|
|
integerValue(4, 4),
|
|
},
|
|
|
|
b: []tsm1.IntegerValue{
|
|
integerValue(1, 10), // overwrites a
|
|
integerValue(2, 20), // overwrites a
|
|
integerValue(3, 30),
|
|
integerValue(4, 40),
|
|
},
|
|
exp: []tsm1.IntegerValue{
|
|
integerValue(1, 10),
|
|
integerValue(2, 20),
|
|
integerValue(3, 30),
|
|
integerValue(4, 40),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.IntegerValue{
|
|
integerValue(0, 0),
|
|
integerValue(1, 1),
|
|
integerValue(2, 2),
|
|
integerValue(3, 3),
|
|
integerValue(4, 4),
|
|
},
|
|
b: []tsm1.IntegerValue{
|
|
integerValue(0, 0),
|
|
integerValue(2, 20),
|
|
integerValue(4, 40),
|
|
},
|
|
exp: []tsm1.IntegerValue{
|
|
integerValue(0, 0.0),
|
|
integerValue(1, 1),
|
|
integerValue(2, 20),
|
|
integerValue(3, 3),
|
|
integerValue(4, 40),
|
|
},
|
|
},
|
|
}
|
|
|
|
for i, test := range tests {
|
|
if i != 2 {
|
|
continue
|
|
}
|
|
|
|
got := tsm1.IntegerValues(test.a).Merge(test.b)
|
|
if exp, got := len(test.exp), len(got); exp != got {
|
|
t.Fatalf("test(%d): value length mismatch: exp %v, got %v", i, exp, got)
|
|
}
|
|
|
|
dedup := tsm1.IntegerValues(append(test.a, test.b...)).Deduplicate()
|
|
|
|
for i := range test.exp {
|
|
if exp, got := test.exp[i].String(), got[i].String(); exp != got {
|
|
t.Fatalf("value mismatch:\n exp %v\n got %v", exp, got)
|
|
}
|
|
|
|
if exp, got := test.exp[i].String(), dedup[i].String(); exp != got {
|
|
t.Fatalf("value mismatch:\n exp %v\n got %v", exp, got)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestUnsignedValues_Merge(t *testing.T) {
|
|
uintValue := func(t int64, f uint64) tsm1.UnsignedValue {
|
|
return tsm1.NewValue(t, f).(tsm1.UnsignedValue)
|
|
}
|
|
|
|
tests := []struct {
|
|
a, b, exp []tsm1.UnsignedValue
|
|
}{
|
|
|
|
{ // empty a
|
|
a: []tsm1.UnsignedValue{},
|
|
|
|
b: []tsm1.UnsignedValue{
|
|
uintValue(1, 10),
|
|
uintValue(2, 20),
|
|
},
|
|
exp: []tsm1.UnsignedValue{
|
|
uintValue(1, 10),
|
|
uintValue(2, 20),
|
|
},
|
|
},
|
|
{ // empty b
|
|
a: []tsm1.UnsignedValue{
|
|
uintValue(1, 1),
|
|
uintValue(2, 2),
|
|
},
|
|
|
|
b: []tsm1.UnsignedValue{},
|
|
exp: []tsm1.UnsignedValue{
|
|
uintValue(1, 1),
|
|
uintValue(2, 2),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.UnsignedValue{
|
|
uintValue(1, 1),
|
|
},
|
|
b: []tsm1.UnsignedValue{
|
|
uintValue(0, 0),
|
|
uintValue(1, 10), // overwrites a
|
|
uintValue(2, 20),
|
|
uintValue(3, 30),
|
|
uintValue(4, 40),
|
|
},
|
|
exp: []tsm1.UnsignedValue{
|
|
uintValue(0, 0),
|
|
uintValue(1, 10),
|
|
uintValue(2, 20),
|
|
uintValue(3, 30),
|
|
uintValue(4, 40),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.UnsignedValue{
|
|
uintValue(1, 1),
|
|
uintValue(2, 2),
|
|
uintValue(3, 3),
|
|
uintValue(4, 4),
|
|
},
|
|
|
|
b: []tsm1.UnsignedValue{
|
|
uintValue(1, ^uint64(0)), // overwrites a
|
|
uintValue(2, 20), // overwrites a
|
|
},
|
|
exp: []tsm1.UnsignedValue{
|
|
uintValue(1, ^uint64(0)),
|
|
uintValue(2, 20),
|
|
uintValue(3, 3),
|
|
uintValue(4, 4),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.UnsignedValue{
|
|
uintValue(1, 1),
|
|
uintValue(2, 2),
|
|
uintValue(3, 3),
|
|
uintValue(4, 4),
|
|
},
|
|
|
|
b: []tsm1.UnsignedValue{
|
|
uintValue(1, 10), // overwrites a
|
|
uintValue(2, 20), // overwrites a
|
|
uintValue(3, 30),
|
|
uintValue(4, 40),
|
|
},
|
|
exp: []tsm1.UnsignedValue{
|
|
uintValue(1, 10),
|
|
uintValue(2, 20),
|
|
uintValue(3, 30),
|
|
uintValue(4, 40),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.UnsignedValue{
|
|
uintValue(0, 0),
|
|
uintValue(1, 1),
|
|
uintValue(2, 2),
|
|
uintValue(3, 3),
|
|
uintValue(4, 4),
|
|
},
|
|
b: []tsm1.UnsignedValue{
|
|
uintValue(0, 0),
|
|
uintValue(2, 20),
|
|
uintValue(4, 40),
|
|
},
|
|
exp: []tsm1.UnsignedValue{
|
|
uintValue(0, 0.0),
|
|
uintValue(1, 1),
|
|
uintValue(2, 20),
|
|
uintValue(3, 3),
|
|
uintValue(4, 40),
|
|
},
|
|
},
|
|
}
|
|
|
|
for i, test := range tests {
|
|
if i != 2 {
|
|
continue
|
|
}
|
|
|
|
got := tsm1.UnsignedValues(test.a).Merge(test.b)
|
|
if exp, got := len(test.exp), len(got); exp != got {
|
|
t.Fatalf("test(%d): value length mismatch: exp %v, got %v", i, exp, got)
|
|
}
|
|
|
|
dedup := tsm1.UnsignedValues(append(test.a, test.b...)).Deduplicate()
|
|
|
|
for i := range test.exp {
|
|
if exp, got := test.exp[i].String(), got[i].String(); exp != got {
|
|
t.Fatalf("value mismatch:\n exp %v\n got %v", exp, got)
|
|
}
|
|
|
|
if exp, got := test.exp[i].String(), dedup[i].String(); exp != got {
|
|
t.Fatalf("value mismatch:\n exp %v\n got %v", exp, got)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestFloatValues_Merge(t *testing.T) {
|
|
floatValue := func(t int64, f float64) tsm1.FloatValue {
|
|
return tsm1.NewValue(t, f).(tsm1.FloatValue)
|
|
}
|
|
|
|
tests := []struct {
|
|
a, b, exp []tsm1.FloatValue
|
|
}{
|
|
|
|
{ // empty a
|
|
a: []tsm1.FloatValue{},
|
|
|
|
b: []tsm1.FloatValue{
|
|
floatValue(1, 1.2),
|
|
floatValue(2, 2.2),
|
|
},
|
|
exp: []tsm1.FloatValue{
|
|
floatValue(1, 1.2),
|
|
floatValue(2, 2.2),
|
|
},
|
|
},
|
|
{ // empty b
|
|
a: []tsm1.FloatValue{
|
|
floatValue(1, 1.1),
|
|
floatValue(2, 2.1),
|
|
},
|
|
|
|
b: []tsm1.FloatValue{},
|
|
exp: []tsm1.FloatValue{
|
|
floatValue(1, 1.1),
|
|
floatValue(2, 2.1),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.FloatValue{
|
|
floatValue(1, 1.1),
|
|
},
|
|
b: []tsm1.FloatValue{
|
|
floatValue(0, 0.0),
|
|
floatValue(1, 1.2), // overwrites a
|
|
floatValue(2, 2.2),
|
|
floatValue(3, 3.2),
|
|
floatValue(4, 4.2),
|
|
},
|
|
exp: []tsm1.FloatValue{
|
|
floatValue(0, 0.0),
|
|
floatValue(1, 1.2),
|
|
floatValue(2, 2.2),
|
|
floatValue(3, 3.2),
|
|
floatValue(4, 4.2),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.FloatValue{
|
|
floatValue(1, 1.1),
|
|
floatValue(2, 2.1),
|
|
floatValue(3, 3.1),
|
|
floatValue(4, 4.1),
|
|
},
|
|
|
|
b: []tsm1.FloatValue{
|
|
floatValue(1, 1.2), // overwrites a
|
|
floatValue(2, 2.2), // overwrites a
|
|
},
|
|
exp: []tsm1.FloatValue{
|
|
floatValue(1, 1.2),
|
|
floatValue(2, 2.2),
|
|
floatValue(3, 3.1),
|
|
floatValue(4, 4.1),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.FloatValue{
|
|
floatValue(1, 1.1),
|
|
floatValue(2, 2.1),
|
|
floatValue(3, 3.1),
|
|
floatValue(4, 4.1),
|
|
},
|
|
|
|
b: []tsm1.FloatValue{
|
|
floatValue(1, 1.2), // overwrites a
|
|
floatValue(2, 2.2), // overwrites a
|
|
floatValue(3, 3.2),
|
|
floatValue(4, 4.2),
|
|
},
|
|
exp: []tsm1.FloatValue{
|
|
floatValue(1, 1.2),
|
|
floatValue(2, 2.2),
|
|
floatValue(3, 3.2),
|
|
floatValue(4, 4.2),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.FloatValue{
|
|
floatValue(0, 0.0),
|
|
floatValue(1, 1.1),
|
|
floatValue(2, 2.1),
|
|
floatValue(3, 3.1),
|
|
floatValue(4, 4.1),
|
|
},
|
|
b: []tsm1.FloatValue{
|
|
floatValue(0, 0.0),
|
|
floatValue(2, 2.2),
|
|
floatValue(4, 4.2),
|
|
},
|
|
exp: []tsm1.FloatValue{
|
|
floatValue(0, 0.0),
|
|
floatValue(1, 1.1),
|
|
floatValue(2, 2.2),
|
|
floatValue(3, 3.1),
|
|
floatValue(4, 4.2),
|
|
},
|
|
},
|
|
}
|
|
|
|
for i, test := range tests {
|
|
got := tsm1.FloatValues(test.a).Merge(test.b)
|
|
if exp, got := len(test.exp), len(got); exp != got {
|
|
t.Fatalf("test(%d): value length mismatch: exp %v, got %v", i, exp, got)
|
|
}
|
|
|
|
dedup := tsm1.FloatValues(append(test.a, test.b...)).Deduplicate()
|
|
|
|
for i := range test.exp {
|
|
if exp, got := test.exp[i].String(), got[i].String(); exp != got {
|
|
t.Fatalf("value mismatch:\n exp %v\n got %v", exp, got)
|
|
}
|
|
|
|
if exp, got := test.exp[i].String(), dedup[i].String(); exp != got {
|
|
t.Fatalf("value mismatch:\n exp %v\n got %v", exp, got)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestBooleanValues_Merge(t *testing.T) {
|
|
booleanValue := func(t int64, f bool) tsm1.BooleanValue {
|
|
return tsm1.NewValue(t, f).(tsm1.BooleanValue)
|
|
}
|
|
|
|
tests := []struct {
|
|
a, b, exp []tsm1.BooleanValue
|
|
}{
|
|
|
|
{ // empty a
|
|
a: []tsm1.BooleanValue{},
|
|
|
|
b: []tsm1.BooleanValue{
|
|
booleanValue(1, true),
|
|
booleanValue(2, true),
|
|
},
|
|
exp: []tsm1.BooleanValue{
|
|
booleanValue(1, true),
|
|
booleanValue(2, true),
|
|
},
|
|
},
|
|
{ // empty b
|
|
a: []tsm1.BooleanValue{
|
|
booleanValue(1, true),
|
|
booleanValue(2, true),
|
|
},
|
|
|
|
b: []tsm1.BooleanValue{},
|
|
exp: []tsm1.BooleanValue{
|
|
booleanValue(1, true),
|
|
booleanValue(2, true),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.BooleanValue{
|
|
booleanValue(1, true),
|
|
},
|
|
b: []tsm1.BooleanValue{
|
|
booleanValue(0, false),
|
|
booleanValue(1, false), // overwrites a
|
|
booleanValue(2, false),
|
|
booleanValue(3, false),
|
|
booleanValue(4, false),
|
|
},
|
|
exp: []tsm1.BooleanValue{
|
|
booleanValue(0, false),
|
|
booleanValue(1, false),
|
|
booleanValue(2, false),
|
|
booleanValue(3, false),
|
|
booleanValue(4, false),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.BooleanValue{
|
|
booleanValue(1, true),
|
|
booleanValue(2, true),
|
|
booleanValue(3, true),
|
|
booleanValue(4, true),
|
|
},
|
|
|
|
b: []tsm1.BooleanValue{
|
|
booleanValue(1, false), // overwrites a
|
|
booleanValue(2, false), // overwrites a
|
|
},
|
|
exp: []tsm1.BooleanValue{
|
|
booleanValue(1, false), // overwrites a
|
|
booleanValue(2, false), // overwrites a
|
|
booleanValue(3, true),
|
|
booleanValue(4, true),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.BooleanValue{
|
|
booleanValue(1, true),
|
|
booleanValue(2, true),
|
|
booleanValue(3, true),
|
|
booleanValue(4, true),
|
|
},
|
|
|
|
b: []tsm1.BooleanValue{
|
|
booleanValue(1, false), // overwrites a
|
|
booleanValue(2, false), // overwrites a
|
|
booleanValue(3, false),
|
|
booleanValue(4, false),
|
|
},
|
|
exp: []tsm1.BooleanValue{
|
|
booleanValue(1, false),
|
|
booleanValue(2, false),
|
|
booleanValue(3, false),
|
|
booleanValue(4, false),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.BooleanValue{
|
|
booleanValue(0, true),
|
|
booleanValue(1, true),
|
|
booleanValue(2, true),
|
|
booleanValue(3, true),
|
|
booleanValue(4, true),
|
|
},
|
|
b: []tsm1.BooleanValue{
|
|
booleanValue(0, false),
|
|
booleanValue(2, false),
|
|
booleanValue(4, false),
|
|
},
|
|
exp: []tsm1.BooleanValue{
|
|
booleanValue(0, false),
|
|
booleanValue(1, true),
|
|
booleanValue(2, false),
|
|
booleanValue(3, true),
|
|
booleanValue(4, false),
|
|
},
|
|
},
|
|
}
|
|
|
|
for i, test := range tests {
|
|
got := tsm1.BooleanValues(test.a).Merge(test.b)
|
|
if exp, got := len(test.exp), len(got); exp != got {
|
|
t.Fatalf("test(%d): value length mismatch: exp %v, got %v", i, exp, got)
|
|
}
|
|
|
|
dedup := tsm1.BooleanValues(append(test.a, test.b...)).Deduplicate()
|
|
|
|
for i := range test.exp {
|
|
if exp, got := test.exp[i].String(), got[i].String(); exp != got {
|
|
t.Fatalf("value mismatch:\n exp %v\n got %v", exp, got)
|
|
}
|
|
|
|
if exp, got := test.exp[i].String(), dedup[i].String(); exp != got {
|
|
t.Fatalf("value mismatch:\n exp %v\n got %v", exp, got)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestStringValues_Merge(t *testing.T) {
|
|
stringValue := func(t int64, f string) tsm1.StringValue {
|
|
return tsm1.NewValue(t, f).(tsm1.StringValue)
|
|
}
|
|
|
|
tests := []struct {
|
|
a, b, exp []tsm1.StringValue
|
|
}{
|
|
|
|
{ // empty a
|
|
a: []tsm1.StringValue{},
|
|
|
|
b: []tsm1.StringValue{
|
|
stringValue(1, "10"),
|
|
stringValue(2, "20"),
|
|
},
|
|
exp: []tsm1.StringValue{
|
|
stringValue(1, "10"),
|
|
stringValue(2, "20"),
|
|
},
|
|
},
|
|
{ // empty b
|
|
a: []tsm1.StringValue{
|
|
stringValue(1, "1"),
|
|
stringValue(2, "2"),
|
|
},
|
|
|
|
b: []tsm1.StringValue{},
|
|
exp: []tsm1.StringValue{
|
|
stringValue(1, "1"),
|
|
stringValue(2, "2"),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.StringValue{
|
|
stringValue(1, "1"),
|
|
},
|
|
b: []tsm1.StringValue{
|
|
stringValue(0, "0"),
|
|
stringValue(1, "10"), // overwrites a
|
|
stringValue(2, "20"),
|
|
stringValue(3, "30"),
|
|
stringValue(4, "40"),
|
|
},
|
|
exp: []tsm1.StringValue{
|
|
stringValue(0, "0"),
|
|
stringValue(1, "10"),
|
|
stringValue(2, "20"),
|
|
stringValue(3, "30"),
|
|
stringValue(4, "40"),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.StringValue{
|
|
stringValue(1, "1"),
|
|
stringValue(2, "2"),
|
|
stringValue(3, "3"),
|
|
stringValue(4, "4"),
|
|
},
|
|
|
|
b: []tsm1.StringValue{
|
|
stringValue(1, "10"), // overwrites a
|
|
stringValue(2, "20"), // overwrites a
|
|
},
|
|
exp: []tsm1.StringValue{
|
|
stringValue(1, "10"),
|
|
stringValue(2, "20"),
|
|
stringValue(3, "3"),
|
|
stringValue(4, "4"),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.StringValue{
|
|
stringValue(1, "1"),
|
|
stringValue(2, "2"),
|
|
stringValue(3, "3"),
|
|
stringValue(4, "4"),
|
|
},
|
|
|
|
b: []tsm1.StringValue{
|
|
stringValue(1, "10"), // overwrites a
|
|
stringValue(2, "20"), // overwrites a
|
|
stringValue(3, "30"),
|
|
stringValue(4, "40"),
|
|
},
|
|
exp: []tsm1.StringValue{
|
|
stringValue(1, "10"),
|
|
stringValue(2, "20"),
|
|
stringValue(3, "30"),
|
|
stringValue(4, "40"),
|
|
},
|
|
},
|
|
{
|
|
a: []tsm1.StringValue{
|
|
stringValue(0, "0"),
|
|
stringValue(1, "1"),
|
|
stringValue(2, "2"),
|
|
stringValue(3, "3"),
|
|
stringValue(4, "4"),
|
|
},
|
|
b: []tsm1.StringValue{
|
|
stringValue(0, "0"),
|
|
stringValue(2, "20"),
|
|
stringValue(4, "40"),
|
|
},
|
|
exp: []tsm1.StringValue{
|
|
stringValue(0, "0.0"),
|
|
stringValue(1, "1"),
|
|
stringValue(2, "20"),
|
|
stringValue(3, "3"),
|
|
stringValue(4, "40"),
|
|
},
|
|
},
|
|
}
|
|
|
|
for i, test := range tests {
|
|
if i != 2 {
|
|
continue
|
|
}
|
|
|
|
got := tsm1.StringValues(test.a).Merge(test.b)
|
|
if exp, got := len(test.exp), len(got); exp != got {
|
|
t.Fatalf("test(%d): value length mismatch: exp %v, got %v", i, exp, got)
|
|
}
|
|
|
|
dedup := tsm1.StringValues(append(test.a, test.b...)).Deduplicate()
|
|
|
|
for i := range test.exp {
|
|
if exp, got := test.exp[i].String(), got[i].String(); exp != got {
|
|
t.Fatalf("value mismatch:\n exp %v\n got %v", exp, got)
|
|
}
|
|
|
|
if exp, got := test.exp[i].String(), dedup[i].String(); exp != got {
|
|
t.Fatalf("value mismatch:\n exp %v\n got %v", exp, got)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
func getTimes(n, step int, precision time.Duration) []int64 {
|
|
t := time.Now().Round(precision).UnixNano()
|
|
a := make([]int64, n)
|
|
for i := 0; i < n; i++ {
|
|
a[i] = t + (time.Duration(i*60) * precision).Nanoseconds()
|
|
}
|
|
return a
|
|
}
|
|
|
|
func BenchmarkDecodeBlock_Float_Empty(b *testing.B) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
values := make([]tsm1.Value, len(times))
|
|
for i, t := range times {
|
|
values[i] = tsm1.NewValue(t, float64(i))
|
|
}
|
|
|
|
bytes, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
var decodedValues []tsm1.Value
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_, err = tsm1.DecodeBlock(bytes, decodedValues)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkDecodeBlock_Float_EqualSize(b *testing.B) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
values := make([]tsm1.Value, len(times))
|
|
for i, t := range times {
|
|
values[i] = tsm1.NewValue(t, float64(i))
|
|
}
|
|
|
|
bytes, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
decodedValues := make([]tsm1.Value, len(values))
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_, err = tsm1.DecodeBlock(bytes, decodedValues)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkDecodeBlock_Float_TypeSpecific(b *testing.B) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
values := make([]tsm1.Value, len(times))
|
|
for i, t := range times {
|
|
values[i] = tsm1.NewValue(t, float64(i))
|
|
}
|
|
|
|
bytes, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
decodedValues := make([]tsm1.FloatValue, len(values))
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_, err = tsm1.DecodeFloatBlock(bytes, &decodedValues)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkDecodeBlock_Integer_Empty(b *testing.B) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
values := make([]tsm1.Value, len(times))
|
|
for i, t := range times {
|
|
values[i] = tsm1.NewValue(t, int64(i))
|
|
}
|
|
|
|
bytes, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
var decodedValues []tsm1.Value
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_, err = tsm1.DecodeBlock(bytes, decodedValues)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkDecodeBlock_Integer_EqualSize(b *testing.B) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
values := make([]tsm1.Value, len(times))
|
|
for i, t := range times {
|
|
values[i] = tsm1.NewValue(t, int64(i))
|
|
}
|
|
|
|
bytes, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
decodedValues := make([]tsm1.Value, len(values))
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_, err = tsm1.DecodeBlock(bytes, decodedValues)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkDecodeBlock_Integer_TypeSpecific(b *testing.B) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
values := make([]tsm1.Value, len(times))
|
|
for i, t := range times {
|
|
values[i] = tsm1.NewValue(t, int64(i))
|
|
}
|
|
|
|
bytes, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
decodedValues := make([]tsm1.IntegerValue, len(values))
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_, err = tsm1.DecodeIntegerBlock(bytes, &decodedValues)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkDecodeBlock_Boolean_Empty(b *testing.B) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
values := make([]tsm1.Value, len(times))
|
|
for i, t := range times {
|
|
values[i] = tsm1.NewValue(t, true)
|
|
}
|
|
|
|
bytes, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
var decodedValues []tsm1.Value
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_, err = tsm1.DecodeBlock(bytes, decodedValues)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkDecodeBlock_Boolean_EqualSize(b *testing.B) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
values := make([]tsm1.Value, len(times))
|
|
for i, t := range times {
|
|
values[i] = tsm1.NewValue(t, true)
|
|
}
|
|
|
|
bytes, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
decodedValues := make([]tsm1.Value, len(values))
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_, err = tsm1.DecodeBlock(bytes, decodedValues)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkDecodeBlock_Boolean_TypeSpecific(b *testing.B) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
values := make([]tsm1.Value, len(times))
|
|
for i, t := range times {
|
|
values[i] = tsm1.NewValue(t, true)
|
|
}
|
|
|
|
bytes, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
decodedValues := make([]tsm1.BooleanValue, len(values))
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_, err = tsm1.DecodeBooleanBlock(bytes, &decodedValues)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkDecodeBooleanBlock(b *testing.B) {
|
|
cases := []int{
|
|
5,
|
|
55,
|
|
555,
|
|
1000,
|
|
}
|
|
for _, n := range cases {
|
|
b.Run(fmt.Sprintf("%d", n), func(b *testing.B) {
|
|
valueCount := n
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
values := make([]tsm1.Value, len(times))
|
|
for i, t := range times {
|
|
values[i] = tsm1.NewValue(t, true)
|
|
}
|
|
|
|
bytes, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
b.SetBytes(int64(tsm1.Values(values).Size()))
|
|
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
decodedValues := make([]tsm1.BooleanValue, len(values))
|
|
|
|
for pb.Next() {
|
|
_, err = tsm1.DecodeBooleanBlock(bytes, &decodedValues)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
}
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
func BenchmarkDecodeFloatBlock(b *testing.B) {
|
|
cases := []int{
|
|
5,
|
|
55,
|
|
555,
|
|
1000,
|
|
}
|
|
for _, n := range cases {
|
|
b.Run(fmt.Sprintf("%d", n), func(b *testing.B) {
|
|
valueCount := n
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
values := make([]tsm1.Value, len(times))
|
|
for i, t := range times {
|
|
values[i] = tsm1.NewValue(t, float64(i))
|
|
}
|
|
|
|
bytes, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
b.SetBytes(int64(tsm1.Values(values).Size()))
|
|
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
decodedValues := make([]tsm1.FloatValue, len(values))
|
|
|
|
for pb.Next() {
|
|
_, err = tsm1.DecodeFloatBlock(bytes, &decodedValues)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
}
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
func BenchmarkDecodeIntegerBlock(b *testing.B) {
|
|
rle := func(i int) int64 { return int64(i) }
|
|
s8b := func(i int) int64 { return int64(i + int(rand.Int31n(10))) }
|
|
|
|
cases := []struct {
|
|
enc string
|
|
gen func(i int) int64
|
|
n int
|
|
}{
|
|
{enc: "rle", gen: rle, n: 5},
|
|
{enc: "rle", gen: rle, n: 55},
|
|
{enc: "rle", gen: rle, n: 555},
|
|
{enc: "rle", gen: rle, n: 1000},
|
|
{enc: "s8b", gen: s8b, n: 5},
|
|
{enc: "s8b", gen: s8b, n: 55},
|
|
{enc: "s8b", gen: s8b, n: 555},
|
|
{enc: "s8b", gen: s8b, n: 1000},
|
|
}
|
|
for _, bm := range cases {
|
|
b.Run(fmt.Sprintf("%s_%d", bm.enc, bm.n), func(b *testing.B) {
|
|
rand.Seed(int64(bm.n * 1e3))
|
|
|
|
valueCount := bm.n
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
values := make([]tsm1.Value, len(times))
|
|
for i, t := range times {
|
|
values[i] = tsm1.NewValue(t, bm.gen(i))
|
|
}
|
|
|
|
bytes, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
b.SetBytes(int64(tsm1.Values(values).Size()))
|
|
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
decodedValues := make([]tsm1.IntegerValue, len(values))
|
|
|
|
for pb.Next() {
|
|
_, err = tsm1.DecodeIntegerBlock(bytes, &decodedValues)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
}
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
func BenchmarkDecodeStringBlock(b *testing.B) {
|
|
cases := []int{
|
|
5,
|
|
55,
|
|
555,
|
|
1000,
|
|
}
|
|
for _, n := range cases {
|
|
b.Run(fmt.Sprintf("%d", n), func(b *testing.B) {
|
|
valueCount := n
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
values := make([]tsm1.Value, len(times))
|
|
for i, t := range times {
|
|
values[i] = tsm1.NewValue(t, fmt.Sprintf("value %d", i))
|
|
}
|
|
|
|
bytes, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
b.SetBytes(int64(tsm1.Values(values).Size()))
|
|
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
decodedValues := make([]tsm1.StringValue, len(values))
|
|
|
|
for pb.Next() {
|
|
_, err = tsm1.DecodeStringBlock(bytes, &decodedValues)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
}
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
func BenchmarkDecodeBlock_String_Empty(b *testing.B) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
values := make([]tsm1.Value, len(times))
|
|
for i, t := range times {
|
|
values[i] = tsm1.NewValue(t, fmt.Sprintf("value %d", i))
|
|
}
|
|
|
|
bytes, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
var decodedValues []tsm1.Value
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_, err = tsm1.DecodeBlock(bytes, decodedValues)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkDecodeBlock_String_EqualSize(b *testing.B) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
values := make([]tsm1.Value, len(times))
|
|
for i, t := range times {
|
|
values[i] = tsm1.NewValue(t, fmt.Sprintf("value %d", i))
|
|
}
|
|
|
|
bytes, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
decodedValues := make([]tsm1.Value, len(values))
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_, err = tsm1.DecodeBlock(bytes, decodedValues)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkDecodeBlock_String_TypeSpecific(b *testing.B) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
values := make([]tsm1.Value, len(times))
|
|
for i, t := range times {
|
|
values[i] = tsm1.NewValue(t, fmt.Sprintf("value %d", i))
|
|
}
|
|
|
|
bytes, err := tsm1.Values(values).Encode(nil)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error: %v", err)
|
|
}
|
|
|
|
decodedValues := make([]tsm1.StringValue, len(values))
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_, err = tsm1.DecodeStringBlock(bytes, &decodedValues)
|
|
if err != nil {
|
|
b.Fatalf("unexpected error decoding block: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkValues_Deduplicate(b *testing.B) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
values := make([]tsm1.Value, len(times))
|
|
for i, t := range times {
|
|
values[i] = tsm1.NewValue(t, fmt.Sprintf("value %d", i))
|
|
}
|
|
values = append(values, values...)
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
tsm1.Values(values).Deduplicate()
|
|
}
|
|
}
|
|
|
|
func BenchmarkValues_Merge(b *testing.B) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
a := make([]tsm1.Value, len(times))
|
|
c := make([]tsm1.Value, len(times))
|
|
|
|
for i, t := range times {
|
|
a[i] = tsm1.NewValue(t, float64(i))
|
|
c[i] = tsm1.NewValue(t+1, float64(i))
|
|
}
|
|
|
|
b.ResetTimer()
|
|
benchmarkMerge(a, c, b)
|
|
}
|
|
|
|
func BenchmarkValues_MergeDisjoint(b *testing.B) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
a := make([]tsm1.Value, len(times))
|
|
c := make([]tsm1.Value, len(times))
|
|
|
|
for i, t := range times {
|
|
a[i] = tsm1.NewValue(t, float64(i))
|
|
c[i] = tsm1.NewValue(times[len(times)-1]+int64((i+1)*1e9), float64(i))
|
|
}
|
|
|
|
b.ResetTimer()
|
|
benchmarkMerge(a, c, b)
|
|
}
|
|
|
|
func BenchmarkValues_MergeSame(b *testing.B) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
a := make([]tsm1.Value, len(times))
|
|
c := make([]tsm1.Value, len(times))
|
|
|
|
for i, t := range times {
|
|
a[i] = tsm1.NewValue(t, float64(i))
|
|
c[i] = tsm1.NewValue(t, float64(i))
|
|
}
|
|
|
|
b.ResetTimer()
|
|
benchmarkMerge(a, c, b)
|
|
}
|
|
|
|
func BenchmarkValues_MergeSimilar(b *testing.B) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
a := make([]tsm1.Value, len(times))
|
|
c := make([]tsm1.Value, len(times))
|
|
|
|
for i, t := range times {
|
|
a[i] = tsm1.NewValue(t, float64(i))
|
|
if i == 0 {
|
|
t++
|
|
}
|
|
c[i] = tsm1.NewValue(t, float64(i))
|
|
}
|
|
|
|
b.ResetTimer()
|
|
benchmarkMerge(a, c, b)
|
|
}
|
|
|
|
func BenchmarkValues_MergeUnevenA(b *testing.B) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
a := make([]tsm1.Value, len(times))
|
|
c := make([]tsm1.Value, len(times))
|
|
|
|
for i, t := range times {
|
|
a[i] = tsm1.NewValue(t, float64(i))
|
|
c[i] = tsm1.NewValue(t, float64(i))
|
|
}
|
|
|
|
b.ResetTimer()
|
|
benchmarkMerge(a[:700], c[:10], b)
|
|
}
|
|
|
|
func BenchmarkValues_MergeUnevenB(b *testing.B) {
|
|
valueCount := 1000
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
a := make([]tsm1.Value, len(times))
|
|
c := make([]tsm1.Value, len(times))
|
|
|
|
for i, t := range times {
|
|
a[i] = tsm1.NewValue(t, float64(i))
|
|
c[i] = tsm1.NewValue(t, float64(i))
|
|
}
|
|
|
|
b.ResetTimer()
|
|
benchmarkMerge(a[:10], c[:700], b)
|
|
}
|
|
|
|
func benchmarkMerge(a, c tsm1.Values, b *testing.B) {
|
|
for i := 0; i < b.N; i++ {
|
|
b.StopTimer()
|
|
aa := make(tsm1.Values, len(a))
|
|
copy(aa, a)
|
|
cc := make(tsm1.Values, len(c))
|
|
copy(cc, c)
|
|
b.StartTimer()
|
|
tsm1.Values(aa).Merge(tsm1.Values(cc))
|
|
}
|
|
}
|
|
|
|
func BenchmarkValues_EncodeInteger(b *testing.B) {
|
|
valueCount := 1024
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
a := make([]tsm1.Value, len(times))
|
|
|
|
for i, t := range times {
|
|
a[i] = tsm1.NewValue(t, int64(i))
|
|
}
|
|
|
|
buf := make([]byte, 1024*8)
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
tsm1.Values(a).Encode(buf)
|
|
}
|
|
}
|
|
|
|
func BenchmarkValues_EncodeFloat(b *testing.B) {
|
|
valueCount := 1024
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
a := make([]tsm1.Value, len(times))
|
|
|
|
for i, t := range times {
|
|
a[i] = tsm1.NewValue(t, float64(i))
|
|
}
|
|
|
|
buf := make([]byte, 1024*8)
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
tsm1.Values(a).Encode(buf)
|
|
}
|
|
}
|
|
func BenchmarkValues_EncodeString(b *testing.B) {
|
|
valueCount := 1024
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
a := make([]tsm1.Value, len(times))
|
|
|
|
for i, t := range times {
|
|
a[i] = tsm1.NewValue(t, fmt.Sprintf("%d", i))
|
|
}
|
|
|
|
buf := make([]byte, 1024*8)
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
tsm1.Values(a).Encode(buf)
|
|
}
|
|
}
|
|
func BenchmarkValues_EncodeBool(b *testing.B) {
|
|
valueCount := 1024
|
|
times := getTimes(valueCount, 60, time.Second)
|
|
a := make([]tsm1.Value, len(times))
|
|
|
|
for i, t := range times {
|
|
if i%2 == 0 {
|
|
a[i] = tsm1.NewValue(t, true)
|
|
} else {
|
|
a[i] = tsm1.NewValue(t, false)
|
|
}
|
|
}
|
|
|
|
buf := make([]byte, 1024*8)
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
tsm1.Values(a).Encode(buf)
|
|
}
|
|
}
|