diff --git a/storage/buffer.go b/storage/buffer.go index b3c789e97d..651e5c83e8 100644 --- a/storage/buffer.go +++ b/storage/buffer.go @@ -306,10 +306,9 @@ func (r *sampleRing) reset() { r.iBuf = r.iBuf[:0] } -// Returns the current iterator. Invalidates previously returned iterators. +// Resets and returns the iterator. Invalidates previously returned iterators. func (r *sampleRing) iterator() *SampleRingIterator { - r.it.r = r - r.it.i = -1 + r.it.reset(r) return &r.it } @@ -324,6 +323,13 @@ type SampleRingIterator struct { fh *histogram.FloatHistogram } +func (it *SampleRingIterator) reset(r *sampleRing) { + it.r = r + it.i = -1 + it.h = nil + it.fh = nil +} + func (it *SampleRingIterator) Next() chunkenc.ValueType { it.i++ if it.i >= it.r.l { diff --git a/storage/buffer_test.go b/storage/buffer_test.go index 61074c2122..1b24e5da22 100644 --- a/storage/buffer_test.go +++ b/storage/buffer_test.go @@ -138,6 +138,69 @@ func TestSampleRingMixed(t *testing.T) { require.Equal(t, chunkenc.ValNone, it.Next()) } +func TestSampleRingAtFloatHistogram(t *testing.T) { + fh1 := tsdbutil.GenerateTestFloatHistogram(1) + fh2 := tsdbutil.GenerateTestFloatHistogram(2) + h1 := tsdbutil.GenerateTestHistogram(3) + h2 := tsdbutil.GenerateTestHistogram(4) + + // With ValNone as the preferred type, nothing should be initialized. + r := newSampleRing(10, 2, chunkenc.ValNone) + require.Zero(t, len(r.fBuf)) + require.Zero(t, len(r.hBuf)) + require.Zero(t, len(r.fhBuf)) + require.Zero(t, len(r.iBuf)) + + var ( + h *histogram.Histogram + fh *histogram.FloatHistogram + ts int64 + ) + + it := r.iterator() + require.Equal(t, chunkenc.ValNone, it.Next()) + + r.addFH(fhSample{t: 1, fh: fh1}) + r.addFH(fhSample{t: 2, fh: fh2}) + + it = r.iterator() + + require.Equal(t, chunkenc.ValFloatHistogram, it.Next()) + ts, fh = it.AtFloatHistogram(fh) + require.Equal(t, int64(1), ts) + require.Equal(t, fh1, fh) + require.Equal(t, chunkenc.ValFloatHistogram, it.Next()) + ts, fh = it.AtFloatHistogram(fh) + require.Equal(t, int64(2), ts) + require.Equal(t, fh2, fh) + require.Equal(t, chunkenc.ValNone, it.Next()) + + r.reset() + it = r.iterator() + require.Equal(t, chunkenc.ValNone, it.Next()) + + r.addH(hSample{t: 3, h: h1}) + r.addH(hSample{t: 4, h: h2}) + + it = r.iterator() + + require.Equal(t, chunkenc.ValHistogram, it.Next()) + ts, h = it.AtHistogram() + require.Equal(t, int64(3), ts) + require.Equal(t, h1, h) + ts, fh = it.AtFloatHistogram(fh) + require.Equal(t, int64(3), ts) + require.Equal(t, h1.ToFloat(nil), fh) + require.Equal(t, chunkenc.ValHistogram, it.Next()) + ts, h = it.AtHistogram() + require.Equal(t, int64(4), ts) + require.Equal(t, h2, h) + ts, fh = it.AtFloatHistogram(fh) + require.Equal(t, int64(4), ts) + require.Equal(t, h2.ToFloat(nil), fh) + require.Equal(t, chunkenc.ValNone, it.Next()) +} + func TestBufferedSeriesIterator(t *testing.T) { var it *BufferedSeriesIterator