Go实现雪花算法

Go实现雪花算法

一个简单的雪花算法的Go实现

需要的小伙伴直接拿去用就可以了。可以比较简单,一些数据你可以根据需要自定义就行了:

  • 机器ID位数:没必要必须10位
  • 开始时间戳:设置一个自己喜欢的,业务允许你只需要一天、一月的时间范围。42位也不是必须的。
  • 序列所占位数,每msid范围,根据需要调整吧。
    总得来说:除去第一个0是正负位不能变,其他63位,根据需要进行划分、组合,可以打进去很多信息,算法设计肯定很好,更多的希望你根据需要自我调整。

``

package main
import (
	"fmt"
	"sync"
	"errors"
	"time"

)
//	定义基本变量,雪花算法,时间戳,机器id,以及二者偏移量
const (
	twepoch 		= int64(1483228800000)		//开始时间戳(根据实际情况考虑)
	workidBits 		= uint(4) 					// 机器id所占用位数
	sequenceBits 	= uint(18)					// 序列所占位数

	workeridMax 	= int64(-1 ^ (-1 << workidBits))	//最大机器id
	sequenceMask	= int64(-1 ^ (-1 << sequenceBits))	//最大序列数
	workIdShift 	= sequenceBits 				//机器id左移位数
	timestampShift 	= sequenceBits + workidBits

)	

//雪花算法所需要的结构
type SnowFlake struct {
	sync.Mutex
	timestamp int64
	workerId int64
	sequence int64
}

func NewSnowflake(workerid int64)(*SnowFlake , error)  {
	fmt.Println("初始化")
	
	if workerid < 0 || workerid > workeridMax {
		return nil , errors.New("worker id must be between 0 and 1023")	
	}
	return &SnowFlake{
		timestamp : 0 , 
		workerId : workerid , 
		sequence : 0 , 
	}, nil
}

func (s *SnowFlake) Generate() int64  {
	s.Lock()
	now := time.Now().UnixNano()/1000000
	//fmt.Println(now << timestampShift)
	if s.timestamp == now {
		s.sequence = (s.sequence + 1 ) & sequenceMask
		if s.sequence == 0 {
			for  now <= s.timestamp {
				now = time.Now().UnixNano() / 1000000
			}
		}
	}else{
		s.sequence = 0 
	}
	s.timestamp = now 
	r := int64( (now - 0)<< timestampShift | (s.workerId << workIdShift) | (s.sequence) )
	s.Unlock()
	return r ;
}

func main()  {

	snow := SnowFlake{}
	//snow2 , _ := NewSnowflake(0)
	//fmt.Printf("%p\t%p\n" , &snow , &*snow2)
	count := 100 * 100 * 100 * 100 // * 100
	start :=  time.Now().UnixNano()/1000000
	for i := 0; i < count; i++ {
		id := snow.Generate()
		if id > 0  {
			continue
		}
		/*
		id2 := snow2.Generate()
		if id !=id2 {
		//	fmt.Println(id , id2 )
		}
		*/
	}
	end :=  time.Now().UnixNano()/1000000
	takes := (int) (end - start )
	fmt.Println("运行" ,  count   , "时间" , end - start)

	fmt.Println("运行速度" , (uint64)(count / takes) )
	
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值