Blame view

common/snow/snowflake.go 2.62 KB
436e0af4   zhangqijia   reactor: dir; Ac...
1
  package snow
ee23102d   zhangqijia   支持mongo, grpc接服务器
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  
  import (
  	"fmt"
  	"github.com/golang/glog"
  	"sync"
  	"time"
  )
  
  type Snowflake struct {
  	*sync.Mutex					// 锁
  	timestamp    int64	// 时间戳 ,毫秒
  	workerid     int64  // 工作节点
  	datacenterid int64	// 数据中心机房id
  	sequence     int64	// 序列号
  }
  const (
  	epoch             = int64(1577808000000)                           // 设置起始时间(时间戳/毫秒):2020-01-01 00:00:00,有效期69年
  	timestampBits     = uint(41)                                       // 时间戳占用位数
  	datacenteridBits  = uint(2)                                        // 数据中心id所占位数
  	workeridBits      = uint(7)                                        // 机器id所占位数
  	sequenceBits      = uint(12)                                       // 序列所占的位数
  	timestampMax      = int64(-1 ^ (-1 << timestampBits))              // 时间戳最大值
  	datacenteridMax   = int64(-1 ^ (-1 << datacenteridBits))           // 支持的最大数据中心id数量
  	workeridMax       = int64(-1 ^ (-1 << workeridBits))               // 支持的最大机器id数量
  	sequenceMask      = int64(-1 ^ (-1 << sequenceBits))               // 支持的最大序列id数量
  	workeridShift     = sequenceBits                                   // 机器id左移位数
  	datacenteridShift = sequenceBits + workeridBits                    // 数据中心id左移位数
  	timestampShift    = sequenceBits + workeridBits + datacenteridBits // 时间戳左移位数
  )
  
ee23102d   zhangqijia   支持mongo, grpc接服务器
32
33
34
35
36
37
38
39
40
41
42
43
44
45
  func NewSnowflake(workerid, datacenterid int64) *Snowflake {
  	return &Snowflake{
  		Mutex:        new(sync.Mutex),
  		timestamp:    time.Now().UnixNano() / 1000000,
  		workerid:     workerid,
  		datacenterid: datacenterid,
  		sequence:     0,
  	}
  }
  
  func (s *Snowflake) NextValStr() string {
  	return fmt.Sprintf("%d", s.NextVal())
  }
  
ee23102d   zhangqijia   支持mongo, grpc接服务器
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  func (s *Snowflake) NextVal() int64 {
  	s.Lock()
  	now := time.Now().UnixNano() / 1000000 // 转毫秒
  	if s.timestamp == now {
  		// 当同一时间戳(精度:毫秒)下多次生成id会增加序列号
  		s.sequence = (s.sequence + 1) & sequenceMask
  		if s.sequence == 0 {
  			// 如果当前序列超出12bit长度,则需要等待下一毫秒
  			// 下一毫秒将使用sequence:0
  			for now <= s.timestamp {
  				now = time.Now().UnixNano() / 1000000
  			}
  		}
  	} else {
  		// 不同时间戳(精度:毫秒)下直接使用序列号:0
  		s.sequence = 0
  	}
  	t := now - epoch
  	if t > timestampMax {
  		s.Unlock()
  		glog.Errorf("epoch must be between 0 and %d", timestampMax-1)
  		return 0
  	}
  	s.timestamp = now
  	r := int64((t)<<timestampShift | (s.datacenterid << datacenteridShift) | (s.workerid << workeridShift) | (s.sequence))
  	s.Unlock()
  	return r
  }