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 }