github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/data/id/snowid/snowid_1.go (about)

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