From 9e1f34dae309f998def5d48f35b1d597bb9928e1 Mon Sep 17 00:00:00 2001 From: Goutham Veeramachaneni Date: Tue, 13 Jun 2017 11:24:04 +0530 Subject: [PATCH 1/2] Fix bug with Seek() and optimise bounding params. Signed-off-by: Goutham Veeramachaneni --- querier.go | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/querier.go b/querier.go index 601fc7440..cf694a668 100644 --- a/querier.go +++ b/querier.go @@ -657,10 +657,6 @@ func newChunkSeriesIterator(cs []*ChunkMeta, dranges intervals, mint, maxt int64 } } -func (it *chunkSeriesIterator) inBounds(t int64) bool { - return t >= it.mint && t <= it.maxt -} - func (it *chunkSeriesIterator) Seek(t int64) (ok bool) { if t > it.maxt { return false @@ -673,7 +669,9 @@ func (it *chunkSeriesIterator) Seek(t int64) (ok bool) { // Only do binary search forward to stay in line with other iterators // that can only move forward. - x := sort.Search(len(it.chunks[it.i:]), func(i int) bool { return it.chunks[i].MinTime >= t }) + x := sort.Search(len(it.chunks[it.i:]), func(i int) bool { + return it.chunks[it.i+i].MinTime >= t + }) x += it.i // If the timestamp was not found, it might be in the last chunk. @@ -708,9 +706,15 @@ func (it *chunkSeriesIterator) At() (t int64, v float64) { func (it *chunkSeriesIterator) Next() bool { for it.cur.Next() { t, _ := it.cur.At() - if it.inBounds(t) { - return true + if t < it.mint { + return it.Seek(it.mint) } + + if t > it.maxt { + return false + } + + return true } if err := it.cur.Err(); err != nil { From a280169427e6f4326e480d319b42ffbfc1f87b14 Mon Sep 17 00:00:00 2001 From: Goutham Veeramachaneni Date: Tue, 13 Jun 2017 13:21:22 +0530 Subject: [PATCH 2/2] Add regression test Signed-off-by: Goutham Veeramachaneni --- querier_test.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/querier_test.go b/querier_test.go index e03570fad..ed504da39 100644 --- a/querier_test.go +++ b/querier_test.go @@ -1027,6 +1027,22 @@ func TestSeriesIterator(t *testing.T) { return } +// Regression for: https://github.com/prometheus/tsdb/pull/97 +func TestCSIteratorDoubleSeek(t *testing.T) { + chkMetas := []*ChunkMeta{ + chunkFromSamples([]sample{}), + chunkFromSamples([]sample{{1, 1}, {2, 2}, {3, 3}}), + chunkFromSamples([]sample{{4, 4}, {5, 5}}), + } + + res := newChunkSeriesIterator(chkMetas, nil, 2, 8) + require.True(t, res.Seek(1)) + require.True(t, res.Seek(2)) + ts, v := res.At() + require.Equal(t, int64(2), ts) + require.Equal(t, float64(2), v) +} + func TestPopulatedCSReturnsValidChunkSlice(t *testing.T) { lbls := []labels.Labels{labels.New(labels.Label{"a", "b"})} chunkMetas := [][]*ChunkMeta{