github.com/haraldrudell/parl@v0.4.176/counter/counter-consumer.go (about)

     1  /*
     2  © 2023–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/)
     3  ISC License
     4  */
     5  
     6  package counter
     7  
     8  import (
     9  	"sync/atomic"
    10  
    11  	"github.com/haraldrudell/parl"
    12  )
    13  
    14  // CounterConsumer is accessible value/running/max values
    15  type CounterConsumer struct {
    16  	// value is the number of Inc invocations and positive Adds
    17  	//	- value will never decrease
    18  	//	- atomic
    19  	value uint64
    20  	//	running is a value going up and down
    21  	//	- the sum of Inc less Dec invocations and positive or negative Adds
    22  	//	- will never go below 0
    23  	//	- atomic
    24  	running uint64 // atomic
    25  	// max is the greatest value running has had
    26  	//	- will never be less than 0
    27  	//	- atomic
    28  	max uint64
    29  	// a controls atomic or lock-based access to value/running/max
    30  	a accessManager
    31  }
    32  
    33  var _ parl.CounterValues = &CounterConsumer{} // Counter supports data consumers
    34  
    35  // Get returns value/running/max with integrity. Thread-Safe
    36  //   - value is the monotonically increasing value
    37  //   - running is the fluctuating running value
    38  //   - max is the highest value running has had
    39  func (c *CounterConsumer) Get() (value, running, max uint64) {
    40  	defer c.a.Lock().Unlock()
    41  
    42  	value = atomic.LoadUint64(&c.value)
    43  	running = atomic.LoadUint64(&c.running)
    44  	max = atomic.LoadUint64(&c.max)
    45  
    46  	return
    47  }
    48  
    49  // GetReset returns value/running/max with integrity and resets the counter. Thread-Safe
    50  //   - value is the monotonically increasing value
    51  //   - running is the fluctuating running value
    52  //   - max is the highest value running has had
    53  func (c *CounterConsumer) GetReset() (value, running, max uint64) {
    54  	defer c.a.Lock().Unlock()
    55  
    56  	value = atomic.SwapUint64(&c.value, 0)
    57  	running = atomic.SwapUint64(&c.running, 0)
    58  	max = atomic.SwapUint64(&c.max, 0)
    59  
    60  	return
    61  }
    62  
    63  // Value returns the monotonically increasing value
    64  //   - number of Inc invocations and positive Adds
    65  func (c *CounterConsumer) Value() (value uint64) { return atomic.LoadUint64(&c.value) }
    66  
    67  // Running returns the fluctuating running value
    68  //   - number of Inc less Dec invocations and sum of Adds
    69  //   - never below 0
    70  func (c *CounterConsumer) Running() (running uint64) { return atomic.LoadUint64(&c.running) }
    71  
    72  // Max returns the highest value running has had
    73  func (c *CounterConsumer) Max() (max uint64) { return atomic.LoadUint64(&c.max) }