Co-authored-by: liuhuan210 <liuhuan210@jd.com>
@@ -1,8 +1,11 @@
package collection
+import "sync"
+
type Ring struct {
elements []interface{}
index int
+ lock sync.Mutex
}
func NewRing(n int) *Ring {
@@ -16,11 +19,16 @@ func NewRing(n int) *Ring {
func (r *Ring) Add(v interface{}) {
+ r.lock.Lock()
+ defer r.lock.Unlock()
r.elements[r.index%len(r.elements)] = v
r.index++
func (r *Ring) Take() []interface{} {
var size int
var start int
if r.index > len(r.elements) {
@@ -1,6 +1,7 @@
import (
+ "sync"
"testing"
"github.com/stretchr/testify/assert"
@@ -29,3 +30,30 @@ func TestRingMore(t *testing.T) {
elements := ring.Take()
assert.ElementsMatch(t, []interface{}{6, 7, 8, 9, 10}, elements)
+func BenchmarkRingAdd(b *testing.B) {
+ ring := NewRing(500)
+ b.RunParallel(func(pb *testing.PB) {
+ for pb.Next() {
+ for i := 0; i < b.N; i++ {
+ ring.Add(i)
+ }
+ })
+}
+func TestRingAdd(t *testing.T) {
+ ring := NewRing(5051)
+ wg := sync.WaitGroup{}
+ for i := 1; i <= 100; i++ {
+ wg.Add(1)
+ go func(i int) {
+ defer wg.Done()
+ for j := 1; j <= i; j++ {
+ }(i)
+ wg.Wait()
+ assert.Equal(t, 5050, len(ring.Take()))