mm_os
Version:
MM_OS服务端架构,用于快速构建应用程序,支持网站建设、小程序后台、AI应用、物联网(IOT/AIOT)、游戏服务端等多种场景。
135 lines (116 loc) • 3.5 kB
JavaScript
/**
* ID生成器
* 基于雪花算法实现,生成唯一ID
*/
class IdGen {
/**
* 构造函数
* @param {object} config 配置参数
* @param {number} config.worker_id 工作机器ID (0-31)
* @param {number} config.dc_id 数据中心ID (0-31)
* @param {number} config.sequence 序列号
*/
constructor(config = {}) {
this.worker_id = config.worker_id || 0;
this.dc_id = config.dc_id || 0;
this.sequence = config.sequence || 0;
this.worker_id_bits = 5;
this.dc_id_bits = 5;
this.max_worker_id = -1 ^ (-1 << this.worker_id_bits);
this.max_dc_id = -1 ^ (-1 << this.dc_id_bits);
this.sequence_bits = 12;
this.worker_id_shift = this.sequence_bits;
this.dc_id_shift = this.sequence_bits + this.worker_id_bits;
this.timestamp_left_shift = this.sequence_bits + this.worker_id_bits + this.dc_id_bits;
this.sequence_mask = -1 ^ (-1 << this.sequence_bits);
this.last_timestamp = -1;
this.twepoch = 1288834974657;
if (this.worker_id > this.max_worker_id || this.worker_id < 0) {
throw new TypeError(`工作机器ID必须在0-${this.max_worker_id}之间`);
}
if (this.dc_id > this.max_dc_id || this.dc_id < 0) {
throw new TypeError(`数据中心ID必须在0-${this.max_dc_id}之间`);
}
}
}
/**
* 获取当前时间戳
* @returns {number} 当前时间戳
*/
IdGen.prototype._timeGen = function () {
return Date.now();
};
/**
* 等待下一毫秒
* @param {number} last_timestamp 上次时间戳
* @returns {number} 新的时间戳
*/
IdGen.prototype._tilNextMillis = function (last_timestamp) {
var timestamp = this._timeGen();
while (timestamp <= last_timestamp) {
timestamp = this._timeGen();
}
return timestamp;
};
/**
* 生成下一个ID
* @returns {string} 唯一ID
*/
IdGen.prototype.nextId = function () {
var timestamp = this._timeGen();
if (timestamp < this.last_timestamp) {
throw new Error('时钟回拨,拒绝生成ID');
}
if (this.last_timestamp === timestamp) {
this.sequence = (this.sequence + 1) & this.sequence_mask;
if (this.sequence === 0) {
timestamp = this._tilNextMillis(this.last_timestamp);
}
} else {
this.sequence = 0;
}
this.last_timestamp = timestamp;
var id = (BigInt(timestamp - this.twepoch) << BigInt(this.timestamp_left_shift))
| (BigInt(this.dc_id) << BigInt(this.dc_id_shift))
| (BigInt(this.worker_id) << BigInt(this.worker_id_shift))
| BigInt(this.sequence);
return id.toString();
};
/**
* 生成带前缀的ID
* @param {string} prefix 前缀
* @returns {string} 带前缀的唯一ID
*/
IdGen.prototype.genId = function (prefix) {
if (typeof prefix !== 'string') {
throw new TypeError('前缀必须是字符串');
}
return prefix + '_' + this.nextId();
};
/**
* 解析ID信息
* @param {string} id ID字符串
* @returns {object} ID信息对象
*/
IdGen.prototype.parseId = function (id) {
if (typeof id !== 'string') {
throw new TypeError('ID必须是字符串');
}
var num = BigInt(id.replace(/^[a-zA-Z_]+_/, ''));
var timestamp = Number((num >> 22n) + BigInt(this.twepoch));
var dc_id = Number((num >> 17n) & 31n);
var worker_id = Number((num >> 12n) & 31n);
var sequence = Number(num & 4095n);
return {
timestamp: timestamp,
datetime: new Date(timestamp).toISOString(),
dc_id: dc_id,
worker_id: worker_id,
sequence: sequence
};
};
var idGen = new IdGen();
module.exports = {
IdGen,
idGen
};