Merge pull request #13190 from linasm/fix-float-histogram-add-sub-mutating-argument

Fix FloatHistogram.Add/Sub mutating its argument
This commit is contained in:
Björn Rabenstein 2023-11-28 14:04:50 +01:00 committed by GitHub
commit a6d4b8d97b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 8 deletions

View file

@ -268,12 +268,23 @@ func (h *FloatHistogram) Add(other *FloatHistogram) *FloatHistogram {
h.Count += other.Count h.Count += other.Count
h.Sum += other.Sum h.Sum += other.Sum
if other.Schema != h.Schema { var (
other = other.ReduceResolution(h.Schema) otherPositiveSpans = other.PositiveSpans
otherPositiveBuckets = other.PositiveBuckets
otherNegativeSpans = other.NegativeSpans
otherNegativeBuckets = other.NegativeBuckets
)
if other.Schema < h.Schema {
panic(fmt.Errorf("cannot add histogram with schema %d to %d", other.Schema, h.Schema))
} else if other.Schema > h.Schema {
otherPositiveSpans, otherPositiveBuckets = reduceResolution(otherPositiveSpans, otherPositiveBuckets, other.Schema, h.Schema, false)
otherNegativeSpans, otherNegativeBuckets = reduceResolution(otherNegativeSpans, otherNegativeBuckets, other.Schema, h.Schema, false)
} }
h.PositiveSpans, h.PositiveBuckets = addBuckets(h.Schema, h.ZeroThreshold, false, h.PositiveSpans, h.PositiveBuckets, other.PositiveSpans, other.PositiveBuckets) h.PositiveSpans, h.PositiveBuckets = addBuckets(h.Schema, h.ZeroThreshold, false, h.PositiveSpans, h.PositiveBuckets, otherPositiveSpans, otherPositiveBuckets)
h.NegativeSpans, h.NegativeBuckets = addBuckets(h.Schema, h.ZeroThreshold, false, h.NegativeSpans, h.NegativeBuckets, other.NegativeSpans, other.NegativeBuckets) h.NegativeSpans, h.NegativeBuckets = addBuckets(h.Schema, h.ZeroThreshold, false, h.NegativeSpans, h.NegativeBuckets, otherNegativeSpans, otherNegativeBuckets)
return h return h
} }
@ -284,12 +295,23 @@ func (h *FloatHistogram) Sub(other *FloatHistogram) *FloatHistogram {
h.Count -= other.Count h.Count -= other.Count
h.Sum -= other.Sum h.Sum -= other.Sum
if other.Schema != h.Schema { var (
other = other.ReduceResolution(h.Schema) otherPositiveSpans = other.PositiveSpans
otherPositiveBuckets = other.PositiveBuckets
otherNegativeSpans = other.NegativeSpans
otherNegativeBuckets = other.NegativeBuckets
)
if other.Schema < h.Schema {
panic(fmt.Errorf("cannot subtract histigram with schema %d to %d", other.Schema, h.Schema))
} else if other.Schema > h.Schema {
otherPositiveSpans, otherPositiveBuckets = reduceResolution(otherPositiveSpans, otherPositiveBuckets, other.Schema, h.Schema, false)
otherNegativeSpans, otherNegativeBuckets = reduceResolution(otherNegativeSpans, otherNegativeBuckets, other.Schema, h.Schema, false)
} }
h.PositiveSpans, h.PositiveBuckets = addBuckets(h.Schema, h.ZeroThreshold, true, h.PositiveSpans, h.PositiveBuckets, other.PositiveSpans, other.PositiveBuckets) h.PositiveSpans, h.PositiveBuckets = addBuckets(h.Schema, h.ZeroThreshold, true, h.PositiveSpans, h.PositiveBuckets, otherPositiveSpans, otherPositiveBuckets)
h.NegativeSpans, h.NegativeBuckets = addBuckets(h.Schema, h.ZeroThreshold, true, h.NegativeSpans, h.NegativeBuckets, other.NegativeSpans, other.NegativeBuckets) h.NegativeSpans, h.NegativeBuckets = addBuckets(h.Schema, h.ZeroThreshold, true, h.NegativeSpans, h.NegativeBuckets, otherNegativeSpans, otherNegativeBuckets)
return h return h
} }

View file

@ -1573,9 +1573,12 @@ func TestFloatHistogramAdd(t *testing.T) {
for _, c := range cases { for _, c := range cases {
t.Run(c.name, func(t *testing.T) { t.Run(c.name, func(t *testing.T) {
in2Copy := c.in2.Copy()
require.Equal(t, c.expected, c.in1.Add(c.in2)) require.Equal(t, c.expected, c.in1.Add(c.in2))
// Has it also happened in-place? // Has it also happened in-place?
require.Equal(t, c.expected, c.in1) require.Equal(t, c.expected, c.in1)
// Check that the argument was not mutated.
require.Equal(t, in2Copy, c.in2)
}) })
} }
} }
@ -1659,9 +1662,12 @@ func TestFloatHistogramSub(t *testing.T) {
for _, c := range cases { for _, c := range cases {
t.Run(c.name, func(t *testing.T) { t.Run(c.name, func(t *testing.T) {
in2Copy := c.in2.Copy()
require.Equal(t, c.expected, c.in1.Sub(c.in2)) require.Equal(t, c.expected, c.in1.Sub(c.in2))
// Has it also happened in-place? // Has it also happened in-place?
require.Equal(t, c.expected, c.in1) require.Equal(t, c.expected, c.in1)
// Check that the argument was not mutated.
require.Equal(t, in2Copy, c.in2)
}) })
} }
} }