-
Notifications
You must be signed in to change notification settings - Fork 1
/
sequence.go
69 lines (62 loc) · 1.06 KB
/
sequence.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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package flyline
import (
"runtime"
"sync/atomic"
"time"
)
const (
padding = 7
)
// Sequence New Function, value starts from -1.
func NewSequence() (seq *Sequence) {
seq = &Sequence{value: int64(-1)}
return
}
// sequence, atomic operators.
type Sequence struct {
value int64
rhs [padding]int64
}
// Atomic increment
func (s *Sequence) Incr() (value int64) {
times := 10
for {
times--
nextValue := s.Get() + 1
ok := atomic.CompareAndSwapInt64(&s.value, s.value, nextValue)
if ok {
value = nextValue
break
}
time.Sleep(1 * time.Nanosecond)
if times <= 0 {
times = 10
runtime.Gosched()
}
}
return
}
// Atomic decrement
func (s *Sequence) Decr() (value int64) {
times := 10
for {
times--
preValue := s.Get() - 1
ok := atomic.CompareAndSwapInt64(&s.value, s.value, preValue)
if ok {
value = preValue
break
}
time.Sleep(1 * time.Nanosecond)
if times <= 0 {
times = 10
runtime.Gosched()
}
}
return
}
// Atomic get Sequence value.
func (s *Sequence) Get() (value int64) {
value = atomic.LoadInt64(&s.value)
return
}