github.com/cdoern/storage@v1.12.13/drivers/counter.go (about)

     1  package graphdriver
     2  
     3  import "sync"
     4  
     5  type minfo struct {
     6  	check bool
     7  	count int
     8  }
     9  
    10  // RefCounter is a generic counter for use by graphdriver Get/Put calls
    11  type RefCounter struct {
    12  	counts  map[string]*minfo
    13  	mu      sync.Mutex
    14  	checker Checker
    15  }
    16  
    17  // NewRefCounter returns a new RefCounter
    18  func NewRefCounter(c Checker) *RefCounter {
    19  	return &RefCounter{
    20  		checker: c,
    21  		counts:  make(map[string]*minfo),
    22  	}
    23  }
    24  
    25  // Increment increases the ref count for the given id and returns the current count
    26  func (c *RefCounter) Increment(path string) int {
    27  	return c.incdec(path, func(minfo *minfo) {
    28  		minfo.count++
    29  	})
    30  }
    31  
    32  // Decrement decreases the ref count for the given id and returns the current count
    33  func (c *RefCounter) Decrement(path string) int {
    34  	return c.incdec(path, func(minfo *minfo) {
    35  		minfo.count--
    36  	})
    37  }
    38  
    39  func (c *RefCounter) incdec(path string, infoOp func(minfo *minfo)) int {
    40  	c.mu.Lock()
    41  	m := c.counts[path]
    42  	if m == nil {
    43  		m = &minfo{}
    44  		c.counts[path] = m
    45  	}
    46  	// if we are checking this path for the first time check to make sure
    47  	// if it was already mounted on the system and make sure we have a correct ref
    48  	// count if it is mounted as it is in use.
    49  	if !m.check {
    50  		m.check = true
    51  		if c.checker.IsMounted(path) {
    52  			m.count++
    53  		}
    54  	}
    55  	infoOp(m)
    56  	count := m.count
    57  	c.mu.Unlock()
    58  	return count
    59  }