github.com/JohanShen/go-utils@v1.1.4-0.20201117124024-901319a2b2a0/utils/id_generator.go (about) 1 package utils 2 3 import ( 4 "fmt" 5 "sync/atomic" 6 "time" 7 ) 8 9 type idGenerator struct { 10 num uint64 11 ch chan string 12 timestamp uint64 13 mid string 14 } 15 16 var IdGenerator = NewIdGenerator() 17 18 func NewIdGenerator() *idGenerator { 19 g := &idGenerator{ 20 num: 1, 21 ch: make(chan string), 22 mid: GetMachineId(), 23 timestamp: makeTimestamp(), 24 } 25 go g.make() 26 return g 27 } 28 29 func makeTimestamp() uint64 { 30 return uint64(time.Now().UnixNano() / 1e3) 31 } 32 33 func (g *idGenerator) make() { 34 for { 35 oct := g.timestamp*1000 + g.num 36 if id, err := Oct2Any(oct, 62); err == nil { 37 //fmt.Println(oct, g.timestamp, g.num, id) 38 atomic.AddUint64(&g.num, 1) 39 if g.num > 9999 { 40 g.timestamp = makeTimestamp() 41 atomic.AddUint64(&g.num, -g.num) 42 } 43 //atomic.StoreUint64(&g.num, 0) 44 45 g.ch <- fmt.Sprintf("%v%v", g.mid, id) 46 } 47 } 48 } 49 50 func (g *idGenerator) Next(num int) []string { 51 r := make([]string, num) 52 i := 0 53 for v := range g.ch { 54 r[i] = v 55 i++ 56 if i == num { 57 break 58 } 59 } 60 return r 61 } 62 63 func (g *idGenerator) NextId() string { 64 return <-g.ch 65 }