diff --git a/model/histogram/float_histogram.go b/model/histogram/float_histogram.go index 3c394c85e..3cb7fe7da 100644 --- a/model/histogram/float_histogram.go +++ b/model/histogram/float_histogram.go @@ -338,29 +338,30 @@ func (h *FloatHistogram) Equals(h2 *FloatHistogram) bool { return true } -// Size returns the size of the whole fields histogram in bytes. +// Size returns the total size of the FloatHistogram, which includes the size of the pointer +// to FloatHistogram, all its fields, and all elements contained in slices. // NOTE: this is only valid for 64 bit architectures. func (fh *FloatHistogram) Size() int { - // Size of each slice separately - posSpanSize := len(fh.PositiveSpans) * 8 // 8 bytes (int32 + uint32) - negSpanSize := len(fh.NegativeSpans) * 8 // 8 bytes (int32 + uint32) - posBucketSize := len(fh.PositiveBuckets) * 8 // 8 bytes (float64) - negBucketSize := len(fh.NegativeBuckets) * 8 // 8 bytes (float64) + // Size of each slice separately. + posSpanSize := len(fh.PositiveSpans) * 8 // 8 bytes (int32 + uint32). + negSpanSize := len(fh.NegativeSpans) * 8 // 8 bytes (int32 + uint32). + posBucketSize := len(fh.PositiveBuckets) * 8 // 8 bytes (float64). + negBucketSize := len(fh.NegativeBuckets) * 8 // 8 bytes (float64). - // Total size of the struct + // Total size of the struct. - // fh is 8 bytes - // fh.CounterResetHint is 1 byte - // fh.Schema is 4 bytes - // fh.ZeroThreshold is 8 bytes - // fh.ZeroCount is 8 bytes - // fh.Count is 8 bytes - // fh.Sum is 8 bytes - // fh.PositiveSpans is 24 bytes - // fh.NegativeSpans is 24 bytes - // fh.PositiveBuckets is 24 bytes - // fh.NegativeBuckets is 24 bytes - structSize := 141 + // fh is 8 bytes. + // fh.CounterResetHint is 4 bytes (1 byte bool + 3 bytes padding). + // fh.Schema is 4 bytes. + // fh.ZeroThreshold is 8 bytes. + // fh.ZeroCount is 8 bytes. + // fh.Count is 8 bytes. + // fh.Sum is 8 bytes. + // fh.PositiveSpans is 24 bytes. + // fh.NegativeSpans is 24 bytes. + // fh.PositiveBuckets is 24 bytes. + // fh.NegativeBuckets is 24 bytes. + structSize := 144 return structSize + posSpanSize + negSpanSize + posBucketSize + negBucketSize } diff --git a/model/histogram/float_histogram_test.go b/model/histogram/float_histogram_test.go index 7f5c29e3b..d40cecd7a 100644 --- a/model/histogram/float_histogram_test.go +++ b/model/histogram/float_histogram_test.go @@ -2362,7 +2362,7 @@ func TestFloatHistogramSize(t *testing.T) { NegativeSpans: nil, // 24 bytes NegativeBuckets: nil, // 24 bytes }, - 8 + 1 + 4 + 8 + 8 + 8 + 8 + 24 + 24 + 24 + 24, + 8 + 4 + 4 + 8 + 8 + 8 + 8 + 24 + 24 + 24 + 24, }, { "complete struct", @@ -2383,7 +2383,7 @@ func TestFloatHistogramSize(t *testing.T) { {3, 2}}, // 2 * 4 bytes NegativeBuckets: []float64{3.1, 3, 1.234e5, 1000}, // 24 bytes + 4 * 8 bytes }, - 8 + 1 + 4 + 8 + 8 + 8 + 8 + (24 + 2*4 + 2*4) + (24 + 2*4 + 2*4) + (24 + 4*8) + (24 + 4*8), + 8 + 4 + 4 + 8 + 8 + 8 + 8 + (24 + 2*4 + 2*4) + (24 + 2*4 + 2*4) + (24 + 4*8) + (24 + 4*8), }, } diff --git a/promql/engine.go b/promql/engine.go index 120964ca0..4e0769f99 100644 --- a/promql/engine.go +++ b/promql/engine.go @@ -1700,7 +1700,7 @@ func (ev *evaluator) eval(expr parser.Expr) (parser.Value, annotations.Annotatio } point := HPoint{H: h, T: ts} ss.Histograms = append(ss.Histograms, point) - histSize := point.histogramSize() + histSize := point.size() ev.currentSamples += histSize ev.samplesStats.IncrementSamplesAtStep(step, int64(histSize)) } @@ -1818,7 +1818,7 @@ func (ev *evaluator) eval(expr parser.Expr) (parser.Value, annotations.Annotatio H: mat[i].Histograms[0].H, } mat[i].Histograms = append(mat[i].Histograms, point) - ev.currentSamples += point.histogramSize() + ev.currentSamples += point.size() } if ev.currentSamples > ev.maxSamples { ev.error(ErrTooManySamples(env)) @@ -2091,7 +2091,7 @@ loop: histograms = getHPointSlice(16) } histograms = append(histograms, point) - ev.currentSamples += point.histogramSize() + ev.currentSamples += point.size() } case chunkenc.ValFloat: t, f := buf.At() @@ -2124,7 +2124,7 @@ loop: } point := HPoint{T: t, H: h} histograms = append(histograms, point) - ev.currentSamples += point.histogramSize() + ev.currentSamples += point.size() } case chunkenc.ValFloat: t, f := it.At() diff --git a/promql/value.go b/promql/value.go index 5fa339ad5..28cf3fe31 100644 --- a/promql/value.go +++ b/promql/value.go @@ -168,11 +168,11 @@ func (p HPoint) MarshalJSON() ([]byte, error) { return json.Marshal([...]interface{}{float64(p.T) / 1000, h}) } -// histogramSize returns the size of the HPoint compared to the size of an FPoint. +// size returns the size of the HPoint compared to the size of an FPoint. // The total size is calculated considering the histogram timestamp (p.T - 8 bytes), // and then a number of bytes in the histogram. // This sum is divided by 16, as samples are 16 bytes. -func (p HPoint) histogramSize() int { +func (p HPoint) size() int { return (p.H.Size() + 8) / 16 } @@ -180,7 +180,7 @@ func (p HPoint) histogramSize() int { func totalHPointSize(histograms []HPoint) int { var total int for _, h := range histograms { - total += h.histogramSize() + total += h.size() } return total } @@ -246,7 +246,7 @@ func (vec Vector) String() string { // TotalSamples returns the total number of samples in the series within a vector. // Float samples have a weight of 1 in this number, while histogram samples have a higher // weight according to their size compared with the size of a float sample. -// See HPoint.histogramSize for details. +// See HPoint.size for details. func (vec Vector) TotalSamples() int { numSamples := 0 for _, sample := range vec { @@ -296,7 +296,9 @@ func (m Matrix) String() string { } // TotalSamples returns the total number of samples in the series within a matrix. -// It takes into account the number of samples in the histograms using the histogramSize method. +// Float samples have a weight of 1 in this number, while histogram samples have a higher +// weight according to their size compared with the size of a float sample. +// See HPoint.size for details. func (m Matrix) TotalSamples() int { numSamples := 0 for _, series := range m {