github.com/theQRL/go-zond@v0.1.1/metrics/counter.go (about)

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