github.com/hata/goseq@v0.0.0-20150316021154-a5ca66a92399/sequence.go (about) 1 package goseq 2 3 import "sync/atomic" 4 5 const ( 6 initialSequenceValue = -1 7 ) 8 9 type SequenceID int64 10 11 type Sequence interface { 12 Get() SequenceID 13 Set(newSequenceID SequenceID) 14 Next() SequenceID 15 } 16 17 type sequence struct { 18 value int64 19 } 20 21 func NewSequence() Sequence { 22 return newSequence() 23 } 24 25 func newSequence() (seq *sequence) { 26 seq = new(sequence) 27 seq.set(initialSequenceValue) 28 return 29 } 30 31 func (seq *sequence) Get() SequenceID { 32 return SequenceID(seq.get()) 33 } 34 35 func (seq *sequence) Set(newSequenceID SequenceID) { 36 seq.set(int64(newSequenceID)) 37 } 38 39 func (seq *sequence) Next() SequenceID { 40 return SequenceID(seq.incrementAndGet()) 41 } 42 43 func (seq *sequence) get() int64 { 44 return atomic.LoadInt64(&seq.value) 45 } 46 47 func (seq *sequence) set(v int64) { 48 atomic.StoreInt64(&seq.value, v) 49 } 50 51 func (seq *sequence) incrementAndGet() int64 { 52 return atomic.AddInt64(&seq.value, 1) 53 } 54 55 func (seq *sequence) compareAndSet(expected int64, v int64) bool { 56 return atomic.CompareAndSwapInt64(&seq.value, expected, v) 57 } 58 59 func (seq *sequence) addAndGet(delta int64) int64 { 60 var current, newvalue int64 61 for { 62 current = seq.get() 63 newvalue = current + delta 64 if seq.compareAndSet(current, newvalue) { 65 return newvalue 66 } 67 } 68 }