github.com/yitter/idgenerator-go@v1.3.3/idgen/SnowWorkerM1.go (about) 1 /* 2 * 版权属于:yitter(yitter@126.com) 3 * 代码编辑:guoyahao 4 * 代码修订:yitter 5 * 开源地址:https://github.com/yitter/idgenerator 6 */ 7 8 package idgen 9 10 import ( 11 "sync" 12 "time" 13 ) 14 15 // SnowWorkerM1 . 16 type SnowWorkerM1 struct { 17 BaseTime int64 // 基础时间 18 WorkerId uint16 // 机器码 19 WorkerIdBitLength byte // 机器码位长 20 SeqBitLength byte // 自增序列数位长 21 MaxSeqNumber uint32 // 最大序列数(含) 22 MinSeqNumber uint32 // 最小序列数(含) 23 TopOverCostCount uint32 // 最大漂移次数 24 _TimestampShift byte 25 _CurrentSeqNumber uint32 26 27 _LastTimeTick int64 28 _TurnBackTimeTick int64 29 _TurnBackIndex byte 30 _IsOverCost bool 31 _OverCostCountInOneTerm uint32 32 // _GenCountInOneTerm uint32 33 // _TermIndex uint32 34 35 sync.Mutex 36 } 37 38 // NewSnowWorkerM1 . 39 func NewSnowWorkerM1(options *IdGeneratorOptions) ISnowWorker { 40 var workerIdBitLength byte 41 var seqBitLength byte 42 var maxSeqNumber uint32 43 44 // 1.BaseTime 45 var baseTime int64 46 if options.BaseTime != 0 { 47 baseTime = options.BaseTime 48 } else { 49 baseTime = 1582136402000 50 } 51 52 // 2.WorkerIdBitLength 53 if options.WorkerIdBitLength == 0 { 54 workerIdBitLength = 6 55 } else { 56 workerIdBitLength = options.WorkerIdBitLength 57 } 58 59 // 3.WorkerId 60 var workerId = options.WorkerId 61 62 // 4.SeqBitLength 63 if options.SeqBitLength == 0 { 64 seqBitLength = 6 65 } else { 66 seqBitLength = options.SeqBitLength 67 } 68 69 // 5.MaxSeqNumber 70 if options.MaxSeqNumber <= 0 { 71 maxSeqNumber = (1 << seqBitLength) - 1 72 } else { 73 maxSeqNumber = options.MaxSeqNumber 74 } 75 76 // 6.MinSeqNumber 77 var minSeqNumber = options.MinSeqNumber 78 79 // 7.Others 80 var topOverCostCount = options.TopOverCostCount 81 if topOverCostCount == 0 { 82 topOverCostCount = 2000 83 } 84 85 timestampShift := (byte)(workerIdBitLength + seqBitLength) 86 currentSeqNumber := minSeqNumber 87 88 return &SnowWorkerM1{ 89 BaseTime: baseTime, 90 WorkerIdBitLength: workerIdBitLength, 91 WorkerId: workerId, 92 SeqBitLength: seqBitLength, 93 MaxSeqNumber: maxSeqNumber, 94 MinSeqNumber: minSeqNumber, 95 TopOverCostCount: topOverCostCount, 96 _TimestampShift: timestampShift, 97 _CurrentSeqNumber: currentSeqNumber, 98 99 _LastTimeTick: 0, 100 _TurnBackTimeTick: 0, 101 _TurnBackIndex: 0, 102 _IsOverCost: false, 103 _OverCostCountInOneTerm: 0, 104 // _GenCountInOneTerm: 0, 105 // _TermIndex: 0, 106 } 107 } 108 109 // DoGenIDAction . 110 func (m1 *SnowWorkerM1) DoGenIdAction(arg *OverCostActionArg) { 111 112 } 113 114 func (m1 *SnowWorkerM1) BeginOverCostAction(useTimeTick int64) { 115 116 } 117 118 func (m1 *SnowWorkerM1) EndOverCostAction(useTimeTick int64) { 119 // if m1._TermIndex > 10000 { 120 // m1._TermIndex = 0 121 // } 122 } 123 124 func (m1 *SnowWorkerM1) BeginTurnBackAction(useTimeTick int64) { 125 126 } 127 128 func (m1 *SnowWorkerM1) EndTurnBackAction(useTimeTick int64) { 129 130 } 131 132 func (m1 *SnowWorkerM1) NextOverCostId() int64 { 133 currentTimeTick := m1.GetCurrentTimeTick() 134 if currentTimeTick > m1._LastTimeTick { 135 // m1.EndOverCostAction(currentTimeTick) 136 m1._LastTimeTick = currentTimeTick 137 m1._CurrentSeqNumber = m1.MinSeqNumber 138 m1._IsOverCost = false 139 m1._OverCostCountInOneTerm = 0 140 // m1._GenCountInOneTerm = 0 141 return m1.CalcId(m1._LastTimeTick) 142 } 143 if m1._OverCostCountInOneTerm >= m1.TopOverCostCount { 144 // m1.EndOverCostAction(currentTimeTick) 145 m1._LastTimeTick = m1.GetNextTimeTick() 146 m1._CurrentSeqNumber = m1.MinSeqNumber 147 m1._IsOverCost = false 148 m1._OverCostCountInOneTerm = 0 149 // m1._GenCountInOneTerm = 0 150 return m1.CalcId(m1._LastTimeTick) 151 } 152 if m1._CurrentSeqNumber > m1.MaxSeqNumber { 153 m1._LastTimeTick++ 154 m1._CurrentSeqNumber = m1.MinSeqNumber 155 m1._IsOverCost = true 156 m1._OverCostCountInOneTerm++ 157 // m1._GenCountInOneTerm++ 158 159 return m1.CalcId(m1._LastTimeTick) 160 } 161 162 // m1._GenCountInOneTerm++ 163 return m1.CalcId(m1._LastTimeTick) 164 } 165 166 // NextNormalID . 167 func (m1 *SnowWorkerM1) NextNormalId() int64 { 168 currentTimeTick := m1.GetCurrentTimeTick() 169 if currentTimeTick < m1._LastTimeTick { 170 if m1._TurnBackTimeTick < 1 { 171 m1._TurnBackTimeTick = m1._LastTimeTick - 1 172 m1._TurnBackIndex++ 173 // 每毫秒序列数的前5位是预留位,0用于手工新值,1-4是时间回拨次序 174 // 支持4次回拨次序(避免回拨重叠导致ID重复),可无限次回拨(次序循环使用)。 175 if m1._TurnBackIndex > 4 { 176 m1._TurnBackIndex = 1 177 } 178 m1.BeginTurnBackAction(m1._TurnBackTimeTick) 179 } 180 181 // time.Sleep(time.Duration(1) * time.Millisecond) 182 return m1.CalcTurnBackId(m1._TurnBackTimeTick) 183 } 184 185 // 时间追平时,_TurnBackTimeTick清零 186 if m1._TurnBackTimeTick > 0 { 187 m1.EndTurnBackAction(m1._TurnBackTimeTick) 188 m1._TurnBackTimeTick = 0 189 } 190 191 if currentTimeTick > m1._LastTimeTick { 192 m1._LastTimeTick = currentTimeTick 193 m1._CurrentSeqNumber = m1.MinSeqNumber 194 return m1.CalcId(m1._LastTimeTick) 195 } 196 197 if m1._CurrentSeqNumber > m1.MaxSeqNumber { 198 m1.BeginOverCostAction(currentTimeTick) 199 // m1._TermIndex++ 200 m1._LastTimeTick++ 201 m1._CurrentSeqNumber = m1.MinSeqNumber 202 m1._IsOverCost = true 203 m1._OverCostCountInOneTerm = 1 204 // m1._GenCountInOneTerm = 1 205 206 return m1.CalcId(m1._LastTimeTick) 207 } 208 209 return m1.CalcId(m1._LastTimeTick) 210 } 211 212 // CalcID . 213 func (m1 *SnowWorkerM1) CalcId(useTimeTick int64) int64 { 214 result := int64(useTimeTick<<m1._TimestampShift) + int64(m1.WorkerId<<m1.SeqBitLength) + int64(m1._CurrentSeqNumber) 215 m1._CurrentSeqNumber++ 216 return result 217 } 218 219 // CalcTurnBackID . 220 func (m1 *SnowWorkerM1) CalcTurnBackId(useTimeTick int64) int64 { 221 result := int64(useTimeTick<<m1._TimestampShift) + int64(m1.WorkerId<<m1.SeqBitLength) + int64(m1._TurnBackIndex) 222 m1._TurnBackTimeTick-- 223 return result 224 } 225 226 // GetCurrentTimeTick . 227 func (m1 *SnowWorkerM1) GetCurrentTimeTick() int64 { 228 var millis = time.Now().UnixNano() / 1e6 229 return millis - m1.BaseTime 230 } 231 232 // GetNextTimeTick . 233 func (m1 *SnowWorkerM1) GetNextTimeTick() int64 { 234 tempTimeTicker := m1.GetCurrentTimeTick() 235 for tempTimeTicker <= m1._LastTimeTick { 236 time.Sleep(time.Duration(1) * time.Millisecond) 237 tempTimeTicker = m1.GetCurrentTimeTick() 238 } 239 return tempTimeTicker 240 } 241 242 // NextId . 243 func (m1 *SnowWorkerM1) NextId() int64 { 244 m1.Lock() 245 defer m1.Unlock() 246 if m1._IsOverCost { 247 return m1.NextOverCostId() 248 } else { 249 return m1.NextNormalId() 250 } 251 }