github.com/koko1123/flow-go-1@v0.29.6/engine/consensus/sealing/counters/monotonous_counter.go (about)

     1  package counters
     2  
     3  import "sync/atomic"
     4  
     5  // StrictMonotonousCounter is a helper struct which implements a strict monotonous counter.
     6  // StrictMonotonousCounter is implemented using atomic operations and doesn't allow to set a value
     7  // which is lower or equal to the already stored one. The counter is implemented
     8  // solely with  non-blocking atomic operations for concurrency safety.
     9  type StrictMonotonousCounter struct {
    10  	atomicCounter uint64
    11  }
    12  
    13  // NewMonotonousCounter creates new counter with initial value
    14  func NewMonotonousCounter(initialValue uint64) StrictMonotonousCounter {
    15  	return StrictMonotonousCounter{
    16  		atomicCounter: initialValue,
    17  	}
    18  }
    19  
    20  // Set updates value of counter if and only if it's strictly larger than value which is already stored.
    21  // Returns true if update was successful or false if stored value is larger.
    22  func (c *StrictMonotonousCounter) Set(newValue uint64) bool {
    23  	for {
    24  		oldValue := c.Value()
    25  		if newValue <= oldValue {
    26  			return false
    27  		}
    28  		if atomic.CompareAndSwapUint64(&c.atomicCounter, oldValue, newValue) {
    29  			return true
    30  		}
    31  	}
    32  }
    33  
    34  // Value returns value which is stored in atomic variable
    35  func (c *StrictMonotonousCounter) Value() uint64 {
    36  	return atomic.LoadUint64(&c.atomicCounter)
    37  }