2017-04-10 20:59:45 +02: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 15:34:49 +01:00
package chunkenc
2016-11-15 10:33:34 +01:00
import (
"fmt"
"io"
"math/rand"
"testing"
2019-08-14 10:07:02 +01:00
"github.com/prometheus/prometheus/util/testutil"
2016-11-15 10:33:34 +01:00
)
2016-11-29 22:02:58 +01:00
type pair struct {
t int64
v float64
2016-11-15 10:33:34 +01:00
}
2016-11-29 22:43:24 +01:00
func TestChunk ( t * testing . T ) {
2016-12-31 10:10:27 +01:00
for enc , nc := range map [ Encoding ] func ( ) Chunk {
EncXOR : func ( ) Chunk { return NewXORChunk ( ) } ,
2016-11-29 22:43:24 +01:00
} {
2019-01-07 12:39:11 +01:00
t . Run ( fmt . Sprintf ( "%v" , enc ) , func ( t * testing . T ) {
2016-11-30 23:01:01 +01:00
for range make ( [ ] struct { } , 1 ) {
2016-12-31 10:10:27 +01:00
c := nc ( )
2020-02-06 15:58:38 +00:00
testChunk ( t , c )
2016-11-29 22:43:24 +01:00
}
} )
}
}
2020-02-06 15:58:38 +00:00
func testChunk ( t * testing . T , c Chunk ) {
2016-11-29 22:43:24 +01:00
app , err := c . Appender ( )
2020-02-06 15:58:38 +00:00
testutil . Ok ( t , err )
2016-11-29 22:43:24 +01:00
var exp [ ] pair
var (
ts = int64 ( 1234123324 )
v = 1243535.123
)
2016-12-08 10:04:24 +01:00
for i := 0 ; i < 300 ; i ++ {
2016-11-29 22:43:24 +01:00
ts += int64 ( rand . Intn ( 10000 ) + 1 )
2016-11-30 23:01:01 +01:00
if i % 2 == 0 {
v += float64 ( rand . Intn ( 1000000 ) )
} else {
v -= float64 ( rand . Intn ( 1000000 ) )
}
2016-11-30 19:08:28 +01: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 ( )
2020-02-06 15:58:38 +00:00
testutil . Ok ( t , err )
2016-11-30 19:08:28 +01:00
}
2016-11-29 22:43:24 +01:00
2016-12-31 10:10:27 +01:00
app . Append ( ts , v )
2016-11-29 22:43:24 +01:00
exp = append ( exp , pair { t : ts , v : v } )
}
2020-02-06 15:58:38 +00:00
// 1. Expand iterator in simple case.
it1 := c . Iterator ( nil )
var res1 [ ] pair
for it1 . Next ( ) {
ts , v := it1 . At ( )
res1 = append ( res1 , pair { t : ts , v : v } )
2016-11-29 22:43:24 +01:00
}
2020-02-06 15:58:38 +00:00
testutil . Ok ( t , it1 . Err ( ) )
testutil . Equals ( t , exp , res1 )
// 2. Expand second iterator while reusing first one.
it2 := c . Iterator ( it1 )
var res2 [ ] pair
for it2 . Next ( ) {
ts , v := it2 . At ( )
res2 = append ( res2 , pair { t : ts , v : v } )
2016-11-29 22:43:24 +01:00
}
2020-02-06 15:58:38 +00:00
testutil . Ok ( t , it2 . Err ( ) )
testutil . Equals ( t , exp , res2 )
2020-02-11 16:34:09 +00:00
// 3. Test iterator Seek.
2020-02-06 15:58:38 +00:00
mid := len ( exp ) / 2
it3 := c . Iterator ( nil )
var res3 [ ] pair
testutil . Equals ( t , true , it3 . Seek ( exp [ mid ] . t ) )
// Below ones should not matter.
testutil . Equals ( t , true , it3 . Seek ( exp [ mid ] . t ) )
testutil . Equals ( t , true , it3 . Seek ( exp [ mid ] . t ) )
ts , v = it3 . At ( )
res3 = append ( res3 , pair { t : ts , v : v } )
for it3 . Next ( ) {
ts , v := it3 . At ( )
res3 = append ( res3 , pair { t : ts , v : v } )
2016-11-29 22:43:24 +01:00
}
2020-02-06 15:58:38 +00:00
testutil . Ok ( t , it3 . Err ( ) )
testutil . Equals ( t , exp [ mid : ] , res3 )
testutil . Equals ( t , false , it3 . Seek ( exp [ len ( exp ) - 1 ] . t + 1 ) )
2016-11-29 22:43:24 +01:00
}
2016-12-31 10:10:27 +01:00
func benchmarkIterator ( b * testing . B , newChunk func ( ) Chunk ) {
2016-11-15 10:33:34 +01:00
var (
2020-03-24 20:15:47 +00:00
t = int64 ( 1234123324 )
v = 1243535.123
exp [ ] pair
2016-11-15 10:33:34 +01:00
)
for i := 0 ; i < b . N ; i ++ {
2017-01-02 22:24:35 +01:00
// t += int64(rand.Intn(10000) + 1)
t += int64 ( 1000 )
2016-11-30 19:08:28 +01:00
// v = rand.Float64()
2016-12-07 15:37:37 +01:00
v += float64 ( 100 )
2016-11-29 22:02:58 +01:00
exp = append ( exp , pair { t : t , v : v } )
2016-11-15 10:33:34 +01:00
}
2016-11-29 22:02:58 +01:00
2016-11-15 10:33:34 +01:00
var chunks [ ] Chunk
for i := 0 ; i < b . N ; {
2016-12-31 10:10:27 +01:00
c := newChunk ( )
2016-11-29 22:02:58 +01:00
a , err := c . Appender ( )
if err != nil {
b . Fatalf ( "get appender: %s" , err )
}
2016-12-31 10:10:27 +01:00
j := 0
2016-11-29 22:02:58 +01:00
for _ , p := range exp {
2016-12-31 10:10:27 +01:00
if j > 250 {
2016-11-15 10:33:34 +01:00
break
}
2016-12-31 10:10:27 +01:00
a . Append ( p . t , p . v )
2016-11-15 10:33:34 +01:00
i ++
2016-12-31 10:10:27 +01:00
j ++
2016-11-15 10:33:34 +01:00
}
chunks = append ( chunks , c )
}
b . ReportAllocs ( )
b . ResetTimer ( )
2020-03-24 20:15:47 +00:00
b . Log ( "num" , b . N , "created chunks" , len ( chunks ) )
2016-11-29 22:02:58 +01:00
res := make ( [ ] float64 , 0 , 1024 )
2019-07-09 15:19:34 +05:30
var it Iterator
2016-11-15 10:33:34 +01:00
for i := 0 ; i < len ( chunks ) ; i ++ {
c := chunks [ i ]
2019-07-09 15:19:34 +05:30
it := c . Iterator ( it )
2016-11-15 10:33:34 +01:00
2016-11-29 22:02:58 +01:00
for it . Next ( ) {
2017-01-02 13:27:52 +01:00
_ , v := it . At ( )
2016-11-29 22:02:58 +01:00
res = append ( res , v )
2016-11-15 10:33:34 +01:00
}
if it . Err ( ) != io . EOF {
2017-12-06 19:05:58 -08:00
testutil . Ok ( b , it . Err ( ) )
2016-11-15 10:33:34 +01:00
}
res = res [ : 0 ]
}
}
2016-11-20 14:33:00 +01:00
func BenchmarkXORIterator ( b * testing . B ) {
2016-12-31 10:10:27 +01:00
benchmarkIterator ( b , func ( ) Chunk {
return NewXORChunk ( )
2016-11-20 14:33:00 +01:00
} )
}
func BenchmarkXORAppender ( b * testing . B ) {
2016-12-31 10:10:27 +01:00
benchmarkAppender ( b , func ( ) Chunk {
return NewXORChunk ( )
2016-11-20 14:33:00 +01:00
} )
}
2016-12-31 10:10:27 +01:00
func benchmarkAppender ( b * testing . B , newChunk func ( ) Chunk ) {
2016-11-15 10:33:34 +01:00
var (
2016-11-29 22:02:58 +01:00
t = int64 ( 1234123324 )
v = 1243535.123
2016-11-15 10:33:34 +01:00
)
2016-11-29 22:02:58 +01:00
var exp [ ] pair
2016-11-15 10:33:34 +01:00
for i := 0 ; i < b . N ; i ++ {
2017-01-02 22:24:35 +01:00
// t += int64(rand.Intn(10000) + 1)
t += int64 ( 1000 )
2016-11-30 19:08:28 +01:00
// v = rand.Float64()
2016-12-07 15:37:37 +01:00
v += float64 ( 100 )
2016-11-29 22:02:58 +01:00
exp = append ( exp , pair { t : t , v : v } )
2016-11-15 10:33:34 +01:00
}
b . ReportAllocs ( )
b . ResetTimer ( )
var chunks [ ] Chunk
for i := 0 ; i < b . N ; {
2016-12-31 10:10:27 +01:00
c := newChunk ( )
2016-11-29 22:02:58 +01:00
a , err := c . Appender ( )
if err != nil {
b . Fatalf ( "get appender: %s" , err )
}
2016-12-31 10:10:27 +01:00
j := 0
2016-11-29 22:02:58 +01:00
for _ , p := range exp {
2016-12-31 10:10:27 +01:00
if j > 250 {
2016-11-15 10:33:34 +01:00
break
}
2016-12-31 10:10:27 +01:00
a . Append ( p . t , p . v )
2016-11-15 10:33:34 +01:00
i ++
2016-12-31 10:10:27 +01:00
j ++
2016-11-15 10:33:34 +01:00
}
chunks = append ( chunks , c )
}
2016-11-29 22:02:58 +01:00
fmt . Println ( "num" , b . N , "created chunks" , len ( chunks ) )
2016-11-15 10:33:34 +01:00
}