Files
traces/tempodb/encoding/vparquet5/multiblock_iterator_test.go
Martin DisibioandGitHub 8e57f1972c vParquet5 Preview 1 - low resolution timestamp columns (#5495)
* Experiments with next parquet version. Added rounded start time column

* Vparquet5 use lower precision timestamp column when possible based on step interval

* microoptimization

* leftjoiniterator use dynamic branch reordering, plus other performance improvements

* Add columns with other granularities

* Add new functionality: nocompactflg and short trace ID search

* Fix handling of large step intervals and split between backend and generator requests

* Repair tests and reduce divergence from main

* Cleanup, separate benchmark env vars

* Set version string to preview

* rename/comments

* Oops undo change to default encoding

* Fix tests and lint

* Bring in more updates from vparquet4

* Improve accuracy of estimate function, cleanup debug statements

* Reduce diff from main

* lint

* Add test parquet file

* Fix to maintain nano-second precision for blocks overlapping query range edges and recent/backend handoff where things don't align

* Fix tests after merging main, one more fix to maintain nanosecond precision when needed

* changelog

* Cleanup/reduce diff from main

* Review feedback
2025-08-18 15:06:58 -04:00

97 lines
2.2 KiB
Go

package vparquet5
import (
"context"
"errors"
"io"
"testing"
"github.com/stretchr/testify/require"
"github.com/grafana/tempo/tempodb/encoding/common"
)
type intIterator []*uint8 // making this a pointer makes the below code a little gross but allows multiblockiterator to treat all types as nillable
func (i *intIterator) Next(_ context.Context) (common.ID, *uint8, error) {
s := *i
if len(s) == 0 {
return nil, nil, io.EOF
}
ret := s[0]
*i = s[1:]
return []byte{*ret}, ret, nil
}
func (i *intIterator) Close() {}
func (i *intIterator) peekNextID(_ context.Context) (common.ID, error) { //nolint:unused //this is being marked as unused, but it's literally used about 30 lines south
s := *i
if len(s) == 0 {
return nil, io.EOF
}
return []byte{*s[0]}, nil
}
func TestMultiBlockIterator(t *testing.T) {
ptr := func(n uint8) *uint8 {
return &n
}
tcs := []struct {
iters []*intIterator
expected []uint8
}{
{
iters: []*intIterator{{}},
expected: []uint8{},
},
{
iters: []*intIterator{{}, {}},
expected: []uint8{},
},
{
iters: []*intIterator{{ptr(1), ptr(2), ptr(3)}, {ptr(4), ptr(5), ptr(6)}},
expected: []uint8{1, 2, 3, 4, 5, 6},
},
{
iters: []*intIterator{{ptr(1), ptr(3), ptr(5)}, {ptr(2), ptr(4), ptr(6)}},
expected: []uint8{1, 2, 3, 4, 5, 6},
},
{
iters: []*intIterator{{ptr(1), ptr(3)}, {ptr(2), ptr(6)}, {ptr(4), ptr(5)}},
expected: []uint8{1, 2, 3, 4, 5, 6},
},
{
iters: []*intIterator{{ptr(1), ptr(3)}, {ptr(1), ptr(6)}, {ptr(4), ptr(6)}},
expected: []uint8{1, 3, 4, 6},
},
}
for _, tc := range tcs {
bookmarks := make([]*bookmark[*uint8], 0, len(tc.iters))
for _, iter := range tc.iters {
bookmarks = append(bookmarks, newBookmark[*uint8](iter))
}
mbi := newMultiblockIterator(bookmarks, func(i []*uint8) (*uint8, error) {
return i[0], nil
})
defer mbi.Close()
ctx := context.Background()
for {
id, val, err := mbi.Next(ctx)
if errors.Is(err, io.EOF) {
break
}
require.NoError(t, err)
require.Equal(t, common.ID([]byte{tc.expected[0]}), id)
require.Equal(t, tc.expected[0], *val)
tc.expected = tc.expected[1:]
}
require.Len(t, tc.expected, 0)
}
}