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  }