You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
go-zero/core/collection/ring.go

64 lines
1019 B
Go

4 years ago
package collection
import (
"sync"
)
// A Ring can be used as fixed size ring.
4 years ago
type Ring struct {
elements []any
4 years ago
index int
lock sync.RWMutex
4 years ago
}
// NewRing returns a Ring object with the given size n.
4 years ago
func NewRing(n int) *Ring {
4 years ago
if n < 1 {
panic("n should be greater than 0")
}
4 years ago
return &Ring{
elements: make([]any, n),
4 years ago
}
}
// Add adds v into r.
func (r *Ring) Add(v any) {
r.lock.Lock()
defer r.lock.Unlock()
ringLength := len(r.elements)
r.elements[r.index%ringLength] = v
4 years ago
r.index++
// prevent ring index overflow
if r.index/ringLength >= 2 {
r.index = r.index - ringLength
}
4 years ago
}
// Take takes all items from r.
func (r *Ring) Take() []any {
r.lock.RLock()
defer r.lock.RUnlock()
4 years ago
var size int
var start int
ringLength := len(r.elements)
if r.index > ringLength {
size = ringLength
start = r.index % ringLength
4 years ago
} else {
size = r.index
}
elements := make([]any, size)
4 years ago
for i := 0; i < size; i++ {
elements[i] = r.elements[(start+i)%ringLength]
4 years ago
}
return elements
}