idworker.go 1.3 KB
package idworker

import (
	"sync"
	"time"
)

const (
	twepoch      int64 = 1483200000000 // 默认起始的毫秒时间戳 1483200000000 。计算时,减去这个值
	sequenceBits uint  = 12            //自增ID 所占用位置
	sequenceMax  int64 = -1 ^ (-1 << sequenceBits)
	timeShift    uint  = sequenceBits
)

/*
* 1 符号位  |  39 时间戳                                    | 12 (毫秒内)自增ID
* 0        |  0000000 00000000 00000000 00000000 00000000  |  000000 000000
*
 */

type IdWorker struct {
	sequence      int64 //序号
	lastTimestamp int64 //最后的时间戳
	mutex         sync.Mutex
	twepoch       int64 //默认起始的毫秒时间戳
}

func NewIdWorker() *IdWorker {
	idworker := &IdWorker{
		lastTimestamp: -1,
		sequence:      0,
		twepoch:       twepoch,
		mutex:         sync.Mutex{},
	}
	return idworker
}

func (n *IdWorker) Generate() int64 {
	n.mutex.Lock()
	defer n.mutex.Unlock()
	now := time.Now().UnixNano() / 1e6
	if n.lastTimestamp == now {
		n.sequence++
		if n.sequence > sequenceMax {
			for now <= n.lastTimestamp {
				now = time.Now().UnixNano() / 1e6
			}
		}
	} else {
		n.sequence = 0
	}
	n.lastTimestamp = now
	result := (now-twepoch)<<timeShift | n.sequence
	return result
}

var newIdworker = NewIdWorker()

//NextId 新的id, 15 个数字的 id
func NextId() int64 {
	return newIdworker.Generate()
}