github.com/intfoundation/intchain@v0.0.0-20220727031208-4316ad31ca73/metrics/counter.go (about)

     1  package metrics
     2  
     3  import "sync/atomic"
     4  
     5  // Counters hold an int64 value that can be incremented and decremented.
     6  type Counter interface {
     7  	Clear()
     8  	Count() int64
     9  	Dec(int64)
    10  	Inc(int64)
    11  	Snapshot() Counter
    12  }
    13  
    14  // GetOrRegisterCounter returns an existing Counter or constructs and registers
    15  // a new StandardCounter.
    16  func GetOrRegisterCounter(name string, r Registry) Counter {
    17  	if nil == r {
    18  		r = DefaultRegistry
    19  	}
    20  	return r.GetOrRegister(name, NewCounter).(Counter)
    21  }
    22  
    23  // NewCounter constructs a new StandardCounter.
    24  func NewCounter() Counter {
    25  	if !Enabled {
    26  		return NilCounter{}
    27  	}
    28  	return &StandardCounter{0}
    29  }
    30  
    31  // NewRegisteredCounter constructs and registers a new StandardCounter.
    32  func NewRegisteredCounter(name string, r Registry) Counter {
    33  	c := NewCounter()
    34  	if nil == r {
    35  		r = DefaultRegistry
    36  	}
    37  	r.Register(name, c)
    38  	return c
    39  }
    40  
    41  // CounterSnapshot is a read-only copy of another Counter.
    42  type CounterSnapshot int64
    43  
    44  // Clear panics.
    45  func (CounterSnapshot) Clear() {
    46  	panic("Clear called on a CounterSnapshot")
    47  }
    48  
    49  // Count returns the count at the time the snapshot was taken.
    50  func (c CounterSnapshot) Count() int64 { return int64(c) }
    51  
    52  // Dec panics.
    53  func (CounterSnapshot) Dec(int64) {
    54  	panic("Dec called on a CounterSnapshot")
    55  }
    56  
    57  // Inc panics.
    58  func (CounterSnapshot) Inc(int64) {
    59  	panic("Inc called on a CounterSnapshot")
    60  }
    61  
    62  // Snapshot returns the snapshot.
    63  func (c CounterSnapshot) Snapshot() Counter { return c }
    64  
    65  // NilCounter is a no-op Counter.
    66  type NilCounter struct{}
    67  
    68  // Clear is a no-op.
    69  func (NilCounter) Clear() {}
    70  
    71  // Count is a no-op.
    72  func (NilCounter) Count() int64 { return 0 }
    73  
    74  // Dec is a no-op.
    75  func (NilCounter) Dec(i int64) {}
    76  
    77  // Inc is a no-op.
    78  func (NilCounter) Inc(i int64) {}
    79  
    80  // Snapshot is a no-op.
    81  func (NilCounter) Snapshot() Counter { return NilCounter{} }
    82  
    83  // StandardCounter is the standard implementation of a Counter and uses the
    84  // sync/atomic package to manage a single int64 value.
    85  type StandardCounter struct {
    86  	count int64
    87  }
    88  
    89  // Clear sets the counter to zero.
    90  func (c *StandardCounter) Clear() {
    91  	atomic.StoreInt64(&c.count, 0)
    92  }
    93  
    94  // Count returns the current count.
    95  func (c *StandardCounter) Count() int64 {
    96  	return atomic.LoadInt64(&c.count)
    97  }
    98  
    99  // Dec decrements the counter by the given amount.
   100  func (c *StandardCounter) Dec(i int64) {
   101  	atomic.AddInt64(&c.count, -i)
   102  }
   103  
   104  // Inc increments the counter by the given amount.
   105  func (c *StandardCounter) Inc(i int64) {
   106  	atomic.AddInt64(&c.count, i)
   107  }
   108  
   109  // Snapshot returns a read-only copy of the counter.
   110  func (c *StandardCounter) Snapshot() Counter {
   111  	return CounterSnapshot(c.Count())
   112  }