雪花算法id长度_分布式全局ID生成器(雪花算法golang无锁版)

//github地址:https://github.com/chenjie199234/Corelib/tree/master/id
var offset uint64 = uint64(time.Date(2020, 5, 21, 13, 14, 0, 0, time.UTC).Unix())

var lasttime uint64
var serverid uint64
var rollback uint64

//64bit data
//00000000000000000000000000000000         000                000000               0          0000000000000000000000
//----32 bit timestamp(second)------3bit time rollback-----6bit serverid----1bit maxid lock-------22bit id----------
//-----can support 136 years--------rollback 8 times/s---can support 60 servers----------can make 4,000,000+ ids in one second
var base uint64

func init() {
	if serverid <= 0 || serverid >= 64 {
		panic("[ID.init]serviceid range wrong,only support [1-63]")
	}
	now := uint64(time.Now().Unix())
	templasttime := now - offset
	if now <= offset || templasttime > (1<<32-1) {
		panic("[ID.init]server time wrong")
	}
	lasttime = templasttime
	base = getlasttime() + getrollback() + getserverid()
	go func() {
		tker := time.NewTicker(200 * time.Millisecond)
		for {
			<-tker.C
			now = uint64(time.Now().Unix())
			templasttime = now - offset
			if now <= offset || templasttime > (1<<32-1) {
				panic("[ID.init]server time wrong")
			}
			if templasttime < lasttime {
				rollback++
				fmt.Printf("[ID.init]server time rollback,old time:%d current time:%d rollback:%dn", lasttime, templasttime, rollback&7)
			}
                        if lasttime != templasttime {
		                lasttime = templasttime
			        base = getlasttime() + getrollback() + getserverid()
                        }
		}
	}()
}
func getlasttime() uint64 {
	return lasttime << 32
}
func getrollback() uint64 {
	return (rollback & 7) << 29
}
func getserverid() uint64 {
	return serverid << 23
}

func GetId() (uint64,error) {
	if (base & (1 << 22)) > 0 {
		return 0, fmt.Errorf("[ID.GetId]max id used up")
	}
	newid := atomic.AddUint64(&base, 1)
	if (newid & (1 << 22)) > 0 {
		return 0, fmt.Errorf("[ID.GetId]max id used up")
	}
	return newid, nil
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值