github.com/codingfuture/orig-energi3@v0.8.4/metrics/counter.go (about) 1 // Copyright 2018 The Energi Core Authors 2 // Copyright 2015 The go-ethereum Authors 3 // This file is part of the Energi Core library. 4 // 5 // The Energi Core library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The Energi Core library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the Energi Core library. If not, see <http://www.gnu.org/licenses/>. 17 18 package metrics 19 20 import ( 21 "sync/atomic" 22 ) 23 24 // Counters hold an int64 value that can be incremented and decremented. 25 type Counter interface { 26 Clear() 27 Count() int64 28 Dec(int64) 29 Inc(int64) 30 Snapshot() Counter 31 } 32 33 // GetOrRegisterCounter returns an existing Counter or constructs and registers 34 // a new StandardCounter. 35 func GetOrRegisterCounter(name string, r Registry) Counter { 36 if nil == r { 37 r = DefaultRegistry 38 } 39 return r.GetOrRegister(name, NewCounter).(Counter) 40 } 41 42 // GetOrRegisterCounterForced returns an existing Counter or constructs and registers a 43 // new Counter no matter the global switch is enabled or not. 44 // Be sure to unregister the counter from the registry once it is of no use to 45 // allow for garbage collection. 46 func GetOrRegisterCounterForced(name string, r Registry) Counter { 47 if nil == r { 48 r = DefaultRegistry 49 } 50 return r.GetOrRegister(name, NewCounterForced).(Counter) 51 } 52 53 // NewCounter constructs a new StandardCounter. 54 func NewCounter() Counter { 55 if !Enabled { 56 return NilCounter{} 57 } 58 return &StandardCounter{0} 59 } 60 61 // NewCounterForced constructs a new StandardCounter and returns it no matter if 62 // the global switch is enabled or not. 63 func NewCounterForced() Counter { 64 return &StandardCounter{0} 65 } 66 67 // NewRegisteredCounter constructs and registers a new StandardCounter. 68 func NewRegisteredCounter(name string, r Registry) Counter { 69 c := NewCounter() 70 if nil == r { 71 r = DefaultRegistry 72 } 73 r.Register(name, c) 74 return c 75 } 76 77 // NewRegisteredCounterForced constructs and registers a new StandardCounter 78 // and launches a goroutine no matter the global switch is enabled or not. 79 // Be sure to unregister the counter from the registry once it is of no use to 80 // allow for garbage collection. 81 func NewRegisteredCounterForced(name string, r Registry) Counter { 82 c := NewCounterForced() 83 if nil == r { 84 r = DefaultRegistry 85 } 86 r.Register(name, c) 87 return c 88 } 89 90 // CounterSnapshot is a read-only copy of another Counter. 91 type CounterSnapshot int64 92 93 // Clear panics. 94 func (CounterSnapshot) Clear() { 95 panic("Clear called on a CounterSnapshot") 96 } 97 98 // Count returns the count at the time the snapshot was taken. 99 func (c CounterSnapshot) Count() int64 { return int64(c) } 100 101 // Dec panics. 102 func (CounterSnapshot) Dec(int64) { 103 panic("Dec called on a CounterSnapshot") 104 } 105 106 // Inc panics. 107 func (CounterSnapshot) Inc(int64) { 108 panic("Inc called on a CounterSnapshot") 109 } 110 111 // Snapshot returns the snapshot. 112 func (c CounterSnapshot) Snapshot() Counter { return c } 113 114 // NilCounter is a no-op Counter. 115 type NilCounter struct{} 116 117 // Clear is a no-op. 118 func (NilCounter) Clear() {} 119 120 // Count is a no-op. 121 func (NilCounter) Count() int64 { return 0 } 122 123 // Dec is a no-op. 124 func (NilCounter) Dec(i int64) {} 125 126 // Inc is a no-op. 127 func (NilCounter) Inc(i int64) {} 128 129 // Snapshot is a no-op. 130 func (NilCounter) Snapshot() Counter { return NilCounter{} } 131 132 // StandardCounter is the standard implementation of a Counter and uses the 133 // sync/atomic package to manage a single int64 value. 134 type StandardCounter struct { 135 count int64 136 } 137 138 // Clear sets the counter to zero. 139 func (c *StandardCounter) Clear() { 140 atomic.StoreInt64(&c.count, 0) 141 } 142 143 // Count returns the current count. 144 func (c *StandardCounter) Count() int64 { 145 return atomic.LoadInt64(&c.count) 146 } 147 148 // Dec decrements the counter by the given amount. 149 func (c *StandardCounter) Dec(i int64) { 150 atomic.AddInt64(&c.count, -i) 151 } 152 153 // Inc increments the counter by the given amount. 154 func (c *StandardCounter) Inc(i int64) { 155 atomic.AddInt64(&c.count, i) 156 } 157 158 // Snapshot returns a read-only copy of the counter. 159 func (c *StandardCounter) Snapshot() Counter { 160 return CounterSnapshot(c.Count()) 161 }