github.com/aaabigfish/gopkg@v1.1.0/stat/counter/counter.go (about)

     1  package counter
     2  
     3  import (
     4  	"sync"
     5  )
     6  
     7  // Counter is a counter interface.
     8  type Counter interface {
     9  	Add(int64)
    10  	Reset()
    11  	Value() int64
    12  }
    13  
    14  // Group is a counter group.
    15  type Group struct {
    16  	mu   sync.RWMutex
    17  	vecs map[string]Counter
    18  
    19  	// New optionally specifies a function to generate a counter.
    20  	// It may not be changed concurrently with calls to other functions.
    21  	New func() Counter
    22  }
    23  
    24  // Add add a counter by a specified key, if counter not exists then make a new one and return new value.
    25  func (g *Group) Add(key string, value int64) {
    26  	g.mu.RLock()
    27  	vec, ok := g.vecs[key]
    28  	g.mu.RUnlock()
    29  	if !ok {
    30  		vec = g.New()
    31  		g.mu.Lock()
    32  		if g.vecs == nil {
    33  			g.vecs = make(map[string]Counter)
    34  		}
    35  		if _, ok = g.vecs[key]; !ok {
    36  			g.vecs[key] = vec
    37  		}
    38  		g.mu.Unlock()
    39  	}
    40  	vec.Add(value)
    41  }
    42  
    43  // Value get a counter value by key.
    44  func (g *Group) Value(key string) int64 {
    45  	g.mu.RLock()
    46  	vec, ok := g.vecs[key]
    47  	g.mu.RUnlock()
    48  	if ok {
    49  		return vec.Value()
    50  	}
    51  	return 0
    52  }
    53  
    54  // Reset reset a counter by key.
    55  func (g *Group) Reset(key string) {
    56  	g.mu.RLock()
    57  	vec, ok := g.vecs[key]
    58  	g.mu.RUnlock()
    59  	if ok {
    60  		vec.Reset()
    61  	}
    62  }