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  }