github.com/pharosnet/flyline@v1.0.2/sequence.go (about) 1 package flyline 2 3 import ( 4 "runtime" 5 "sync/atomic" 6 "time" 7 ) 8 9 const ( 10 padding = 7 11 ) 12 13 // Sequence New Function, value starts from -1. 14 func NewSequence() (seq *Sequence) { 15 seq = &Sequence{value: int64(-1)} 16 return 17 } 18 19 // sequence, atomic operators. 20 type Sequence struct { 21 value int64 22 rhs [padding]int64 23 } 24 25 // Atomic increment 26 func (s *Sequence) Incr() (value int64) { 27 times := 10 28 for { 29 times-- 30 nextValue := s.Get() + 1 31 ok := atomic.CompareAndSwapInt64(&s.value, s.value, nextValue) 32 if ok { 33 value = nextValue 34 break 35 } 36 time.Sleep(1 * time.Nanosecond) 37 if times <= 0 { 38 times = 10 39 runtime.Gosched() 40 } 41 } 42 return 43 } 44 45 // Atomic decrement 46 func (s *Sequence) Decr() (value int64) { 47 times := 10 48 for { 49 times-- 50 preValue := s.Get() - 1 51 ok := atomic.CompareAndSwapInt64(&s.value, s.value, preValue) 52 if ok { 53 value = preValue 54 break 55 } 56 time.Sleep(1 * time.Nanosecond) 57 if times <= 0 { 58 times = 10 59 runtime.Gosched() 60 } 61 } 62 return 63 } 64 65 // Atomic get Sequence value. 66 func (s *Sequence) Get() (value int64) { 67 value = atomic.LoadInt64(&s.value) 68 return 69 }