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  }