id快速生产算法 雪花id

/**

  • @description:

  • @author: bubao
    /
    class Genid {
    /
    *
    *Creates an instance of Genid.

    • @author bubao

    • @param {{

    • Method: 1, // 雪花计算方法,(1-漂移算法|2-传统算法),默认 1
      
    • BaseTime: 1577836800000,  // 基础时间(ms 单位),不能超过当前系统时间
      
    • WorkerId: Number, // 机器码,必须由外部设定,最大值 2^WorkerIdBitLength-1
      
    • WorkerIdBitLength: 6,   // 机器码位长,默认值 6,取值范围 [1, 15](要求:序列数位长+机器码位长不超过 22)
      
    • SeqBitLength: 6,   // 序列数位长,默认值 6,取值范围 [3, 21](要求:序列数位长+机器码位长不超过 22)
      
    • MaxSeqNumber: 5, // 最大序列数(含),设置范围 [MinSeqNumber, 2^SeqBitLength-1],默认值 0,表示最大序列数取最大值(2^SeqBitLength-1])
      
    • MinSeqNumber: 5, // 最小序列数(含),默认值 5,取值范围 [5, MaxSeqNumber],每毫秒的前 5 个序列数对应编号 0-4 是保留位,其中 1-4 是时间回拨相应预留位,0 是手工新值预留位
      
    • TopOverCostCount: 2000// 最大漂移次数(含),默认 2000,推荐范围 500-10000(与计算能力有关)
      
    • }} options

    • @memberof Genid
      */
      constructor(options) {
      if (options.WorkerId === undefined) {
      throw new Error(“lost WorkerId”);
      }
      // 1.BaseTime
      const BaseTime = 1577836800000;
      if (!options.BaseTime || options.BaseTime < 0) {
      options.BaseTime = BaseTime;
      }
      // 2.WorkerIdBitLength
      const WorkerIdBitLength = 6;
      if (!options.WorkerIdBitLength || options.WorkerIdBitLength < 0) {
      options.WorkerIdBitLength = WorkerIdBitLength;
      }

      // 4.SeqBitLength
      const SeqBitLength = 6;
      if (!options.SeqBitLength || options.SeqBitLength < 0) {
      options.SeqBitLength = SeqBitLength;
      }
      // 5.MaxSeqNumber
      const MaxSeqNumber = (1 << options.SeqBitLength) - 1;
      if (options.MaxSeqNumber <= 0 || options.MaxSeqNumber === undefined) {
      options.MaxSeqNumber = MaxSeqNumber;
      }
      // 6.MinSeqNumber
      const MinSeqNumber = 5;
      if (!options.MinSeqNumber || options.MinSeqNumber < 0) {
      options.MinSeqNumber = MinSeqNumber;
      }
      // 7.Others
      const topOverCostCount = 2000;
      if (!options.TopOverCostCount || options.TopOverCostCount < 0) {
      options.TopOverCostCount = topOverCostCount;
      }

      if (options.Method !== 2) {
      options.Method = 1;
      } else {
      options.Method = 2;
      }

      this.Method = BigInt(options.Method);
      this.BaseTime = BigInt(options.BaseTime);
      this.WorkerId = BigInt(options.WorkerId);
      this.WorkerIdBitLength = BigInt(options.WorkerIdBitLength);
      this.SeqBitLength = BigInt(options.SeqBitLength);
      this.MaxSeqNumber = BigInt(options.MaxSeqNumber);
      this.MinSeqNumber = BigInt(options.MinSeqNumber);
      this.TopOverCostCount = BigInt(options.TopOverCostCount);

      const timestampShift = this.WorkerIdBitLength + this.SeqBitLength;
      const currentSeqNumber = this.MinSeqNumber;

      this._TimestampShift = timestampShift;
      this._CurrentSeqNumber = currentSeqNumber;

      this._LastTimeTick = 0;
      this._TurnBackTimeTick = 0;
      this._TurnBackIndex = 0;
      this._IsOverCost = false;
      this._OverCostCountInOneTerm = 0;
      }

    // DoGenIDAction .
    DoGenIdAction(OverCostActionArg) { }

    BeginOverCostAction(useTimeTick) { }

    EndOverCostAction(useTimeTick) {
    // if m1._TermIndex > 10000 {
    // m1._TermIndex = 0
    // }
    }

    BeginTurnBackAction(useTimeTick) { }

    EndTurnBackAction(useTimeTick) { }

    NextOverCostId() {
    const currentTimeTick = this.GetCurrentTimeTick();
    if (currentTimeTick > this._LastTimeTick) {
    // this.EndOverCostAction(currentTimeTick)
    this._LastTimeTick = currentTimeTick;
    this._CurrentSeqNumber = this.MinSeqNumber;
    this._IsOverCost = false;
    this._OverCostCountInOneTerm = 0;
    // this._GenCountInOneTerm = 0
    return this.CalcId(this._LastTimeTick);
    }
    if (this._OverCostCountInOneTerm >= this.TopOverCostCount) {
    // this.EndOverCostAction(currentTimeTick)
    this._LastTimeTick = this.GetNextTimeTick();
    this._CurrentSeqNumber = this.MinSeqNumber;
    this._IsOverCost = false;
    this._OverCostCountInOneTerm = 0;
    // this._GenCountInOneTerm = 0
    return this.CalcId(this._LastTimeTick);
    }
    if (this._CurrentSeqNumber > this.MaxSeqNumber) {
    this._LastTimeTick++;
    this._CurrentSeqNumber = this.MinSeqNumber;
    this._IsOverCost = true;
    this._OverCostCountInOneTerm++;
    // this._GenCountInOneTerm++

         return this.CalcId(this._LastTimeTick);
     }
    
     // this._GenCountInOneTerm++
     return this.CalcId(this._LastTimeTick);
    

    }

    NextNormalId() {
    const currentTimeTick = this.GetCurrentTimeTick();
    if (currentTimeTick < this._LastTimeTick) {
    if (this._TurnBackTimeTick < 1) {
    this._TurnBackTimeTick = this._LastTimeTick - 1;
    this._TurnBackIndex++;
    // 每毫秒序列数的前 5 位是预留位,0 用于手工新值,1-4 是时间回拨次序
    // 支持 4 次回拨次序(避免回拨重叠导致 ID 重复),可无限次回拨(次序循环使用)。
    if (this._TurnBackIndex > 4) {
    this._TurnBackIndex = 1;
    }
    this.BeginTurnBackAction(this._TurnBackTimeTick);
    }

         return this.CalcTurnBackId(this._TurnBackTimeTick);
     }
     
     // 时间追平时,_TurnBackTimeTick 清零
     if (this._TurnBackTimeTick > 0) {
         this.EndTurnBackAction(this._TurnBackTimeTick);
         this._TurnBackTimeTick = 0;
     }
    
     if (currentTimeTick > this._LastTimeTick) {
         this._LastTimeTick = currentTimeTick;
         this._CurrentSeqNumber = this.MinSeqNumber;
         return this.CalcId(this._LastTimeTick);
     }
    
     if (this._CurrentSeqNumber > this.MaxSeqNumber) {
         this.BeginOverCostAction(currentTimeTick);
         // this._TermIndex++
         this._LastTimeTick++;
         this._CurrentSeqNumber = this.MinSeqNumber;
         this._IsOverCost = true;
         this._OverCostCountInOneTerm = 1;
         // this._GenCountInOneTerm = 1
    
         return this.CalcId(this._LastTimeTick);
     }
    
     return this.CalcId(this._LastTimeTick);
    

    }

    CalcId(useTimeTick) {
    const result = BigInt(useTimeTick << this._TimestampShift) + BigInt(this.WorkerId << this.SeqBitLength) + BigInt(this._CurrentSeqNumber);
    this._CurrentSeqNumber++;
    return result;
    }

    CalcTurnBackId(useTimeTick) {
    const result = BigInt(useTimeTick << this._TimestampShift) + BigInt(this.WorkerId << this.SeqBitLength) + BigInt(this._TurnBackIndex);
    this._TurnBackTimeTick–;
    return result;
    }

    GetCurrentTimeTick() {
    const millis = BigInt((new Date()).valueOf());
    return millis - this.BaseTime;
    }

    GetNextTimeTick() {
    let tempTimeTicker = this.GetCurrentTimeTick();
    while (tempTimeTicker <= this._LastTimeTick) {
    tempTimeTicker = this.GetCurrentTimeTick();
    }
    return tempTimeTicker;
    }

    /**

    • 生成ID

    • @returns 始终输出number类型,超过时throw error
      */
      NextNumber() {
      if (this._IsOverCost) {
      //
      let id = this.NextOverCostId()
      if (id >= 9007199254740992n)
      throw Error(${id.toString()} over max of Number 9007199254740992)

       return parseInt(id.toString())
      

      } else {
      //
      let id = this.NextNormalId()
      if (id >= 9007199254740992n)
      throw Error(${id.toString()} over max of Number 9007199254740992)

       return parseInt(id.toString())
      

      }
      }

    /**

    • 生成ID
    • @returns 根据输出数值判断,小于number最大值时输出number类型,大于时输出bigint
      */
      NextId() {
      if (this._IsOverCost) {
      let id = this.NextOverCostId()
      if (id >= 9007199254740992n)
      return id
      else
      return parseInt(id)
      } else {
      let id = this.NextNormalId()
      if (id >= 9007199254740992n)
      return id
      else
      return parseInt(id)
      }
      }

    /**

    • 生成ID
    • @returns 始终输出bigint类型
      */
      NextBigId() {
      if (this._IsOverCost) {
      //
      return this.NextOverCostId()
      } else {
      //
      return this.NextNormalId()
      }
      }
      }

module.exports = Genid;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小覃2222

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值