MCPcopy
hub / github.com/prometheus/client_golang / maybeWidenZeroBucket

Method maybeWidenZeroBucket

prometheus/histogram.go:1017–1081  ·  view source on GitHub ↗

maybeWidenZeroBucket widens the zero bucket until it includes the existing buckets closest to the zero bucket (which could be two, if an equidistant negative and a positive bucket exists, but usually it's only one bucket to be merged into the new wider zero bucket). h.nativeHistogramMaxZeroThreshold

(hot, cold *histogramCounts)

Source from the content-addressed store, hash-verified

1015// include an existing bucket, the method returns false. The caller must have
1016// locked h.mtx.
1017func (h *histogram) maybeWidenZeroBucket(hot, cold *histogramCounts) bool {
1018 currentZeroThreshold := math.Float64frombits(atomic.LoadUint64(&hot.nativeHistogramZeroThresholdBits))
1019 if currentZeroThreshold >= h.nativeHistogramMaxZeroThreshold {
1020 return false
1021 }
1022 // Find the key of the bucket closest to zero.
1023 smallestKey := findSmallestKey(&hot.nativeHistogramBucketsPositive)
1024 smallestNegativeKey := findSmallestKey(&hot.nativeHistogramBucketsNegative)
1025 if smallestNegativeKey < smallestKey {
1026 smallestKey = smallestNegativeKey
1027 }
1028 if smallestKey == math.MaxInt32 {
1029 return false
1030 }
1031 newZeroThreshold := getLe(smallestKey, atomic.LoadInt32(&hot.nativeHistogramSchema))
1032 if newZeroThreshold > h.nativeHistogramMaxZeroThreshold {
1033 return false // New threshold would exceed the max threshold.
1034 }
1035 atomic.StoreUint64(&cold.nativeHistogramZeroThresholdBits, math.Float64bits(newZeroThreshold))
1036 // Remove applicable buckets.
1037 if _, loaded := cold.nativeHistogramBucketsNegative.LoadAndDelete(smallestKey); loaded {
1038 atomicDecUint32(&cold.nativeHistogramBucketsNumber)
1039 }
1040 if _, loaded := cold.nativeHistogramBucketsPositive.LoadAndDelete(smallestKey); loaded {
1041 atomicDecUint32(&cold.nativeHistogramBucketsNumber)
1042 }
1043 // Make cold counts the new hot counts.
1044 n := atomic.AddUint64(&h.countAndHotIdx, 1<<63)
1045 count := n & ((1 << 63) - 1)
1046 // Swap the pointer names to represent the new roles and make
1047 // the rest less confusing.
1048 hot, cold = cold, hot
1049 waitForCooldown(count, cold)
1050 // Add all the now cold counts to the new hot counts...
1051 addAndResetCounts(hot, cold)
1052 // ...adjust the new zero threshold in the cold counts, too...
1053 atomic.StoreUint64(&cold.nativeHistogramZeroThresholdBits, math.Float64bits(newZeroThreshold))
1054 // ...and then merge the newly deleted buckets into the wider zero
1055 // bucket.
1056 mergeAndDeleteOrAddAndReset := func(hotBuckets, coldBuckets *sync.Map) func(k, v interface{}) bool {
1057 return func(k, v interface{}) bool {
1058 key := k.(int)
1059 bucket := v.(*int64)
1060 if key == smallestKey {
1061 // Merge into hot zero bucket...
1062 atomic.AddUint64(&hot.nativeHistogramZeroBucket, uint64(atomic.LoadInt64(bucket)))
1063 // ...and delete from cold counts.
1064 coldBuckets.Delete(key)
1065 atomicDecUint32(&cold.nativeHistogramBucketsNumber)
1066 } else {
1067 // Add to corresponding hot bucket...
1068 if addToBucket(hotBuckets, key, atomic.LoadInt64(bucket)) {
1069 atomic.AddUint32(&hot.nativeHistogramBucketsNumber, 1)
1070 }
1071 // ...and reset cold bucket.
1072 atomic.StoreInt64(bucket, 0)
1073 }
1074 return true

Callers 1

limitBucketsMethod · 0.95

Calls 7

findSmallestKeyFunction · 0.85
getLeFunction · 0.85
atomicDecUint32Function · 0.85
waitForCooldownFunction · 0.85
addAndResetCountsFunction · 0.85
addToBucketFunction · 0.85
DeleteMethod · 0.45

Tested by

no test coverage detected