diff --git a/tsdb/chunkenc/xxx_xoroptst_test.go b/tsdb/chunkenc/xxx_xoroptst_test.go index f2643813db..9fc9af1c8f 100644 --- a/tsdb/chunkenc/xxx_xoroptst_test.go +++ b/tsdb/chunkenc/xxx_xoroptst_test.go @@ -19,7 +19,75 @@ import ( "github.com/stretchr/testify/require" ) -func TestSTHeader(t *testing.T) { +func TestXorOptSTChunk(t *testing.T) { + testChunkAppenderV2ST( + t, + func() Chunk { + return NewXOROptSTChunk() + }, + func(c Chunk) (AppenderV2, error) { + s := c.(*xorOptSTChunk) + return s.AppenderV2() + }, + ) +} + +func TestXorOptSTChunk_MoreThan127Samples(t *testing.T) { + const afterMax = maxFirstSTChangeOn + 3 + t.Run("zero ST", func(t *testing.T) { + chunk := NewXOROptSTChunk() + app, err := chunk.AppenderV2() + require.NoError(t, err) + for i := 0; i < afterMax; i++ { + app.Append(0, int64(i*10+1), float64(i)*1.5) + } + + it := chunk.Iterator(nil) + for i := 0; i < afterMax; i++ { + require.Equal(t, it.Next(), ValFloat) + st := it.AtST() + ts, v := it.At() + require.Equal(t, int64(0), st) + require.Equal(t, int64(i*10+1), ts) + require.Equal(t, float64(i)*1.5, v) + } + + require.Equal(t, ValNone, it.Next()) + require.NoError(t, it.Err()) + }) + + t.Run("non-zero ST after 127", func(t *testing.T) { + chunk := NewXOROptSTChunk() + app, err := chunk.AppenderV2() + require.NoError(t, err) + for i := 0; i < afterMax; i++ { + st := int64(0) + if i == afterMax-1 { + st = int64((afterMax - 1) * 10) + } + app.Append(st, int64(i*10+1), float64(i)*1.5) + } + + it := chunk.Iterator(nil) + for i := 0; i < afterMax; i++ { + require.Equal(t, it.Next(), ValFloat) + st := it.AtST() + ts, v := it.At() + if i == afterMax-1 { + require.Equal(t, int64((afterMax-1)*10), st) + } else { + require.Equal(t, int64(0), st) + } + require.Equal(t, int64(i*10+1), ts) + require.Equal(t, float64(i)*1.5, v) + } + + require.Equal(t, ValNone, it.Next()) + require.NoError(t, it.Err()) + }) +} + +func TestXorOptSTChunk_STHeader(t *testing.T) { b := make([]byte, 1) writeHeaderFirstSTKnown(b) firstSTKnown, firstSTChangeOn := readSTHeader(b) diff --git a/tsdb/chunkenc/xxx_xorrecoding_test.go b/tsdb/chunkenc/xxx_xorrecoding_test.go index 82a2d2de4e..71340452bd 100644 --- a/tsdb/chunkenc/xxx_xorrecoding_test.go +++ b/tsdb/chunkenc/xxx_xorrecoding_test.go @@ -26,6 +26,19 @@ type sample struct { } func TestXorRecodingChunk(t *testing.T) { + testChunkAppenderV2ST( + t, + func() Chunk { + return NewXorRecodingChunk() + }, + func(c Chunk) (AppenderV2, error) { + s := c.(*xorRecodingChunk) + return s.AppenderV2() + }, + ) +} + +func testChunkAppenderV2ST(t *testing.T, chunkFactory func() Chunk, getAppenderV2 func(c Chunk) (AppenderV2, error)) { t.Run("manual for debugging", func(t *testing.T) { samples := []sample{ {ts: 1000, st: 0, f: 1.5}, @@ -33,8 +46,8 @@ func TestXorRecodingChunk(t *testing.T) { {ts: 3000, st: 0, f: 3.5}, {ts: 4000, st: 0, f: 4.5}, } - chunk := NewXorRecodingChunk() - app, err := chunk.AppenderV2() + chunk := chunkFactory() + app, err := getAppenderV2(chunk) require.NoError(t, err) for _, s := range samples { app.Append(s.st, s.ts, s.f) @@ -53,7 +66,7 @@ func TestXorRecodingChunk(t *testing.T) { require.NoError(t, it.Err()) }) - stTimes := []int64{0, 500, 1500, 2500, 3500} + stTimes := []int64{0, 500, 1000, 1500, 2000, 2500, 3000, 3500, 4000} for numberOfSamples := range 5 { samples := make([]sample, numberOfSamples) sampleSTidx := make([]int, numberOfSamples) @@ -67,8 +80,8 @@ func TestXorRecodingChunk(t *testing.T) { } t.Run(fmt.Sprintf("%v", samples), func(t *testing.T) { - chunk := NewXorRecodingChunk() - app, err := chunk.AppenderV2() + chunk := chunkFactory() + app, err := getAppenderV2(chunk) require.NoError(t, err) for _, s := range samples { app.Append(s.st, s.ts, s.f) @@ -88,7 +101,7 @@ func TestXorRecodingChunk(t *testing.T) { exhausted := true for j := numberOfSamples - 1; j >= 0; j-- { - if sampleSTidx[j] < j+1 { + if sampleSTidx[j] < j+2 { sampleSTidx[j]++ exhausted = false break