|
|
@ -284,103 +284,6 @@ func (h *FloatHistogram) Equals(h2 *FloatHistogram) bool {
|
|
|
|
return true
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// addBucket takes the "coordinates" of the last bucket that was handled and
|
|
|
|
|
|
|
|
// adds the provided bucket after it. If a corresponding bucket exists, the
|
|
|
|
|
|
|
|
// count is added. If not, the bucket is inserted. The updated slices and the
|
|
|
|
|
|
|
|
// coordinates of the inserted or added-to bucket are returned.
|
|
|
|
|
|
|
|
func addBucket(
|
|
|
|
|
|
|
|
b Bucket[float64],
|
|
|
|
|
|
|
|
spans []Span, buckets []float64,
|
|
|
|
|
|
|
|
iSpan, iBucket int,
|
|
|
|
|
|
|
|
iInSpan, index int32,
|
|
|
|
|
|
|
|
) (
|
|
|
|
|
|
|
|
newSpans []Span, newBuckets []float64,
|
|
|
|
|
|
|
|
newISpan, newIBucket int, newIInSpan int32,
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
if iSpan == -1 {
|
|
|
|
|
|
|
|
// First add, check if it is before all spans.
|
|
|
|
|
|
|
|
if len(spans) == 0 || spans[0].Offset > b.Index {
|
|
|
|
|
|
|
|
// Add bucket before all others.
|
|
|
|
|
|
|
|
buckets = append(buckets, 0)
|
|
|
|
|
|
|
|
copy(buckets[1:], buckets)
|
|
|
|
|
|
|
|
buckets[0] = b.Count
|
|
|
|
|
|
|
|
if len(spans) > 0 && spans[0].Offset == b.Index+1 {
|
|
|
|
|
|
|
|
spans[0].Length++
|
|
|
|
|
|
|
|
spans[0].Offset--
|
|
|
|
|
|
|
|
return spans, buckets, 0, 0, 0
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
spans = append(spans, Span{})
|
|
|
|
|
|
|
|
copy(spans[1:], spans)
|
|
|
|
|
|
|
|
spans[0] = Span{Offset: b.Index, Length: 1}
|
|
|
|
|
|
|
|
if len(spans) > 1 {
|
|
|
|
|
|
|
|
// Convert the absolute offset in the formerly
|
|
|
|
|
|
|
|
// first span to a relative offset.
|
|
|
|
|
|
|
|
spans[1].Offset -= b.Index + 1
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return spans, buckets, 0, 0, 0
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if spans[0].Offset == b.Index {
|
|
|
|
|
|
|
|
// Just add to first bucket.
|
|
|
|
|
|
|
|
buckets[0] += b.Count
|
|
|
|
|
|
|
|
return spans, buckets, 0, 0, 0
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// We are behind the first bucket, so set everything to the
|
|
|
|
|
|
|
|
// first bucket and continue normally.
|
|
|
|
|
|
|
|
iSpan, iBucket, iInSpan = 0, 0, 0
|
|
|
|
|
|
|
|
index = spans[0].Offset
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
deltaIndex := b.Index - index
|
|
|
|
|
|
|
|
for {
|
|
|
|
|
|
|
|
remainingInSpan := int32(spans[iSpan].Length) - iInSpan
|
|
|
|
|
|
|
|
if deltaIndex < remainingInSpan {
|
|
|
|
|
|
|
|
// Bucket is in current span.
|
|
|
|
|
|
|
|
iBucket += int(deltaIndex)
|
|
|
|
|
|
|
|
iInSpan += deltaIndex
|
|
|
|
|
|
|
|
buckets[iBucket] += b.Count
|
|
|
|
|
|
|
|
return spans, buckets, iSpan, iBucket, iInSpan
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
deltaIndex -= remainingInSpan
|
|
|
|
|
|
|
|
iBucket += int(remainingInSpan)
|
|
|
|
|
|
|
|
iSpan++
|
|
|
|
|
|
|
|
if iSpan == len(spans) || deltaIndex < spans[iSpan].Offset {
|
|
|
|
|
|
|
|
// Bucket is in gap behind previous span (or there are no further spans).
|
|
|
|
|
|
|
|
buckets = append(buckets, 0)
|
|
|
|
|
|
|
|
copy(buckets[iBucket+1:], buckets[iBucket:])
|
|
|
|
|
|
|
|
buckets[iBucket] = b.Count
|
|
|
|
|
|
|
|
if deltaIndex == 0 {
|
|
|
|
|
|
|
|
// Directly after previous span, extend previous span.
|
|
|
|
|
|
|
|
if iSpan < len(spans) {
|
|
|
|
|
|
|
|
spans[iSpan].Offset--
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
iSpan--
|
|
|
|
|
|
|
|
iInSpan = int32(spans[iSpan].Length)
|
|
|
|
|
|
|
|
spans[iSpan].Length++
|
|
|
|
|
|
|
|
return spans, buckets, iSpan, iBucket, iInSpan
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if iSpan < len(spans) && deltaIndex == spans[iSpan].Offset-1 {
|
|
|
|
|
|
|
|
// Directly before next span, extend next span.
|
|
|
|
|
|
|
|
iInSpan = 0
|
|
|
|
|
|
|
|
spans[iSpan].Offset--
|
|
|
|
|
|
|
|
spans[iSpan].Length++
|
|
|
|
|
|
|
|
return spans, buckets, iSpan, iBucket, iInSpan
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// No next span, or next span is not directly adjacent to new bucket.
|
|
|
|
|
|
|
|
// Add new span.
|
|
|
|
|
|
|
|
iInSpan = 0
|
|
|
|
|
|
|
|
if iSpan < len(spans) {
|
|
|
|
|
|
|
|
spans[iSpan].Offset -= deltaIndex + 1
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
spans = append(spans, Span{})
|
|
|
|
|
|
|
|
copy(spans[iSpan+1:], spans[iSpan:])
|
|
|
|
|
|
|
|
spans[iSpan] = Span{Length: 1, Offset: deltaIndex}
|
|
|
|
|
|
|
|
return spans, buckets, iSpan, iBucket, iInSpan
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// Try start of next span.
|
|
|
|
|
|
|
|
deltaIndex -= spans[iSpan].Offset
|
|
|
|
|
|
|
|
iInSpan = 0
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Compact eliminates empty buckets at the beginning and end of each span, then
|
|
|
|
// Compact eliminates empty buckets at the beginning and end of each span, then
|
|
|
|
// merges spans that are consecutive or at most maxEmptyBuckets apart, and
|
|
|
|
// merges spans that are consecutive or at most maxEmptyBuckets apart, and
|
|
|
|
// finally splits spans that contain more consecutive empty buckets than
|
|
|
|
// finally splits spans that contain more consecutive empty buckets than
|
|
|
|