github.com/zjj1991/quorum@v0.0.0-20190524123704-ae4b0a1e1a19/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  }