UNPKG

badman-core

Version:

badman-core is the layer what all the badman packages depended,or can be used as a tool kit.

282 lines 12.2 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); class Snowflake { /** * @param {{ * baseTime: 1577836800000, // 基础时间(ms 单位),默认2020年1月1日,不能超过当前系统时间,一旦投入使用就不能再更改,更改后产生的ID可能会和以前的重复 * 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 */ constructor(options) { this.maxId = BigInt(9007199254740992); if (options.workerId === undefined) throw new Error("lost WorkerId"); this.snowflakeProperties = options; } afterInitialized() { return __awaiter(this, void 0, void 0, function* () { // 1.baseTime 2020年1月1日 Wed, 01 Jan 2020 00:00:00 GMT 0时区的2020年1月1日 const BaseTime = 1577836800000; if (!this.snowflakeProperties.baseTime || this.snowflakeProperties.baseTime < 0) this.snowflakeProperties.baseTime = BaseTime; // 2.WorkerIdBitLength const WorkerIdBitLength = 6; if (!this.snowflakeProperties.workerIdBitLength || this.snowflakeProperties.workerIdBitLength < 0) this.snowflakeProperties.workerIdBitLength = WorkerIdBitLength; // 4.SeqBitLength const seqBitLength = 6; if (!this.snowflakeProperties.seqBitLength || this.snowflakeProperties.seqBitLength < 0) this.snowflakeProperties.seqBitLength = seqBitLength; // 5.MaxSeqNumber if (this.snowflakeProperties.maxSeqNumber == undefined || this.snowflakeProperties.maxSeqNumber <= 0) this.snowflakeProperties.maxSeqNumber = (1 << this.snowflakeProperties.seqBitLength) - 1; // 6.MinSeqNumber const MinSeqNumber = 5; if (this.snowflakeProperties.minSeqNumber == undefined || this.snowflakeProperties.minSeqNumber < 0) this.snowflakeProperties.minSeqNumber = MinSeqNumber; // 7.Others const topOverCostCount = 2000; if (this.snowflakeProperties.topOverCostCount == undefined || this.snowflakeProperties.topOverCostCount < 0) this.snowflakeProperties.topOverCostCount = topOverCostCount; if (this.snowflakeProperties.method !== 2) this.snowflakeProperties.method = 1; else this.snowflakeProperties.method = 2; this.method = BigInt(this.snowflakeProperties.method); this.baseTime = BigInt(this.snowflakeProperties.baseTime); this.workerId = BigInt(this.snowflakeProperties.workerId); this.workerIdBitLength = BigInt(this.snowflakeProperties.workerIdBitLength); this.seqBitLength = BigInt(this.snowflakeProperties.seqBitLength); this.maxSeqNumber = BigInt(this.snowflakeProperties.maxSeqNumber); this.minSeqNumber = BigInt(this.snowflakeProperties.minSeqNumber); this.topOverCostCount = BigInt(this.snowflakeProperties.topOverCostCount); const timestampShift = this.workerIdBitLength + this.seqBitLength; const currentSeqNumber = this.minSeqNumber; this.timestampShift = timestampShift; this.currentSeqNumber = currentSeqNumber; this.lastTimeTick = BigInt(0); this.turnBackTimeTick = BigInt(0); this.turnBackIndex = 0; this.isOverCost = false; this.overCostCountInOneTerm = 0; }); } /** * 当前序列号超过最大范围,开始透支使用序号号的通知事件,,本项暂未实现 * @returns */ BeginOverCostAction(useTimeTick) { } /** * 当前序列号超过最大范围,结束透支使用序号号的通知事件,,本项暂未实现 * @returns */ EndOverCostAction(useTimeTick) { // if m1._TermIndex > 10000 { // m1._TermIndex = 0 // } } /** * 开始时间回拨通知,本项暂未实现 * @returns */ BeginTurnBackAction(useTimeTick) { } /** * 结束时间回拨通知,本项暂未实现 * @returns */ EndTurnBackAction(useTimeTick) { } /** * 雪花漂移算法 * @returns */ 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) { //当前漂移次数超过最大限制 // TODO: 在漂移终止,等待时间对齐时,如果发生时间回拨较长,则此处可能等待较长时间。可优化为:在漂移终止时增加时间回拨应对逻辑。(该情况发生概率很低) 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); } /** * 常规雪花算法 * @returns */ NextNormalId() { const currentTimeTick = this.GetCurrentTimeTick(); if (currentTimeTick < this.lastTimeTick) { if (this.turnBackTimeTick < 1) { this.turnBackTimeTick = this.lastTimeTick - BigInt(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 = BigInt(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); } /** * 生成ID * @param useTimeTick 时间戳 * @returns */ CalcId(useTimeTick) { //ID组成 1.相对基础时间的时间差 | 2.WorkerId | 3.序列数 //时间差,是生成ID时的系统时间减去 BaseTime 的总时间差(毫秒单位) const result = BigInt(useTimeTick << this.timestampShift) + BigInt(this.workerId << this.seqBitLength) + BigInt(this.currentSeqNumber); this.currentSeqNumber++; return result; } /** * 生成时间回拨ID * @returns */ CalcTurnBackId(useTimeTick) { const result = BigInt(useTimeTick << this.timestampShift) + BigInt(this.workerId << this.seqBitLength) + BigInt(this.turnBackIndex); this.turnBackTimeTick--; return result; } /** * * @returns */ GetCurrentTimeTick() { const millis = BigInt((new Date()).valueOf()); return millis - this.baseTime; } /** * * @returns */ 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 >= this.maxId) throw Error(`${id.toString()} over max of Number 9007199254740992`); return parseInt(id.toString()); } else { // let id = this.NextNormalId(); if (id >= this.maxId) 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 >= this.maxId) return id; else return parseInt(id.toString()); } else { // let id = this.NextNormalId(); if (id >= this.maxId) return id; else return parseInt(id.toString()); } } /** * 生成ID * @returns 始终输出bigint类型 */ NextBigId() { if (this.isOverCost) { // return this.NextOverCostId(); } else { // return this.NextNormalId(); } } } exports.default = Snowflake; //# sourceMappingURL=Snowflake.js.map