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 }