node-idgen
Version:
generator 15 bit integers id for nodejs.
60 lines (52 loc) • 2 kB
JavaScript
/*****************************************************
* Author : Administrator
* Version : 1.0
* Date : 2015/2/2
****************************************************/
var util = require("util");
var TWEPOCH = 1400485784045;
var WORKERIDBITS = 6;
var MAXWORKERID = -1 ^ (-1 << WORKERIDBITS);
var SEQUENCEBITS = 6;
var WORKERIDSHIFT = SEQUENCEBITS;
var TIMESTAMPLEFTSHIFT = SEQUENCEBITS + WORKERIDBITS;
var SEQUENCEMASK = -1 ^ (-1 << SEQUENCEBITS);
function IdGenerator() {
var workerId = (process.pid % MAXWORKERID);
if (workerId > MAXWORKERID || workerId < 0) {
throw new Error(util.format("worker Id can't be greater than %d or less than 0", MAXWORKERID));
}
this.workerId = workerId;
this.lastTimestamp = -1;
this.sequence = 0;
}
IdGenerator.prototype.nextId = function () {
var timestamp = new Date().getTime();
if (this.lastTimestamp == timestamp) {
this.sequence = (this.sequence + 1) & SEQUENCEMASK;
if (this.sequence == 0) {
timestamp = tilNextMillis(this.lastTimestamp);
}
} else {
this.sequence = 0;
}
if (timestamp < this.lastTimestamp) {
throw new Error(util.format("Clock moved backwards. Refusing to generate id for %d milliseconds",
this.lastTimestamp - timestamp));
}
this.lastTimestamp = timestamp;
return leftShift((timestamp - TWEPOCH), TIMESTAMPLEFTSHIFT) + (this.workerId << WORKERIDSHIFT) + this.sequence;
};
// 将leftNum转二进制,加bits个0(相当左移运算),再转回10进制
// Will be converted to binary leftNum, followed by bits' 0 (equivalent to the left shift operation), and then back to 10 decimal
function leftShift(leftNum, bits) {
return parseInt(('' + parseInt(leftNum).toString(2) + (new Array(bits + 1).join('0'))), 2);
}
function tilNextMillis(lastTimestamp) {
var timestamp = new Date().getTime();
while (timestamp <= lastTimestamp) {
timestamp = new Date().getTime();
}
return timestamp;
}
module.exports = exports = IdGenerator;