1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
package memmetrics
import "time"
// RatioCounter calculates a ratio of a/a+b over a rolling window of predefined buckets.
type RatioCounter struct {
a *RollingCounter
b *RollingCounter
}
// NewRatioCounter creates a new RatioCounter.
func NewRatioCounter(buckets int, resolution time.Duration, options ...RatioOption) (*RatioCounter, error) {
rc := &RatioCounter{}
for _, o := range options {
if err := o(rc); err != nil {
return nil, err
}
}
a, err := NewCounter(buckets, resolution)
if err != nil {
return nil, err
}
b, err := NewCounter(buckets, resolution)
if err != nil {
return nil, err
}
rc.a = a
rc.b = b
return rc, nil
}
// Reset resets the counter.
func (r *RatioCounter) Reset() {
r.a.Reset()
r.b.Reset()
}
// IsReady returns true if the counter is ready.
func (r *RatioCounter) IsReady() bool {
return r.a.countedBuckets+r.b.countedBuckets >= len(r.a.values)
}
// CountA gets count A.
func (r *RatioCounter) CountA() int64 {
return r.a.Count()
}
// CountB gets count B.
func (r *RatioCounter) CountB() int64 {
return r.b.Count()
}
// Resolution gets resolution.
func (r *RatioCounter) Resolution() time.Duration {
return r.a.Resolution()
}
// Buckets gets buckets.
func (r *RatioCounter) Buckets() int {
return r.a.Buckets()
}
// WindowSize gets windows size.
func (r *RatioCounter) WindowSize() time.Duration {
return r.a.WindowSize()
}
// ProcessedCount gets processed count.
func (r *RatioCounter) ProcessedCount() int64 {
return r.CountA() + r.CountB()
}
// Ratio gets ratio.
func (r *RatioCounter) Ratio() float64 {
a := r.a.Count()
b := r.b.Count()
// No data, return ok
if a+b == 0 {
return 0
}
return float64(a) / float64(a+b)
}
// IncA increments counter A.
func (r *RatioCounter) IncA(v int) {
r.a.Inc(v)
}
// IncB increments counter B.
func (r *RatioCounter) IncB(v int) {
r.b.Inc(v)
}
// TestMeter a test meter.
type TestMeter struct {
Rate float64
NotReady bool
WindowSize time.Duration
}
// GetWindowSize gets windows size.
func (tm *TestMeter) GetWindowSize() time.Duration {
return tm.WindowSize
}
// IsReady returns true if the meter is ready.
func (tm *TestMeter) IsReady() bool {
return !tm.NotReady
}
// GetRate gets rate.
func (tm *TestMeter) GetRate() float64 {
return tm.Rate
}
|