mirror of
https://github.com/prometheus/prometheus.git
synced 2025-01-13 06:47:28 -08:00
Fix more counterResetInAnyBucket edgecases
Case a) empty span is at the beginning of the spans. Case b) two consequtive empty spans with positive offsets. Signed-off-by: György Krajcsovits <gyorgy.krajcsovits@grafana.com>
This commit is contained in:
parent
4419399e4e
commit
b2fa4d910a
|
@ -339,11 +339,16 @@ func counterResetInAnyFloatBucket(oldBuckets []xorValue, newBuckets []float64, o
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
oldSpanSliceIdx, newSpanSliceIdx := 0, 0 // Index for the span slices.
|
var (
|
||||||
oldInsideSpanIdx, newInsideSpanIdx := uint32(0), uint32(0) // Index inside a span.
|
oldSpanSliceIdx, newSpanSliceIdx int = -1, -1 // Index for the span slices. Starts at -1 to indicate that the first non empty span is not yet found.
|
||||||
oldIdx, newIdx := oldSpans[0].Offset, newSpans[0].Offset
|
oldInsideSpanIdx, newInsideSpanIdx uint32 // Index inside a span.
|
||||||
|
oldIdx, newIdx int32 // Index inside a bucket slice.
|
||||||
|
oldBucketSliceIdx, newBucketSliceIdx int // Index inside bucket slice.
|
||||||
|
)
|
||||||
|
|
||||||
oldBucketSliceIdx, newBucketSliceIdx := 0, 0 // Index inside bucket slice.
|
// Find first non empty spans.
|
||||||
|
oldSpanSliceIdx, oldIdx = nextNonEmptySpanSliceIdx(oldSpanSliceIdx, oldIdx, oldSpans)
|
||||||
|
newSpanSliceIdx, newIdx = nextNonEmptySpanSliceIdx(newSpanSliceIdx, newIdx, newSpans)
|
||||||
oldVal, newVal := oldBuckets[0].value, newBuckets[0]
|
oldVal, newVal := oldBuckets[0].value, newBuckets[0]
|
||||||
|
|
||||||
// Since we assume that new spans won't have missing buckets, there will never be a case
|
// Since we assume that new spans won't have missing buckets, there will never be a case
|
||||||
|
@ -359,13 +364,12 @@ func counterResetInAnyFloatBucket(oldBuckets []xorValue, newBuckets []float64, o
|
||||||
// Moving ahead old bucket and span by 1 index.
|
// Moving ahead old bucket and span by 1 index.
|
||||||
if oldInsideSpanIdx+1 >= oldSpans[oldSpanSliceIdx].Length {
|
if oldInsideSpanIdx+1 >= oldSpans[oldSpanSliceIdx].Length {
|
||||||
// Current span is over.
|
// Current span is over.
|
||||||
oldSpanSliceIdx = nextNonEmptySpanSliceIdx(oldSpanSliceIdx, oldSpans)
|
oldSpanSliceIdx, oldIdx = nextNonEmptySpanSliceIdx(oldSpanSliceIdx, oldIdx, oldSpans)
|
||||||
oldInsideSpanIdx = 0
|
oldInsideSpanIdx = 0
|
||||||
if oldSpanSliceIdx >= len(oldSpans) {
|
if oldSpanSliceIdx >= len(oldSpans) {
|
||||||
// All old spans are over.
|
// All old spans are over.
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
oldIdx += 1 + oldSpans[oldSpanSliceIdx].Offset
|
|
||||||
} else {
|
} else {
|
||||||
oldInsideSpanIdx++
|
oldInsideSpanIdx++
|
||||||
oldIdx++
|
oldIdx++
|
||||||
|
@ -378,14 +382,13 @@ func counterResetInAnyFloatBucket(oldBuckets []xorValue, newBuckets []float64, o
|
||||||
// Moving ahead new bucket and span by 1 index.
|
// Moving ahead new bucket and span by 1 index.
|
||||||
if newInsideSpanIdx+1 >= newSpans[newSpanSliceIdx].Length {
|
if newInsideSpanIdx+1 >= newSpans[newSpanSliceIdx].Length {
|
||||||
// Current span is over.
|
// Current span is over.
|
||||||
newSpanSliceIdx = nextNonEmptySpanSliceIdx(newSpanSliceIdx, newSpans)
|
newSpanSliceIdx, newIdx = nextNonEmptySpanSliceIdx(newSpanSliceIdx, newIdx, newSpans)
|
||||||
newInsideSpanIdx = 0
|
newInsideSpanIdx = 0
|
||||||
if newSpanSliceIdx >= len(newSpans) {
|
if newSpanSliceIdx >= len(newSpans) {
|
||||||
// All new spans are over.
|
// All new spans are over.
|
||||||
// This should not happen, old spans above should catch this first.
|
// This should not happen, old spans above should catch this first.
|
||||||
panic("new spans over before old spans in counterReset")
|
panic("new spans over before old spans in counterReset")
|
||||||
}
|
}
|
||||||
newIdx += 1 + newSpans[newSpanSliceIdx].Offset
|
|
||||||
} else {
|
} else {
|
||||||
newInsideSpanIdx++
|
newInsideSpanIdx++
|
||||||
newIdx++
|
newIdx++
|
||||||
|
|
|
@ -550,62 +550,193 @@ func assertRecodedFloatHistogramChunkOnAppend(t *testing.T, prevChunk Chunk, hAp
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFloatHistogramChunkAppendableWithEmptySpan(t *testing.T) {
|
func TestFloatHistogramChunkAppendableWithEmptySpan(t *testing.T) {
|
||||||
h1 := &histogram.FloatHistogram{
|
tests := map[string]struct {
|
||||||
Schema: 0,
|
h1 *histogram.FloatHistogram
|
||||||
Count: 21,
|
h2 *histogram.FloatHistogram
|
||||||
Sum: 1234.5,
|
}{
|
||||||
ZeroThreshold: 0.001,
|
"empty span in old and new histogram": {
|
||||||
ZeroCount: 4,
|
h1: &histogram.FloatHistogram{
|
||||||
PositiveSpans: []histogram.Span{
|
Schema: 0,
|
||||||
{Offset: 0, Length: 4},
|
Count: 21,
|
||||||
{Offset: 0, Length: 0},
|
Sum: 1234.5,
|
||||||
{Offset: 0, Length: 3},
|
ZeroThreshold: 0.001,
|
||||||
|
ZeroCount: 4,
|
||||||
|
PositiveSpans: []histogram.Span{
|
||||||
|
{Offset: 0, Length: 4},
|
||||||
|
{Offset: 0, Length: 0},
|
||||||
|
{Offset: 0, Length: 3},
|
||||||
|
},
|
||||||
|
PositiveBuckets: []float64{1, 2, 1, 1, 1, 1, 1},
|
||||||
|
NegativeSpans: []histogram.Span{
|
||||||
|
{Offset: 1, Length: 4},
|
||||||
|
{Offset: 2, Length: 0},
|
||||||
|
{Offset: 2, Length: 3},
|
||||||
|
},
|
||||||
|
NegativeBuckets: []float64{1, 2, 1, 2, 2, 2, 2},
|
||||||
|
},
|
||||||
|
h2: &histogram.FloatHistogram{
|
||||||
|
Schema: 0,
|
||||||
|
Count: 37,
|
||||||
|
Sum: 2345.6,
|
||||||
|
ZeroThreshold: 0.001,
|
||||||
|
ZeroCount: 5,
|
||||||
|
PositiveSpans: []histogram.Span{
|
||||||
|
{Offset: 0, Length: 4},
|
||||||
|
{Offset: 0, Length: 0},
|
||||||
|
{Offset: 0, Length: 3},
|
||||||
|
},
|
||||||
|
PositiveBuckets: []float64{1, 3, 1, 2, 1, 1, 1},
|
||||||
|
NegativeSpans: []histogram.Span{
|
||||||
|
{Offset: 1, Length: 4},
|
||||||
|
{Offset: 2, Length: 0},
|
||||||
|
{Offset: 2, Length: 3},
|
||||||
|
},
|
||||||
|
NegativeBuckets: []float64{1, 4, 2, 7, 5, 5, 2},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
PositiveBuckets: []float64{1, 2, 1, 1, 1, 1, 1},
|
"empty span in old histogram": {
|
||||||
NegativeSpans: []histogram.Span{
|
h1: &histogram.FloatHistogram{
|
||||||
{Offset: 1, Length: 4},
|
Schema: 0,
|
||||||
{Offset: 2, Length: 0},
|
Count: 21,
|
||||||
{Offset: 2, Length: 3},
|
Sum: 1234.5,
|
||||||
|
ZeroThreshold: 0.001,
|
||||||
|
ZeroCount: 4,
|
||||||
|
PositiveSpans: []histogram.Span{
|
||||||
|
{Offset: 1, Length: 0}, // This span will disappear.
|
||||||
|
{Offset: 2, Length: 4},
|
||||||
|
{Offset: 0, Length: 3},
|
||||||
|
},
|
||||||
|
PositiveBuckets: []float64{1, 2, 1, 1, 1, 1, 1},
|
||||||
|
NegativeSpans: []histogram.Span{
|
||||||
|
{Offset: 1, Length: 4},
|
||||||
|
{Offset: 2, Length: 0},
|
||||||
|
{Offset: 2, Length: 3},
|
||||||
|
},
|
||||||
|
NegativeBuckets: []float64{1, 2, 1, 2, 2, 2, 2},
|
||||||
|
},
|
||||||
|
h2: &histogram.FloatHistogram{
|
||||||
|
Schema: 0,
|
||||||
|
Count: 37,
|
||||||
|
Sum: 2345.6,
|
||||||
|
ZeroThreshold: 0.001,
|
||||||
|
ZeroCount: 5,
|
||||||
|
PositiveSpans: []histogram.Span{
|
||||||
|
{Offset: 3, Length: 4},
|
||||||
|
{Offset: 0, Length: 3},
|
||||||
|
},
|
||||||
|
PositiveBuckets: []float64{1, 3, 1, 2, 1, 1, 1},
|
||||||
|
NegativeSpans: []histogram.Span{
|
||||||
|
{Offset: 1, Length: 4},
|
||||||
|
{Offset: 2, Length: 0},
|
||||||
|
{Offset: 2, Length: 3},
|
||||||
|
},
|
||||||
|
NegativeBuckets: []float64{1, 4, 2, 7, 5, 5, 2},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
NegativeBuckets: []float64{1, 2, 1, 2, 2, 2, 2},
|
"empty span in new histogram": {
|
||||||
}
|
h1: &histogram.FloatHistogram{
|
||||||
h2 := &histogram.FloatHistogram{
|
Schema: 0,
|
||||||
Schema: 0,
|
Count: 21,
|
||||||
Count: 37,
|
Sum: 1234.5,
|
||||||
Sum: 2345.6,
|
ZeroThreshold: 0.001,
|
||||||
ZeroThreshold: 0.001,
|
ZeroCount: 4,
|
||||||
ZeroCount: 5,
|
PositiveSpans: []histogram.Span{
|
||||||
PositiveSpans: []histogram.Span{
|
{Offset: 0, Length: 4},
|
||||||
{Offset: 0, Length: 4},
|
{Offset: 3, Length: 3},
|
||||||
{Offset: 0, Length: 0},
|
},
|
||||||
{Offset: 0, Length: 3},
|
PositiveBuckets: []float64{1, 2, 1, 1, 1, 1, 1},
|
||||||
|
NegativeSpans: []histogram.Span{
|
||||||
|
{Offset: 1, Length: 4},
|
||||||
|
{Offset: 2, Length: 0},
|
||||||
|
{Offset: 2, Length: 3},
|
||||||
|
},
|
||||||
|
NegativeBuckets: []float64{1, 2, 1, 2, 2, 2, 2},
|
||||||
|
},
|
||||||
|
h2: &histogram.FloatHistogram{
|
||||||
|
Schema: 0,
|
||||||
|
Count: 37,
|
||||||
|
Sum: 2345.6,
|
||||||
|
ZeroThreshold: 0.001,
|
||||||
|
ZeroCount: 5,
|
||||||
|
PositiveSpans: []histogram.Span{
|
||||||
|
{Offset: 0, Length: 4},
|
||||||
|
{Offset: 1, Length: 0}, // This span is new.
|
||||||
|
{Offset: 2, Length: 3},
|
||||||
|
},
|
||||||
|
PositiveBuckets: []float64{1, 3, 1, 2, 1, 1, 1},
|
||||||
|
NegativeSpans: []histogram.Span{
|
||||||
|
{Offset: 1, Length: 4},
|
||||||
|
{Offset: 2, Length: 0},
|
||||||
|
{Offset: 2, Length: 3},
|
||||||
|
},
|
||||||
|
NegativeBuckets: []float64{1, 4, 2, 7, 5, 5, 2},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
PositiveBuckets: []float64{1, 3, 1, 2, 1, 1, 1},
|
"two empty spans mixing offsets": {
|
||||||
NegativeSpans: []histogram.Span{
|
h1: &histogram.FloatHistogram{
|
||||||
{Offset: 1, Length: 4},
|
Schema: 0,
|
||||||
{Offset: 2, Length: 0},
|
Count: 21,
|
||||||
{Offset: 2, Length: 3},
|
Sum: 1234.5,
|
||||||
|
ZeroThreshold: 0.001,
|
||||||
|
ZeroCount: 4,
|
||||||
|
PositiveSpans: []histogram.Span{
|
||||||
|
{Offset: 0, Length: 4},
|
||||||
|
{Offset: 1, Length: 0},
|
||||||
|
{Offset: 3, Length: 0},
|
||||||
|
{Offset: 4, Length: 3},
|
||||||
|
},
|
||||||
|
PositiveBuckets: []float64{1, 2, 1, 1, 1, 1, 1},
|
||||||
|
NegativeSpans: []histogram.Span{
|
||||||
|
{Offset: 1, Length: 4},
|
||||||
|
{Offset: 2, Length: 0},
|
||||||
|
{Offset: 2, Length: 3},
|
||||||
|
},
|
||||||
|
NegativeBuckets: []float64{1, 2, 1, 2, 2, 2, 2},
|
||||||
|
},
|
||||||
|
h2: &histogram.FloatHistogram{
|
||||||
|
Schema: 0,
|
||||||
|
Count: 37,
|
||||||
|
Sum: 2345.6,
|
||||||
|
ZeroThreshold: 0.001,
|
||||||
|
ZeroCount: 5,
|
||||||
|
PositiveSpans: []histogram.Span{
|
||||||
|
{Offset: 0, Length: 4},
|
||||||
|
{Offset: 3, Length: 0},
|
||||||
|
{Offset: 1, Length: 0},
|
||||||
|
{Offset: 4, Length: 3},
|
||||||
|
},
|
||||||
|
PositiveBuckets: []float64{1, 3, 1, 2, 1, 1, 1},
|
||||||
|
NegativeSpans: []histogram.Span{
|
||||||
|
{Offset: 1, Length: 4},
|
||||||
|
{Offset: 2, Length: 0},
|
||||||
|
{Offset: 2, Length: 3},
|
||||||
|
},
|
||||||
|
NegativeBuckets: []float64{1, 4, 2, 7, 5, 5, 2},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
NegativeBuckets: []float64{1, 4, 2, 7, 5, 5, 2},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c := Chunk(NewFloatHistogramChunk())
|
for name, tc := range tests {
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
c := Chunk(NewFloatHistogramChunk())
|
||||||
|
|
||||||
// Create fresh appender and add the first histogram.
|
// Create fresh appender and add the first histogram.
|
||||||
app, err := c.Appender()
|
app, err := c.Appender()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, 0, c.NumSamples())
|
require.Equal(t, 0, c.NumSamples())
|
||||||
|
|
||||||
_, _, _, err = app.AppendFloatHistogram(nil, 1, h1, true)
|
_, _, _, err = app.AppendFloatHistogram(nil, 1, tc.h1, true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, 1, c.NumSamples())
|
require.Equal(t, 1, c.NumSamples())
|
||||||
hApp, _ := app.(*FloatHistogramAppender)
|
hApp, _ := app.(*FloatHistogramAppender)
|
||||||
|
|
||||||
pI, nI, okToAppend, counterReset := hApp.appendable(h2)
|
pI, nI, okToAppend, counterReset := hApp.appendable(tc.h2)
|
||||||
require.Empty(t, pI)
|
require.Empty(t, pI)
|
||||||
require.Empty(t, nI)
|
require.Empty(t, nI)
|
||||||
require.True(t, okToAppend)
|
require.True(t, okToAppend)
|
||||||
require.False(t, counterReset)
|
require.False(t, counterReset)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFloatHistogramChunkAppendableGauge(t *testing.T) {
|
func TestFloatHistogramChunkAppendableGauge(t *testing.T) {
|
||||||
|
|
|
@ -359,11 +359,16 @@ func counterResetInAnyBucket(oldBuckets, newBuckets []int64, oldSpans, newSpans
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
oldSpanSliceIdx, newSpanSliceIdx := 0, 0 // Index for the span slices.
|
var (
|
||||||
oldInsideSpanIdx, newInsideSpanIdx := uint32(0), uint32(0) // Index inside a span.
|
oldSpanSliceIdx, newSpanSliceIdx int = -1, -1 // Index for the span slices. Starts at -1 to indicate that the first non empty span is not yet found.
|
||||||
oldIdx, newIdx := oldSpans[0].Offset, newSpans[0].Offset
|
oldInsideSpanIdx, newInsideSpanIdx uint32 // Index inside a span.
|
||||||
|
oldIdx, newIdx int32 // Index inside a bucket slice.
|
||||||
|
oldBucketSliceIdx, newBucketSliceIdx int // Index inside bucket slice.
|
||||||
|
)
|
||||||
|
|
||||||
oldBucketSliceIdx, newBucketSliceIdx := 0, 0 // Index inside bucket slice.
|
// Find first non empty spans.
|
||||||
|
oldSpanSliceIdx, oldIdx = nextNonEmptySpanSliceIdx(oldSpanSliceIdx, oldIdx, oldSpans)
|
||||||
|
newSpanSliceIdx, newIdx = nextNonEmptySpanSliceIdx(newSpanSliceIdx, newIdx, newSpans)
|
||||||
oldVal, newVal := oldBuckets[0], newBuckets[0]
|
oldVal, newVal := oldBuckets[0], newBuckets[0]
|
||||||
|
|
||||||
// Since we assume that new spans won't have missing buckets, there will never be a case
|
// Since we assume that new spans won't have missing buckets, there will never be a case
|
||||||
|
@ -379,13 +384,12 @@ func counterResetInAnyBucket(oldBuckets, newBuckets []int64, oldSpans, newSpans
|
||||||
// Moving ahead old bucket and span by 1 index.
|
// Moving ahead old bucket and span by 1 index.
|
||||||
if oldInsideSpanIdx+1 >= oldSpans[oldSpanSliceIdx].Length {
|
if oldInsideSpanIdx+1 >= oldSpans[oldSpanSliceIdx].Length {
|
||||||
// Current span is over.
|
// Current span is over.
|
||||||
oldSpanSliceIdx = nextNonEmptySpanSliceIdx(oldSpanSliceIdx, oldSpans)
|
oldSpanSliceIdx, oldIdx = nextNonEmptySpanSliceIdx(oldSpanSliceIdx, oldIdx, oldSpans)
|
||||||
oldInsideSpanIdx = 0
|
oldInsideSpanIdx = 0
|
||||||
if oldSpanSliceIdx >= len(oldSpans) {
|
if oldSpanSliceIdx >= len(oldSpans) {
|
||||||
// All old spans are over.
|
// All old spans are over.
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
oldIdx += 1 + oldSpans[oldSpanSliceIdx].Offset
|
|
||||||
} else {
|
} else {
|
||||||
oldInsideSpanIdx++
|
oldInsideSpanIdx++
|
||||||
oldIdx++
|
oldIdx++
|
||||||
|
@ -398,14 +402,13 @@ func counterResetInAnyBucket(oldBuckets, newBuckets []int64, oldSpans, newSpans
|
||||||
// Moving ahead new bucket and span by 1 index.
|
// Moving ahead new bucket and span by 1 index.
|
||||||
if newInsideSpanIdx+1 >= newSpans[newSpanSliceIdx].Length {
|
if newInsideSpanIdx+1 >= newSpans[newSpanSliceIdx].Length {
|
||||||
// Current span is over.
|
// Current span is over.
|
||||||
newSpanSliceIdx = nextNonEmptySpanSliceIdx(newSpanSliceIdx, newSpans)
|
newSpanSliceIdx, newIdx = nextNonEmptySpanSliceIdx(newSpanSliceIdx, newIdx, newSpans)
|
||||||
newInsideSpanIdx = 0
|
newInsideSpanIdx = 0
|
||||||
if newSpanSliceIdx >= len(newSpans) {
|
if newSpanSliceIdx >= len(newSpans) {
|
||||||
// All new spans are over.
|
// All new spans are over.
|
||||||
// This should not happen, old spans above should catch this first.
|
// This should not happen, old spans above should catch this first.
|
||||||
panic("new spans over before old spans in counterReset")
|
panic("new spans over before old spans in counterReset")
|
||||||
}
|
}
|
||||||
newIdx += 1 + newSpans[newSpanSliceIdx].Offset
|
|
||||||
} else {
|
} else {
|
||||||
newInsideSpanIdx++
|
newInsideSpanIdx++
|
||||||
newIdx++
|
newIdx++
|
||||||
|
|
|
@ -489,8 +489,13 @@ func counterResetHint(crh CounterResetHeader, numRead uint16) histogram.CounterR
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle pathological case of empty span when advancing span idx.
|
// Handle pathological case of empty span when advancing span idx.
|
||||||
func nextNonEmptySpanSliceIdx(idx int, spans []histogram.Span) (newIdx int) {
|
// Call it with idx==-1 to find the first non empty span.
|
||||||
for idx++; idx < len(spans) && spans[idx].Length == 0; idx++ {
|
func nextNonEmptySpanSliceIdx(idx int, bucketIdx int32, spans []histogram.Span) (newIdx int, newBucketIdx int32) {
|
||||||
|
for idx++; idx < len(spans); idx++ {
|
||||||
|
if spans[idx].Length > 0 {
|
||||||
|
return idx, bucketIdx + spans[idx].Offset + 1
|
||||||
|
}
|
||||||
|
bucketIdx += spans[idx].Offset
|
||||||
}
|
}
|
||||||
return idx
|
return idx, 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -573,62 +573,193 @@ func assertSampleCount(t *testing.T, c Chunk, exp int64, vtype ValueType) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHistogramChunkAppendableWithEmptySpan(t *testing.T) {
|
func TestHistogramChunkAppendableWithEmptySpan(t *testing.T) {
|
||||||
h1 := &histogram.Histogram{
|
tests := map[string]struct {
|
||||||
Schema: 0,
|
h1 *histogram.Histogram
|
||||||
Count: 21,
|
h2 *histogram.Histogram
|
||||||
Sum: 1234.5,
|
}{
|
||||||
ZeroThreshold: 0.001,
|
"empty span in old and new histogram": {
|
||||||
ZeroCount: 4,
|
h1: &histogram.Histogram{
|
||||||
PositiveSpans: []histogram.Span{
|
Schema: 0,
|
||||||
{Offset: 0, Length: 4},
|
Count: 21,
|
||||||
{Offset: 0, Length: 0},
|
Sum: 1234.5,
|
||||||
{Offset: 0, Length: 3},
|
ZeroThreshold: 0.001,
|
||||||
|
ZeroCount: 4,
|
||||||
|
PositiveSpans: []histogram.Span{
|
||||||
|
{Offset: 0, Length: 4},
|
||||||
|
{Offset: 0, Length: 0},
|
||||||
|
{Offset: 0, Length: 3},
|
||||||
|
},
|
||||||
|
PositiveBuckets: []int64{1, 1, -1, 0, 0, 0, 0},
|
||||||
|
NegativeSpans: []histogram.Span{
|
||||||
|
{Offset: 1, Length: 4},
|
||||||
|
{Offset: 2, Length: 0},
|
||||||
|
{Offset: 2, Length: 3},
|
||||||
|
},
|
||||||
|
NegativeBuckets: []int64{1, 1, -1, 1, 0, 0, 0},
|
||||||
|
},
|
||||||
|
h2: &histogram.Histogram{
|
||||||
|
Schema: 0,
|
||||||
|
Count: 37,
|
||||||
|
Sum: 2345.6,
|
||||||
|
ZeroThreshold: 0.001,
|
||||||
|
ZeroCount: 5,
|
||||||
|
PositiveSpans: []histogram.Span{
|
||||||
|
{Offset: 0, Length: 4},
|
||||||
|
{Offset: 0, Length: 0},
|
||||||
|
{Offset: 0, Length: 3},
|
||||||
|
},
|
||||||
|
PositiveBuckets: []int64{1, 2, -2, 1, -1, 0, 0},
|
||||||
|
NegativeSpans: []histogram.Span{
|
||||||
|
{Offset: 1, Length: 4},
|
||||||
|
{Offset: 2, Length: 0},
|
||||||
|
{Offset: 2, Length: 3},
|
||||||
|
},
|
||||||
|
NegativeBuckets: []int64{1, 3, -2, 5, -2, 0, -3},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
PositiveBuckets: []int64{1, 1, -1, 0, 0, 0, 0},
|
"empty span in old histogram": {
|
||||||
NegativeSpans: []histogram.Span{
|
h1: &histogram.Histogram{
|
||||||
{Offset: 1, Length: 4},
|
Schema: 0,
|
||||||
{Offset: 2, Length: 0},
|
Count: 21,
|
||||||
{Offset: 2, Length: 3},
|
Sum: 1234.5,
|
||||||
|
ZeroThreshold: 0.001,
|
||||||
|
ZeroCount: 4,
|
||||||
|
PositiveSpans: []histogram.Span{
|
||||||
|
{Offset: 1, Length: 0}, // This span will disappear.
|
||||||
|
{Offset: 2, Length: 4},
|
||||||
|
{Offset: 0, Length: 3},
|
||||||
|
},
|
||||||
|
PositiveBuckets: []int64{1, 1, -1, 0, 0, 0, 0},
|
||||||
|
NegativeSpans: []histogram.Span{
|
||||||
|
{Offset: 1, Length: 4},
|
||||||
|
{Offset: 2, Length: 0},
|
||||||
|
{Offset: 2, Length: 3},
|
||||||
|
},
|
||||||
|
NegativeBuckets: []int64{1, 1, -1, 1, 0, 0, 0},
|
||||||
|
},
|
||||||
|
h2: &histogram.Histogram{
|
||||||
|
Schema: 0,
|
||||||
|
Count: 37,
|
||||||
|
Sum: 2345.6,
|
||||||
|
ZeroThreshold: 0.001,
|
||||||
|
ZeroCount: 5,
|
||||||
|
PositiveSpans: []histogram.Span{
|
||||||
|
{Offset: 3, Length: 4},
|
||||||
|
{Offset: 0, Length: 3},
|
||||||
|
},
|
||||||
|
PositiveBuckets: []int64{1, 2, -2, 1, -1, 0, 0},
|
||||||
|
NegativeSpans: []histogram.Span{
|
||||||
|
{Offset: 1, Length: 4},
|
||||||
|
{Offset: 2, Length: 0},
|
||||||
|
{Offset: 2, Length: 3},
|
||||||
|
},
|
||||||
|
NegativeBuckets: []int64{1, 3, -2, 5, -2, 0, -3},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
NegativeBuckets: []int64{1, 1, -1, 1, 0, 0, 0},
|
"empty span in new histogram": {
|
||||||
}
|
h1: &histogram.Histogram{
|
||||||
h2 := &histogram.Histogram{
|
Schema: 0,
|
||||||
Schema: 0,
|
Count: 21,
|
||||||
Count: 37,
|
Sum: 1234.5,
|
||||||
Sum: 2345.6,
|
ZeroThreshold: 0.001,
|
||||||
ZeroThreshold: 0.001,
|
ZeroCount: 4,
|
||||||
ZeroCount: 5,
|
PositiveSpans: []histogram.Span{
|
||||||
PositiveSpans: []histogram.Span{
|
{Offset: 0, Length: 4},
|
||||||
{Offset: 0, Length: 4},
|
{Offset: 3, Length: 3},
|
||||||
{Offset: 0, Length: 0},
|
},
|
||||||
{Offset: 0, Length: 3},
|
PositiveBuckets: []int64{1, 1, -1, 0, 0, 0, 0},
|
||||||
|
NegativeSpans: []histogram.Span{
|
||||||
|
{Offset: 1, Length: 4},
|
||||||
|
{Offset: 2, Length: 0},
|
||||||
|
{Offset: 2, Length: 3},
|
||||||
|
},
|
||||||
|
NegativeBuckets: []int64{1, 1, -1, 1, 0, 0, 0},
|
||||||
|
},
|
||||||
|
h2: &histogram.Histogram{
|
||||||
|
Schema: 0,
|
||||||
|
Count: 37,
|
||||||
|
Sum: 2345.6,
|
||||||
|
ZeroThreshold: 0.001,
|
||||||
|
ZeroCount: 5,
|
||||||
|
PositiveSpans: []histogram.Span{
|
||||||
|
{Offset: 0, Length: 4},
|
||||||
|
{Offset: 1, Length: 0}, // This span is new.
|
||||||
|
{Offset: 2, Length: 3},
|
||||||
|
},
|
||||||
|
PositiveBuckets: []int64{1, 2, -2, 1, -1, 0, 0},
|
||||||
|
NegativeSpans: []histogram.Span{
|
||||||
|
{Offset: 1, Length: 4},
|
||||||
|
{Offset: 2, Length: 0},
|
||||||
|
{Offset: 2, Length: 3},
|
||||||
|
},
|
||||||
|
NegativeBuckets: []int64{1, 3, -2, 5, -2, 0, -3},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
PositiveBuckets: []int64{1, 2, -2, 1, -1, 0, 0},
|
"two empty spans mixing offsets": {
|
||||||
NegativeSpans: []histogram.Span{
|
h1: &histogram.Histogram{
|
||||||
{Offset: 1, Length: 4},
|
Schema: 0,
|
||||||
{Offset: 2, Length: 0},
|
Count: 21,
|
||||||
{Offset: 2, Length: 3},
|
Sum: 1234.5,
|
||||||
|
ZeroThreshold: 0.001,
|
||||||
|
ZeroCount: 4,
|
||||||
|
PositiveSpans: []histogram.Span{
|
||||||
|
{Offset: 0, Length: 4},
|
||||||
|
{Offset: 1, Length: 0},
|
||||||
|
{Offset: 3, Length: 0},
|
||||||
|
{Offset: 4, Length: 3},
|
||||||
|
},
|
||||||
|
PositiveBuckets: []int64{1, 1, -1, 0, 0, 0, 0},
|
||||||
|
NegativeSpans: []histogram.Span{
|
||||||
|
{Offset: 1, Length: 4},
|
||||||
|
{Offset: 2, Length: 0},
|
||||||
|
{Offset: 2, Length: 3},
|
||||||
|
},
|
||||||
|
NegativeBuckets: []int64{1, 1, -1, 1, 0, 0, 0},
|
||||||
|
},
|
||||||
|
h2: &histogram.Histogram{
|
||||||
|
Schema: 0,
|
||||||
|
Count: 37,
|
||||||
|
Sum: 2345.6,
|
||||||
|
ZeroThreshold: 0.001,
|
||||||
|
ZeroCount: 5,
|
||||||
|
PositiveSpans: []histogram.Span{
|
||||||
|
{Offset: 0, Length: 4},
|
||||||
|
{Offset: 3, Length: 0},
|
||||||
|
{Offset: 1, Length: 0},
|
||||||
|
{Offset: 4, Length: 3},
|
||||||
|
},
|
||||||
|
PositiveBuckets: []int64{1, 2, -2, 1, -1, 0, 0},
|
||||||
|
NegativeSpans: []histogram.Span{
|
||||||
|
{Offset: 1, Length: 4},
|
||||||
|
{Offset: 2, Length: 0},
|
||||||
|
{Offset: 2, Length: 3},
|
||||||
|
},
|
||||||
|
NegativeBuckets: []int64{1, 3, -2, 5, -2, 0, -3},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
NegativeBuckets: []int64{1, 3, -2, 5, -2, 0, -3},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c := Chunk(NewHistogramChunk())
|
for name, tc := range tests {
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
c := Chunk(NewHistogramChunk())
|
||||||
|
|
||||||
// Create fresh appender and add the first histogram.
|
// Create fresh appender and add the first histogram.
|
||||||
app, err := c.Appender()
|
app, err := c.Appender()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, 0, c.NumSamples())
|
require.Equal(t, 0, c.NumSamples())
|
||||||
|
|
||||||
_, _, _, err = app.AppendHistogram(nil, 1, h1, true)
|
_, _, _, err = app.AppendHistogram(nil, 1, tc.h1, true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, 1, c.NumSamples())
|
require.Equal(t, 1, c.NumSamples())
|
||||||
hApp, _ := app.(*HistogramAppender)
|
hApp, _ := app.(*HistogramAppender)
|
||||||
|
|
||||||
pI, nI, okToAppend, counterReset := hApp.appendable(h2)
|
pI, nI, okToAppend, counterReset := hApp.appendable(tc.h2)
|
||||||
require.Empty(t, pI)
|
require.Empty(t, pI)
|
||||||
require.Empty(t, nI)
|
require.Empty(t, nI)
|
||||||
require.True(t, okToAppend)
|
require.True(t, okToAppend)
|
||||||
require.False(t, counterReset)
|
require.False(t, counterReset)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAtFloatHistogram(t *testing.T) {
|
func TestAtFloatHistogram(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue