Reuse float histogram objects

This commit reduces the memory needed to query native histogram objects
by reusing existing HPoint instances.

Signed-off-by: Filip Petkovski <filip.petkovsky@gmail.com>
This commit is contained in:
Filip Petkovski 2023-12-10 21:07:19 +01:00
parent db915b07cb
commit e2a9f8ac0f
No known key found for this signature in database
GPG Key ID: 431B0F2E85E42402
3 changed files with 28 additions and 17 deletions

View File

@ -2078,21 +2078,27 @@ loop:
case chunkenc.ValNone: case chunkenc.ValNone:
break loop break loop
case chunkenc.ValFloatHistogram, chunkenc.ValHistogram: case chunkenc.ValFloatHistogram, chunkenc.ValHistogram:
t, h := buf.AtFloatHistogram() t := buf.AtT()
if value.IsStaleNaN(h.Sum) {
continue loop
}
// Values in the buffer are guaranteed to be smaller than maxt. // Values in the buffer are guaranteed to be smaller than maxt.
if t >= mintHistograms { if t >= mintHistograms {
if ev.currentSamples >= ev.maxSamples {
ev.error(ErrTooManySamples(env))
}
point := HPoint{T: t, H: h}
if histograms == nil { if histograms == nil {
histograms = getHPointSlice(16) histograms = getHPointSlice(16)
} }
histograms = append(histograms, point) n := len(histograms)
ev.currentSamples += point.size() if n < cap(histograms) {
histograms = histograms[:n+1]
} else {
histograms = append(histograms, HPoint{})
}
histograms[n].T, histograms[n].H = buf.AtFloatHistogram(histograms[n].H)
if value.IsStaleNaN(histograms[n].H.Sum) {
histograms = histograms[:n]
continue loop
}
if ev.currentSamples >= ev.maxSamples {
ev.error(ErrTooManySamples(env))
}
ev.currentSamples += histograms[n].size()
} }
case chunkenc.ValFloat: case chunkenc.ValFloat:
t, f := buf.At() t, f := buf.At()
@ -2108,7 +2114,12 @@ loop:
if floats == nil { if floats == nil {
floats = getFPointSlice(16) floats = getFPointSlice(16)
} }
floats = append(floats, FPoint{T: t, F: f}) if n := len(floats); n < cap(floats) {
floats = floats[:n+1]
floats[n].T, floats[n].F = t, f
} else {
floats = append(floats, FPoint{T: t, F: f})
}
} }
} }
} }

View File

@ -74,7 +74,7 @@ func (b *BufferedSeriesIterator) PeekBack(n int) (sample chunks.Sample, ok bool)
// Buffer returns an iterator over the buffered data. Invalidates previously // Buffer returns an iterator over the buffered data. Invalidates previously
// returned iterators. // returned iterators.
func (b *BufferedSeriesIterator) Buffer() chunkenc.Iterator { func (b *BufferedSeriesIterator) Buffer() *sampleRingIterator {
return b.buf.iterator() return b.buf.iterator()
} }
@ -304,7 +304,7 @@ func (r *sampleRing) reset() {
} }
// Returns the current iterator. Invalidates previously returned iterators. // Returns the current iterator. Invalidates previously returned iterators.
func (r *sampleRing) iterator() chunkenc.Iterator { func (r *sampleRing) iterator() *sampleRingIterator {
r.it.r = r r.it.r = r
r.it.i = -1 r.it.i = -1
return &r.it return &r.it
@ -374,9 +374,9 @@ func (it *sampleRingIterator) AtHistogram() (int64, *histogram.Histogram) {
return it.t, it.h return it.t, it.h
} }
func (it *sampleRingIterator) AtFloatHistogram() (int64, *histogram.FloatHistogram) { func (it *sampleRingIterator) AtFloatHistogram(fh *histogram.FloatHistogram) (int64, *histogram.FloatHistogram) {
if it.fh == nil { if it.fh == nil {
return it.t, it.h.ToFloat(nil) return it.t, it.h.ToFloat(fh)
} }
return it.t, it.fh return it.t, it.fh
} }

View File

@ -243,11 +243,11 @@ func TestBufferedSeriesIteratorMixedHistograms(t *testing.T) {
buf := it.Buffer() buf := it.Buffer()
require.Equal(t, chunkenc.ValFloatHistogram, buf.Next()) require.Equal(t, chunkenc.ValFloatHistogram, buf.Next())
_, fh := buf.AtFloatHistogram() _, fh := buf.AtFloatHistogram(nil)
require.Equal(t, histograms[0].ToFloat(nil), fh) require.Equal(t, histograms[0].ToFloat(nil), fh)
require.Equal(t, chunkenc.ValHistogram, buf.Next()) require.Equal(t, chunkenc.ValHistogram, buf.Next())
_, fh = buf.AtFloatHistogram() _, fh = buf.AtFloatHistogram(nil)
require.Equal(t, histograms[1].ToFloat(nil), fh) require.Equal(t, histograms[1].ToFloat(nil), fh)
} }