1package tsm1_test
2
3import (
4	"fmt"
5	"math/rand"
6	"testing"
7	"time"
8
9	"github.com/google/go-cmp/cmp"
10	"github.com/influxdata/influxdb/tsdb"
11	"github.com/influxdata/influxdb/tsdb/engine/tsm1"
12)
13
14func TestDecodeFloatArrayBlock(t *testing.T) {
15	valueCount := 1000
16	times := getTimes(valueCount, 60, time.Second)
17	values := make(tsm1.FloatValues, len(times))
18	for i, t := range times {
19		values[i] = tsm1.NewFloatValue(t, float64(i)).(tsm1.FloatValue)
20	}
21	exp := tsm1.NewFloatArrayFromValues(values)
22
23	b, err := values.Encode(nil)
24	if err != nil {
25		t.Fatalf("unexpected error: %v", err)
26	}
27
28	got := tsdb.NewFloatArrayLen(exp.Len())
29	tsm1.DecodeFloatArrayBlock(b, got)
30	if !cmp.Equal(got, exp) {
31		t.Fatalf("unexpected values -got/+exp\n%s", cmp.Diff(got, exp))
32	}
33}
34
35func BenchmarkDecodeBooleanArrayBlock(b *testing.B) {
36	cases := []int{
37		5,
38		55,
39		555,
40		1000,
41	}
42	for _, n := range cases {
43		b.Run(fmt.Sprintf("%d", n), func(b *testing.B) {
44			valueCount := n
45			times := getTimes(valueCount, 60, time.Second)
46			values := make([]tsm1.Value, len(times))
47			for i, t := range times {
48				values[i] = tsm1.NewValue(t, true)
49			}
50
51			bytes, err := tsm1.Values(values).Encode(nil)
52			if err != nil {
53				b.Fatalf("unexpected error: %v", err)
54			}
55
56			b.ResetTimer()
57			b.ReportAllocs()
58			b.SetBytes(int64(tsm1.Values(values).Size()))
59
60			b.RunParallel(func(pb *testing.PB) {
61				decodedValues := tsdb.NewBooleanArrayLen(len(values))
62
63				for pb.Next() {
64					err = tsm1.DecodeBooleanArrayBlock(bytes, decodedValues)
65					if err != nil {
66						b.Fatalf("unexpected error decoding block: %v", err)
67					}
68				}
69			})
70		})
71	}
72}
73
74func BenchmarkDecodeFloatArrayBlock(b *testing.B) {
75	cases := []int{
76		5,
77		55,
78		555,
79		1000,
80	}
81	for _, n := range cases {
82		b.Run(fmt.Sprintf("%d", n), func(b *testing.B) {
83			valueCount := n
84			times := getTimes(valueCount, 60, time.Second)
85			values := make([]tsm1.Value, len(times))
86			for i, t := range times {
87				values[i] = tsm1.NewValue(t, float64(i))
88			}
89
90			bytes, err := tsm1.Values(values).Encode(nil)
91			if err != nil {
92				b.Fatalf("unexpected error: %v", err)
93			}
94
95			b.ResetTimer()
96			b.ReportAllocs()
97			b.SetBytes(int64(tsm1.Values(values).Size()))
98
99			b.RunParallel(func(pb *testing.PB) {
100				decodedValues := tsdb.NewFloatArrayLen(len(values))
101
102				for pb.Next() {
103					err = tsm1.DecodeFloatArrayBlock(bytes, decodedValues)
104					if err != nil {
105						b.Fatalf("unexpected error decoding block: %v", err)
106					}
107				}
108			})
109		})
110	}
111}
112
113func BenchmarkDecodeIntegerArrayBlock(b *testing.B) {
114	rle := func(i int) int64 { return int64(i) }
115	s8b := func(i int) int64 { return int64(i + int(rand.Int31n(10))) }
116
117	cases := []struct {
118		enc string
119		gen func(i int) int64
120		n   int
121	}{
122		{enc: "rle", gen: rle, n: 5},
123		{enc: "rle", gen: rle, n: 55},
124		{enc: "rle", gen: rle, n: 555},
125		{enc: "rle", gen: rle, n: 1000},
126		{enc: "s8b", gen: s8b, n: 5},
127		{enc: "s8b", gen: s8b, n: 55},
128		{enc: "s8b", gen: s8b, n: 555},
129		{enc: "s8b", gen: s8b, n: 1000},
130	}
131	for _, bm := range cases {
132		b.Run(fmt.Sprintf("%s_%d", bm.enc, bm.n), func(b *testing.B) {
133			rand.Seed(int64(bm.n * 1e3))
134
135			valueCount := bm.n
136			times := getTimes(valueCount, 60, time.Second)
137			values := make([]tsm1.Value, len(times))
138			for i, t := range times {
139				values[i] = tsm1.NewValue(t, bm.gen(i))
140			}
141
142			bytes, err := tsm1.Values(values).Encode(nil)
143			if err != nil {
144				b.Fatalf("unexpected error: %v", err)
145			}
146
147			b.ResetTimer()
148			b.ReportAllocs()
149			b.SetBytes(int64(tsm1.Values(values).Size()))
150
151			b.RunParallel(func(pb *testing.PB) {
152				decodedValues := tsdb.NewIntegerArrayLen(len(values))
153
154				for pb.Next() {
155					err = tsm1.DecodeIntegerArrayBlock(bytes, decodedValues)
156					if err != nil {
157						b.Fatalf("unexpected error decoding block: %v", err)
158					}
159				}
160			})
161		})
162	}
163}
164
165func BenchmarkDecodeStringArrayBlock(b *testing.B) {
166	cases := []int{
167		5,
168		55,
169		555,
170		1000,
171	}
172	for _, n := range cases {
173		b.Run(fmt.Sprintf("%d", n), func(b *testing.B) {
174			valueCount := n
175			times := getTimes(valueCount, 60, time.Second)
176			values := make([]tsm1.Value, len(times))
177			for i, t := range times {
178				values[i] = tsm1.NewValue(t, fmt.Sprintf("value %d", i))
179			}
180
181			bytes, err := tsm1.Values(values).Encode(nil)
182			if err != nil {
183				b.Fatalf("unexpected error: %v", err)
184			}
185
186			b.ResetTimer()
187			b.ReportAllocs()
188			b.SetBytes(int64(tsm1.Values(values).Size()))
189
190			b.RunParallel(func(pb *testing.PB) {
191				decodedValues := tsdb.NewStringArrayLen(len(values))
192
193				for pb.Next() {
194					err = tsm1.DecodeStringArrayBlock(bytes, decodedValues)
195					if err != nil {
196						b.Fatalf("unexpected error decoding block: %v", err)
197					}
198				}
199			})
200		})
201	}
202}
203