-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathseqid.go
62 lines (51 loc) · 1.22 KB
/
seqid.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
package idgen
const (
SEQ_BITS_WORKER_ID = 10
SEQ_BITS_ID = 63 - SEQ_BITS_WORKER_ID
)
var (
SEQ_MAX_SEQ = uint64(1<<SEQ_BITS_ID - 1) // (2**53-1 = 9,007,199,254,740,991)
SEQ_MAX_WORKER_ID = uint16(1<<SEQ_BITS_WORKER_ID - 1) // (2**10-1 = 1023)
SEQ_BLANK_ITEM = struct{}{}
)
type SeqIdGenerator struct {
workerId uint16
nextId uint64
exit bool
idReq chan struct{}
idRes chan uint64
}
func NewSeqIdGenerator(workerId uint16, startId uint64) *SeqIdGenerator {
if workerId > SEQ_MAX_WORKER_ID {
return nil
}
if startId >= SEQ_MAX_SEQ {
return nil
}
nextId := uint64(workerId) << uint64(SEQ_BITS_ID) | startId
ig := &SeqIdGenerator{workerId, nextId, false, make(chan struct{}), make(chan uint64)}
go ig.generator()
return ig
}
func (ig *SeqIdGenerator) generator() {
for range ig.idReq {
ig.idRes <- ig.nextId
ig.nextId++
}
}
func (ig *SeqIdGenerator) NextID() uint64 {
ig.idReq <- SEQ_BLANK_ITEM
return <-ig.idRes
}
func (ig *SeqIdGenerator) Exit() {
if ig.exit {
return
}
ig.exit = true
close(ig.idReq)
}
func DecomposeSeq(id uint64) (workerId uint16, sequence uint64) {
workerId = uint16(id >> uint64(SEQ_BITS_ID)) & SEQ_MAX_WORKER_ID
sequence = id & SEQ_MAX_SEQ
return
}