Last active
August 15, 2019 14:37
-
-
Save ravlio/296032849c6881ec757c9d3670128a68 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package rr_item_test | |
/* | |
Example of round robin with elements of arbitrary types based of interface method `Value() interface{}` and also with Stringer. | |
*/ | |
import ( | |
"github.com/stretchr/testify/require" | |
"strconv" | |
"sync" | |
"testing" | |
) | |
type Item interface { | |
Value() interface{} | |
String() string | |
} | |
type Int int | |
func (i Int) Value() interface{} { | |
return i | |
} | |
func (i Int) String() string { | |
return strconv.Itoa(int(i)) | |
} | |
type String string | |
func (i String) Value() interface{} { | |
return i | |
} | |
func (i String) String() string { | |
return string(i) | |
} | |
type Roundrobin struct { | |
cur int // current elem position | |
obj []Item // elements slice | |
mx sync.RWMutex // sync mutex | |
} | |
// constructor | |
func New(i ...Item) *Roundrobin { | |
ret := &Roundrobin{} | |
ret.Add(i...) | |
return ret | |
} | |
func (r *Roundrobin) Add(i ...Item) { | |
r.mx.Lock() | |
// defer could affect performance, so we could move unlock at the end of function in production | |
defer r.mx.Unlock() | |
r.obj = append(r.obj, i...) | |
} | |
func (r *Roundrobin) Next() Item { | |
r.mx.RLock() | |
defer r.mx.RUnlock() | |
ret := r.obj[r.cur] | |
r.cur = (r.cur + 1) % len(r.obj) // Calculates next element id | |
return ret | |
} | |
func TestRR(t *testing.T) { | |
rr := New(Int(1), Int(2), String("3")) | |
require.Equal(t, Int(1), rr.Next()) | |
require.Equal(t, Int(2), rr.Next()) | |
require.Equal(t, String("3"), rr.Next()) | |
require.Equal(t, Int(1), rr.Next()) | |
rr.Add(Int(4), Int(5), String("6")) | |
require.Equal(t, "2", rr.Next().String()) | |
require.Equal(t, "3", rr.Next().String()) | |
require.Equal(t, "4", rr.Next().String()) | |
require.Equal(t, "5", rr.Next().String()) | |
require.Equal(t, "6", rr.Next().String()) | |
require.Equal(t, "1", rr.Next().String()) | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package rr_test | |
/* | |
Пример раунд робина с элементами конкретного типа int | |
*/ | |
import ( | |
"github.com/stretchr/testify/require" | |
"math/rand" | |
"sync" | |
"testing" | |
) | |
type Roundrobin struct { | |
cur int // current elem position | |
obj []int // elements slice | |
mx sync.RWMutex // sync mutex | |
} | |
// constructor | |
func New(i ...int) *Roundrobin { | |
ret := &Roundrobin{} | |
ret.Add(i...) | |
return ret | |
} | |
func (r *Roundrobin) Add(i ...int) { | |
r.mx.Lock() | |
// defer could affect performance, so we could move unlock at the end of function in production | |
defer r.mx.Unlock() | |
r.obj = append(r.obj, i...) | |
} | |
func (r *Roundrobin) Next() int { | |
r.mx.RLock() | |
defer r.mx.RUnlock() | |
ret := r.obj[r.cur] | |
r.cur = (r.cur + 1) % len(r.obj) // Calculates next element id | |
return ret | |
} | |
func TestRR(t *testing.T) { | |
rr := New(1, 2, 3) | |
require.Equal(t, 1, rr.Next()) | |
require.Equal(t, 2, rr.Next()) | |
require.Equal(t, 3, rr.Next()) | |
require.Equal(t, 1, rr.Next()) | |
rr.Add(4, 5, 6) | |
require.Equal(t, 2, rr.Next()) | |
require.Equal(t, 3, rr.Next()) | |
require.Equal(t, 4, rr.Next()) | |
require.Equal(t, 5, rr.Next()) | |
require.Equal(t, 6, rr.Next()) | |
require.Equal(t, 1, rr.Next()) | |
} | |
func BenchmarkRR(b *testing.B) { | |
rr := New(1, 2, 3) | |
b.RunParallel(func(pb *testing.PB) { | |
for pb.Next() { | |
// Randomly adding elements | |
if rand.Intn(10) == 1 { | |
rr.Add(rand.Intn(1000)) | |
} | |
rr.Next() | |
} | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment