github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/state/stateutil/reference.go (about) 1 package stateutil 2 3 import "sync" 4 5 // Reference structs are shared across BeaconState copies to understand when the state must use 6 // copy-on-write for shared fields or may modify a field in place when it holds the only reference 7 // to the field value. References are tracked in a map of fieldIndex -> *reference. Whenever a state 8 // releases their reference to the field value, they must decrement the refs. Likewise whenever a 9 // copy is performed then the state must increment the refs counter. 10 type Reference struct { 11 refs uint 12 lock sync.RWMutex 13 } 14 15 // NewRef initializes the Reference struct. 16 func NewRef(refs uint) *Reference { 17 return &Reference{ 18 refs: refs, 19 } 20 } 21 22 // Refs returns the reference number. 23 func (r *Reference) Refs() uint { 24 r.lock.RLock() 25 defer r.lock.RUnlock() 26 return r.refs 27 } 28 29 // AddRef adds 1 to the reference number. 30 func (r *Reference) AddRef() { 31 r.lock.Lock() 32 r.refs++ 33 r.lock.Unlock() 34 } 35 36 // MinusRef subtracts 1 to the reference number. 37 func (r *Reference) MinusRef() { 38 r.lock.Lock() 39 // Do not reduce further if object 40 // already has 0 reference to prevent underflow. 41 if r.refs > 0 { 42 r.refs-- 43 } 44 r.lock.Unlock() 45 }