github.com/lingyao2333/mo-zero@v1.4.1/core/collection/ring.go (about)

     1  package collection
     2  
     3  import "sync"
     4  
     5  // A Ring can be used as fixed size ring.
     6  type Ring struct {
     7  	elements []interface{}
     8  	index    int
     9  	lock     sync.Mutex
    10  }
    11  
    12  // NewRing returns a Ring object with the given size n.
    13  func NewRing(n int) *Ring {
    14  	if n < 1 {
    15  		panic("n should be greater than 0")
    16  	}
    17  
    18  	return &Ring{
    19  		elements: make([]interface{}, n),
    20  	}
    21  }
    22  
    23  // Add adds v into r.
    24  func (r *Ring) Add(v interface{}) {
    25  	r.lock.Lock()
    26  	defer r.lock.Unlock()
    27  
    28  	r.elements[r.index%len(r.elements)] = v
    29  	r.index++
    30  }
    31  
    32  // Take takes all items from r.
    33  func (r *Ring) Take() []interface{} {
    34  	r.lock.Lock()
    35  	defer r.lock.Unlock()
    36  
    37  	var size int
    38  	var start int
    39  	if r.index > len(r.elements) {
    40  		size = len(r.elements)
    41  		start = r.index % len(r.elements)
    42  	} else {
    43  		size = r.index
    44  	}
    45  
    46  	elements := make([]interface{}, size)
    47  	for i := 0; i < size; i++ {
    48  		elements[i] = r.elements[(start+i)%len(r.elements)]
    49  	}
    50  
    51  	return elements
    52  }