2020-07-26 17:09:05 +08:00
|
|
|
package collection
|
|
|
|
|
2023-11-24 21:27:05 +08:00
|
|
|
import "sync"
|
2021-02-03 21:41:10 +08:00
|
|
|
|
2021-02-18 15:49:56 +08:00
|
|
|
// A Ring can be used as fixed size ring.
|
2020-07-26 17:09:05 +08:00
|
|
|
type Ring struct {
|
2023-01-24 16:32:02 +08:00
|
|
|
elements []any
|
2020-07-26 17:09:05 +08:00
|
|
|
index int
|
2022-12-26 15:00:47 +08:00
|
|
|
lock sync.RWMutex
|
2020-07-26 17:09:05 +08:00
|
|
|
}
|
|
|
|
|
2021-02-18 15:49:56 +08:00
|
|
|
// NewRing returns a Ring object with the given size n.
|
2020-07-26 17:09:05 +08:00
|
|
|
func NewRing(n int) *Ring {
|
2020-10-15 14:25:10 +08:00
|
|
|
if n < 1 {
|
|
|
|
panic("n should be greater than 0")
|
|
|
|
}
|
|
|
|
|
2020-07-26 17:09:05 +08:00
|
|
|
return &Ring{
|
2023-01-24 16:32:02 +08:00
|
|
|
elements: make([]any, n),
|
2020-07-26 17:09:05 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-18 15:49:56 +08:00
|
|
|
// Add adds v into r.
|
2023-01-24 16:32:02 +08:00
|
|
|
func (r *Ring) Add(v any) {
|
2021-02-03 21:41:10 +08:00
|
|
|
r.lock.Lock()
|
|
|
|
defer r.lock.Unlock()
|
2021-02-05 13:32:56 +08:00
|
|
|
|
2023-11-23 23:57:26 +08:00
|
|
|
rlen := len(r.elements)
|
|
|
|
r.elements[r.index%rlen] = v
|
2020-07-26 17:09:05 +08:00
|
|
|
r.index++
|
2023-11-23 23:44:33 +08:00
|
|
|
|
|
|
|
// prevent ring index overflow
|
2023-11-23 23:57:26 +08:00
|
|
|
if r.index >= rlen<<1 {
|
|
|
|
r.index -= rlen
|
2023-11-23 23:44:33 +08:00
|
|
|
}
|
2020-07-26 17:09:05 +08:00
|
|
|
}
|
|
|
|
|
2021-02-18 15:49:56 +08:00
|
|
|
// Take takes all items from r.
|
2023-01-24 16:32:02 +08:00
|
|
|
func (r *Ring) Take() []any {
|
2022-12-26 15:00:47 +08:00
|
|
|
r.lock.RLock()
|
|
|
|
defer r.lock.RUnlock()
|
2021-02-03 21:41:10 +08:00
|
|
|
|
2020-07-26 17:09:05 +08:00
|
|
|
var size int
|
|
|
|
var start int
|
2023-11-23 23:57:26 +08:00
|
|
|
rlen := len(r.elements)
|
2023-11-23 23:44:33 +08:00
|
|
|
|
2023-11-23 23:57:26 +08:00
|
|
|
if r.index > rlen {
|
|
|
|
size = rlen
|
|
|
|
start = r.index % rlen
|
2020-07-26 17:09:05 +08:00
|
|
|
} else {
|
|
|
|
size = r.index
|
|
|
|
}
|
|
|
|
|
2023-01-24 16:32:02 +08:00
|
|
|
elements := make([]any, size)
|
2020-07-26 17:09:05 +08:00
|
|
|
for i := 0; i < size; i++ {
|
2023-11-23 23:57:26 +08:00
|
|
|
elements[i] = r.elements[(start+i)%rlen]
|
2020-07-26 17:09:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return elements
|
|
|
|
}
|