2017-04-10 18:59:45 +00:00
|
|
|
// Copyright 2017 The Prometheus Authors
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
2017-11-30 14:34:49 +00:00
|
|
|
package chunkenc
|
2016-11-15 09:33:34 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"math/rand"
|
2016-11-29 21:43:24 +00:00
|
|
|
"reflect"
|
2016-11-15 09:33:34 +00:00
|
|
|
"testing"
|
|
|
|
|
2017-12-07 03:05:58 +00:00
|
|
|
"github.com/prometheus/tsdb/testutil"
|
2016-11-15 09:33:34 +00:00
|
|
|
)
|
|
|
|
|
2016-11-29 21:02:58 +00:00
|
|
|
type pair struct {
|
|
|
|
t int64
|
|
|
|
v float64
|
2016-11-15 09:33:34 +00:00
|
|
|
}
|
|
|
|
|
2016-11-29 21:43:24 +00:00
|
|
|
func TestChunk(t *testing.T) {
|
2016-12-31 09:10:27 +00:00
|
|
|
for enc, nc := range map[Encoding]func() Chunk{
|
|
|
|
EncXOR: func() Chunk { return NewXORChunk() },
|
2016-11-29 21:43:24 +00:00
|
|
|
} {
|
2019-01-04 14:45:50 +00:00
|
|
|
t.Run(fmt.Sprintf("%d", enc), func(t *testing.T) {
|
2016-11-30 22:01:01 +00:00
|
|
|
for range make([]struct{}, 1) {
|
2016-12-31 09:10:27 +00:00
|
|
|
c := nc()
|
2016-11-30 18:08:28 +00:00
|
|
|
if err := testChunk(c); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2016-11-29 21:43:24 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-30 18:08:28 +00:00
|
|
|
func testChunk(c Chunk) error {
|
2016-11-29 21:43:24 +00:00
|
|
|
app, err := c.Appender()
|
|
|
|
if err != nil {
|
2016-11-30 18:08:28 +00:00
|
|
|
return err
|
2016-11-29 21:43:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var exp []pair
|
|
|
|
var (
|
|
|
|
ts = int64(1234123324)
|
|
|
|
v = 1243535.123
|
|
|
|
)
|
2016-12-08 09:04:24 +00:00
|
|
|
for i := 0; i < 300; i++ {
|
2016-11-29 21:43:24 +00:00
|
|
|
ts += int64(rand.Intn(10000) + 1)
|
2016-11-30 22:01:01 +00:00
|
|
|
// v = rand.Float64()
|
|
|
|
if i%2 == 0 {
|
|
|
|
v += float64(rand.Intn(1000000))
|
|
|
|
} else {
|
|
|
|
v -= float64(rand.Intn(1000000))
|
|
|
|
}
|
2016-11-30 18:08:28 +00:00
|
|
|
|
|
|
|
// Start with a new appender every 10th sample. This emulates starting
|
|
|
|
// appending to a partially filled chunk.
|
|
|
|
if i%10 == 0 {
|
|
|
|
app, err = c.Appender()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
2016-11-29 21:43:24 +00:00
|
|
|
|
2016-12-31 09:10:27 +00:00
|
|
|
app.Append(ts, v)
|
2016-11-29 21:43:24 +00:00
|
|
|
exp = append(exp, pair{t: ts, v: v})
|
2016-11-30 18:08:28 +00:00
|
|
|
// fmt.Println("appended", len(c.Bytes()), c.Bytes())
|
2016-11-29 21:43:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
it := c.Iterator()
|
|
|
|
var res []pair
|
|
|
|
for it.Next() {
|
2017-01-02 12:27:52 +00:00
|
|
|
ts, v := it.At()
|
2016-11-29 21:43:24 +00:00
|
|
|
res = append(res, pair{t: ts, v: v})
|
|
|
|
}
|
|
|
|
if it.Err() != nil {
|
2016-11-30 18:08:28 +00:00
|
|
|
return it.Err()
|
2016-11-29 21:43:24 +00:00
|
|
|
}
|
|
|
|
if !reflect.DeepEqual(exp, res) {
|
2016-11-30 18:08:28 +00:00
|
|
|
return fmt.Errorf("unexpected result\n\ngot: %v\n\nexp: %v", res, exp)
|
2016-11-29 21:43:24 +00:00
|
|
|
}
|
2016-11-30 18:08:28 +00:00
|
|
|
return nil
|
2016-11-29 21:43:24 +00:00
|
|
|
}
|
|
|
|
|
2016-12-31 09:10:27 +00:00
|
|
|
func benchmarkIterator(b *testing.B, newChunk func() Chunk) {
|
2016-11-15 09:33:34 +00:00
|
|
|
var (
|
2016-11-29 21:02:58 +00:00
|
|
|
t = int64(1234123324)
|
|
|
|
v = 1243535.123
|
2016-11-15 09:33:34 +00:00
|
|
|
)
|
2016-11-29 21:02:58 +00:00
|
|
|
var exp []pair
|
2016-11-15 09:33:34 +00:00
|
|
|
for i := 0; i < b.N; i++ {
|
2017-01-02 21:24:35 +00:00
|
|
|
// t += int64(rand.Intn(10000) + 1)
|
|
|
|
t += int64(1000)
|
2016-11-30 18:08:28 +00:00
|
|
|
// v = rand.Float64()
|
2016-12-07 14:37:37 +00:00
|
|
|
v += float64(100)
|
2016-11-29 21:02:58 +00:00
|
|
|
exp = append(exp, pair{t: t, v: v})
|
2016-11-15 09:33:34 +00:00
|
|
|
}
|
2016-11-29 21:02:58 +00:00
|
|
|
|
2016-11-15 09:33:34 +00:00
|
|
|
var chunks []Chunk
|
|
|
|
for i := 0; i < b.N; {
|
2016-12-31 09:10:27 +00:00
|
|
|
c := newChunk()
|
2016-11-29 21:02:58 +00:00
|
|
|
|
|
|
|
a, err := c.Appender()
|
|
|
|
if err != nil {
|
|
|
|
b.Fatalf("get appender: %s", err)
|
|
|
|
}
|
2016-12-31 09:10:27 +00:00
|
|
|
j := 0
|
2016-11-29 21:02:58 +00:00
|
|
|
for _, p := range exp {
|
2016-12-31 09:10:27 +00:00
|
|
|
if j > 250 {
|
2016-11-15 09:33:34 +00:00
|
|
|
break
|
|
|
|
}
|
2016-12-31 09:10:27 +00:00
|
|
|
a.Append(p.t, p.v)
|
2016-11-15 09:33:34 +00:00
|
|
|
i++
|
2016-12-31 09:10:27 +00:00
|
|
|
j++
|
2016-11-15 09:33:34 +00:00
|
|
|
}
|
|
|
|
chunks = append(chunks, c)
|
|
|
|
}
|
|
|
|
|
|
|
|
b.ReportAllocs()
|
|
|
|
b.ResetTimer()
|
|
|
|
|
2016-11-29 21:02:58 +00:00
|
|
|
fmt.Println("num", b.N, "created chunks", len(chunks))
|
|
|
|
|
|
|
|
res := make([]float64, 0, 1024)
|
|
|
|
|
2016-11-15 09:33:34 +00:00
|
|
|
for i := 0; i < len(chunks); i++ {
|
|
|
|
c := chunks[i]
|
|
|
|
it := c.Iterator()
|
|
|
|
|
2016-11-29 21:02:58 +00:00
|
|
|
for it.Next() {
|
2017-01-02 12:27:52 +00:00
|
|
|
_, v := it.At()
|
2016-11-29 21:02:58 +00:00
|
|
|
res = append(res, v)
|
2016-11-15 09:33:34 +00:00
|
|
|
}
|
|
|
|
if it.Err() != io.EOF {
|
2017-12-07 03:05:58 +00:00
|
|
|
testutil.Ok(b, it.Err())
|
2016-11-15 09:33:34 +00:00
|
|
|
}
|
|
|
|
res = res[:0]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-20 13:33:00 +00:00
|
|
|
func BenchmarkXORIterator(b *testing.B) {
|
2016-12-31 09:10:27 +00:00
|
|
|
benchmarkIterator(b, func() Chunk {
|
|
|
|
return NewXORChunk()
|
2016-11-20 13:33:00 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkXORAppender(b *testing.B) {
|
2016-12-31 09:10:27 +00:00
|
|
|
benchmarkAppender(b, func() Chunk {
|
|
|
|
return NewXORChunk()
|
2016-11-20 13:33:00 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2016-12-31 09:10:27 +00:00
|
|
|
func benchmarkAppender(b *testing.B, newChunk func() Chunk) {
|
2016-11-15 09:33:34 +00:00
|
|
|
var (
|
2016-11-29 21:02:58 +00:00
|
|
|
t = int64(1234123324)
|
|
|
|
v = 1243535.123
|
2016-11-15 09:33:34 +00:00
|
|
|
)
|
2016-11-29 21:02:58 +00:00
|
|
|
var exp []pair
|
2016-11-15 09:33:34 +00:00
|
|
|
for i := 0; i < b.N; i++ {
|
2017-01-02 21:24:35 +00:00
|
|
|
// t += int64(rand.Intn(10000) + 1)
|
|
|
|
t += int64(1000)
|
2016-11-30 18:08:28 +00:00
|
|
|
// v = rand.Float64()
|
2016-12-07 14:37:37 +00:00
|
|
|
v += float64(100)
|
2016-11-29 21:02:58 +00:00
|
|
|
exp = append(exp, pair{t: t, v: v})
|
2016-11-15 09:33:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
b.ReportAllocs()
|
|
|
|
b.ResetTimer()
|
|
|
|
|
|
|
|
var chunks []Chunk
|
|
|
|
for i := 0; i < b.N; {
|
2016-12-31 09:10:27 +00:00
|
|
|
c := newChunk()
|
2016-11-29 21:02:58 +00:00
|
|
|
|
|
|
|
a, err := c.Appender()
|
|
|
|
if err != nil {
|
|
|
|
b.Fatalf("get appender: %s", err)
|
|
|
|
}
|
2016-12-31 09:10:27 +00:00
|
|
|
j := 0
|
2016-11-29 21:02:58 +00:00
|
|
|
for _, p := range exp {
|
2016-12-31 09:10:27 +00:00
|
|
|
if j > 250 {
|
2016-11-15 09:33:34 +00:00
|
|
|
break
|
|
|
|
}
|
2016-12-31 09:10:27 +00:00
|
|
|
a.Append(p.t, p.v)
|
2016-11-15 09:33:34 +00:00
|
|
|
i++
|
2016-12-31 09:10:27 +00:00
|
|
|
j++
|
2016-11-15 09:33:34 +00:00
|
|
|
}
|
|
|
|
chunks = append(chunks, c)
|
|
|
|
}
|
|
|
|
|
2016-11-29 21:02:58 +00:00
|
|
|
fmt.Println("num", b.N, "created chunks", len(chunks))
|
2016-11-15 09:33:34 +00:00
|
|
|
}
|