-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathoffset.go
53 lines (43 loc) · 1.34 KB
/
offset.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package equalizer
import (
"math/rand"
"sync/atomic"
)
// The Offset component is responsible for advancing the head position of the
// Equalizer tape after each request. Implementations of Offset must be thread-safe.
type Offset interface {
NextIndex() int
}
// RandomOffset is an offset manager that uses a random-based offset approach.
type RandomOffset struct {
Len int
}
var _ Offset = (*RandomOffset)(nil)
// NewRandomOffset returns a new RandomOffset, where len is the bitmap tape length.
func NewRandomOffset(len int) *RandomOffset {
return &RandomOffset{Len: len}
}
// NextIndex returns the next random index within a tape.
func (ro *RandomOffset) NextIndex() int {
return rand.Intn(ro.Len)
}
// StepOffset is an offset manager that uses a fixed step approach.
type StepOffset struct {
Len int
Step int64
prev atomic.Int64
}
var _ Offset = (*StepOffset)(nil)
// NewStepOffset allocates and returns a new StepOffset, where len is the length
// of the bitmap tape and step is the offset to be taken from the previous position.
func NewStepOffset(len, step int) *StepOffset {
return &StepOffset{
Len: len,
Step: int64(step),
}
}
// NextIndex returns the next index in a round-robin fashion,
// utilizing the specified step value to advance along the tape.
func (so *StepOffset) NextIndex() int {
return int(so.prev.Add(so.Step)) % so.Len
}