Skip to content

Commit

Permalink
Merge pull request #13276 from fpetkovski/reuse-float-histograms
Browse files Browse the repository at this point in the history
Reuse float histogram objects
  • Loading branch information
beorn7 committed Dec 13, 2023
2 parents 1031331 + ea356c4 commit 775de1a
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 30 deletions.
26 changes: 16 additions & 10 deletions promql/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -2078,21 +2078,27 @@ loop:
case chunkenc.ValNone:
break loop
case chunkenc.ValFloatHistogram, chunkenc.ValHistogram:
t, h := buf.AtFloatHistogram()
if value.IsStaleNaN(h.Sum) {
continue loop
}
t := buf.AtT()
// Values in the buffer are guaranteed to be smaller than maxt.
if t >= mintHistograms {
if ev.currentSamples >= ev.maxSamples {
ev.error(ErrTooManySamples(env))
}
point := HPoint{T: t, H: h}
if histograms == nil {
histograms = getHPointSlice(16)
}
histograms = append(histograms, point)
ev.currentSamples += point.size()
n := len(histograms)
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:
t, f := buf.At()
Expand Down
36 changes: 18 additions & 18 deletions storage/buffer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
// returned iterators.
func (b *BufferedSeriesIterator) Buffer() chunkenc.Iterator {
func (b *BufferedSeriesIterator) Buffer() *SampleRingIterator {
return b.buf.iterator()
}

Expand Down Expand Up @@ -252,7 +252,7 @@ type sampleRing struct {
f int // Position of first element in ring buffer.
l int // Number of elements in buffer.

it sampleRingIterator
it SampleRingIterator
}

type bufType int
Expand Down Expand Up @@ -304,13 +304,15 @@ func (r *sampleRing) reset() {
}

// 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.i = -1
return &r.it
}

type sampleRingIterator struct {
// SampleRingIterator is returned by BufferedSeriesIterator.Buffer() and can be
// used to iterate samples buffered in the lookback window.
type SampleRingIterator struct {
r *sampleRing
i int
t int64
Expand All @@ -319,7 +321,7 @@ type sampleRingIterator struct {
fh *histogram.FloatHistogram
}

func (it *sampleRingIterator) Next() chunkenc.ValueType {
func (it *SampleRingIterator) Next() chunkenc.ValueType {
it.i++
if it.i >= it.r.l {
return chunkenc.ValNone
Expand Down Expand Up @@ -358,30 +360,28 @@ func (it *sampleRingIterator) Next() chunkenc.ValueType {
}
}

func (it *sampleRingIterator) Seek(int64) chunkenc.ValueType {
return chunkenc.ValNone
}

func (it *sampleRingIterator) Err() error {
return nil
}

func (it *sampleRingIterator) At() (int64, float64) {
// At returns the current float element of the iterator.
func (it *SampleRingIterator) At() (int64, float64) {
return it.t, it.f
}

func (it *sampleRingIterator) AtHistogram() (int64, *histogram.Histogram) {
// AtHistogram returns the current histogram element of the iterator.
func (it *SampleRingIterator) AtHistogram() (int64, *histogram.Histogram) {
return it.t, it.h
}

func (it *sampleRingIterator) AtFloatHistogram() (int64, *histogram.FloatHistogram) {
// AtFloatHistogram returns the current histogram element of the iterator. If the
// current sample is an integer histogram, it will be converted to a float histogram.
// An optional histogram.FloatHistogram can be provided to avoid allocating a new
// object for the conversion.
func (it *SampleRingIterator) AtFloatHistogram(fh *histogram.FloatHistogram) (int64, *histogram.FloatHistogram) {
if it.fh == nil {
return it.t, it.h.ToFloat(nil)
return it.t, it.h.ToFloat(fh)
}
return it.t, it.fh
}

func (it *sampleRingIterator) AtT() int64 {
func (it *SampleRingIterator) AtT() int64 {
return it.t
}

Expand Down
4 changes: 2 additions & 2 deletions storage/buffer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,11 +243,11 @@ func TestBufferedSeriesIteratorMixedHistograms(t *testing.T) {
buf := it.Buffer()

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, chunkenc.ValHistogram, buf.Next())
_, fh = buf.AtFloatHistogram()
_, fh = buf.AtFloatHistogram(nil)
require.Equal(t, histograms[1].ToFloat(nil), fh)
}

Expand Down

0 comments on commit 775de1a

Please sign in to comment.