github.com/sunblockterminal/go-sunblocktediuma@v0.0.0-20210616083421-160a35ed7cfa/metrics/counter.go (about) 1 package metrics 2 3 import ( 4 "sync/atomic" 5 ) 6 7 // Counters hold an int64 value that can be incremented and decremented. 8 type Counter interface { 9 Clear() 10 Count() int64 11 Dec(int64) 12 Inc(int64) 13 Snapshot() Counter 14 } 15 16 // GetOrRegisterCounter returns an existing Counter or constructs and registers 17 // a new StandardCounter. 18 func GetOrRegisterCounter(name string, r Registry) Counter { 19 if nil == r { 20 r = DefaultRegistry 21 } 22 return r.GetOrRegister(name, NewCounter).(Counter) 23 } 24 25 // GetOrRegisterCounterForced returns an existing Counter or constructs and registers a 26 // new Counter no matter the global switch is enabled or not. 27 // Be sure to unregister the counter from the registry once it is of no use to 28 // allow for garbage collection. 29 func GetOrRegisterCounterForced(name string, r Registry) Counter { 30 if nil == r { 31 r = DefaultRegistry 32 } 33 return r.GetOrRegister(name, NewCounterForced).(Counter) 34 } 35 36 // NewCounter constructs a new StandardCounter. 37 func NewCounter() Counter { 38 if !Enabled { 39 return NilCounter{} 40 } 41 return &StandardCounter{0} 42 } 43 44 // NewCounterForced constructs a new StandardCounter and returns it no matter if 45 // the global switch is enabled or not. 46 func NewCounterForced() Counter { 47 return &StandardCounter{0} 48 } 49 50 // NewRegisteredCounter constructs and registers a new StandardCounter. 51 func NewRegisteredCounter(name string, r Registry) Counter { 52 c := NewCounter() 53 if nil == r { 54 r = DefaultRegistry 55 } 56 r.Register(name, c) 57 return c 58 } 59 60 // NewRegisteredCounterForced constructs and registers a new StandardCounter 61 // and launches a goroutine no matter the global switch is enabled or not. 62 // Be sure to unregister the counter from the registry once it is of no use to 63 // allow for garbage collection. 64 func NewRegisteredCounterForced(name string, r Registry) Counter { 65 c := NewCounterForced() 66 if nil == r { 67 r = DefaultRegistry 68 } 69 r.Register(name, c) 70 return c 71 } 72 73 // CounterSnapshot is a read-only copy of another Counter. 74 type CounterSnapshot int64 75 76 // Clear panics. 77 func (CounterSnapshot) Clear() { 78 panic("Clear called on a CounterSnapshot") 79 } 80 81 // Count returns the count at the time the snapshot was taken. 82 func (c CounterSnapshot) Count() int64 { return int64(c) } 83 84 // Dec panics. 85 func (CounterSnapshot) Dec(int64) { 86 panic("Dec called on a CounterSnapshot") 87 } 88 89 // Inc panics. 90 func (CounterSnapshot) Inc(int64) { 91 panic("Inc called on a CounterSnapshot") 92 } 93 94 // Snapshot returns the snapshot. 95 func (c CounterSnapshot) Snapshot() Counter { return c } 96 97 // NilCounter is a no-op Counter. 98 type NilCounter struct{} 99 100 // Clear is a no-op. 101 func (NilCounter) Clear() {} 102 103 // Count is a no-op. 104 func (NilCounter) Count() int64 { return 0 } 105 106 // Dec is a no-op. 107 func (NilCounter) Dec(i int64) {} 108 109 // Inc is a no-op. 110 func (NilCounter) Inc(i int64) {} 111 112 // Snapshot is a no-op. 113 func (NilCounter) Snapshot() Counter { return NilCounter{} } 114 115 // StandardCounter is the standard implementation of a Counter and uses the 116 // sync/atomic package to manage a single int64 value. 117 type StandardCounter struct { 118 count int64 119 } 120 121 // Clear sets the counter to zero. 122 func (c *StandardCounter) Clear() { 123 atomic.StoreInt64(&c.count, 0) 124 } 125 126 // Count returns the current count. 127 func (c *StandardCounter) Count() int64 { 128 return atomic.LoadInt64(&c.count) 129 } 130 131 // Dec decrements the counter by the given amount. 132 func (c *StandardCounter) Dec(i int64) { 133 atomic.AddInt64(&c.count, -i) 134 } 135 136 // Inc increments the counter by the given amount. 137 func (c *StandardCounter) Inc(i int64) { 138 atomic.AddInt64(&c.count, i) 139 } 140 141 // Snapshot returns a read-only copy of the counter. 142 func (c *StandardCounter) Snapshot() Counter { 143 return CounterSnapshot(c.Count()) 144 }