core/stat/base/metric_bucket.go (65 lines of code) (raw):

// Copyright 1999-2020 Alibaba Group Holding Ltd. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package base import ( "sync/atomic" "github.com/alibaba/sentinel-golang/core/base" "github.com/alibaba/sentinel-golang/logging" "github.com/pkg/errors" ) // MetricBucket represents the entity to record metrics per minimum time unit (i.e. the bucket time span). // Note that all operations of the MetricBucket are required to be thread-safe. type MetricBucket struct { // Value of statistic counter [base.MetricEventTotal]int64 minRt int64 maxConcurrency int32 } func NewMetricBucket() *MetricBucket { mb := &MetricBucket{ minRt: base.DefaultStatisticMaxRt, maxConcurrency: 0, } return mb } // Add statistic count for the given metric event. func (mb *MetricBucket) Add(event base.MetricEvent, count int64) { if event >= base.MetricEventTotal || event < 0 { logging.Error(errors.Errorf("Unknown metric event: %v", event), "") return } if event == base.MetricEventRt { mb.AddRt(count) return } mb.addCount(event, count) } func (mb *MetricBucket) addCount(event base.MetricEvent, count int64) { atomic.AddInt64(&mb.counter[event], count) } // Get current statistic count of the given metric event. func (mb *MetricBucket) Get(event base.MetricEvent) int64 { if event >= base.MetricEventTotal || event < 0 { logging.Error(errors.Errorf("Unknown metric event: %v", event), "") return 0 } return atomic.LoadInt64(&mb.counter[event]) } func (mb *MetricBucket) reset() { for i := 0; i < int(base.MetricEventTotal); i++ { atomic.StoreInt64(&mb.counter[i], 0) } atomic.StoreInt64(&mb.minRt, base.DefaultStatisticMaxRt) atomic.StoreInt32(&mb.maxConcurrency, int32(0)) } func (mb *MetricBucket) AddRt(rt int64) { mb.addCount(base.MetricEventRt, rt) if rt < atomic.LoadInt64(&mb.minRt) { // Might not be accurate here. atomic.StoreInt64(&mb.minRt, rt) } } func (mb *MetricBucket) MinRt() int64 { return atomic.LoadInt64(&mb.minRt) } func (mb *MetricBucket) UpdateConcurrency(concurrency int32) { cc := concurrency if cc > atomic.LoadInt32(&mb.maxConcurrency) { // Might not be accurate here. atomic.StoreInt32(&mb.maxConcurrency, cc) } } func (mb *MetricBucket) MaxConcurrency() int32 { return atomic.LoadInt32(&mb.maxConcurrency) }