Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ same as MongoId.parse(id.toString()), see below

#### id.getTimestamp( )

same as MongoId.getTimestam(id.toString()), see below
same as MongoId.getTimestamp(id.toString()), see below

#### id.toString( )

Expand Down
16 changes: 10 additions & 6 deletions mongoid.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Ids are a hex number built out of the timestamp, a per-server unique id,
* the process id and a sequence number.
*
* Copyright (C) 2014 Andras Radics
* Copyright (C) 2014,2016 Andras Radics
* Licensed under the Apache License, Version 2.0
*
* MongoDB object ids are 12 bytes (24 hexadecimal chars), composed out of
Expand Down Expand Up @@ -64,8 +64,10 @@ var timestampCache = (function() {
if (!_timestamp || ++_ncalls > 1000) {
_ncalls = 0;
_timestamp = Date.now();
_timestampStr = hexFormat(Math.floor(_timestamp/1000), 8);
setTimeout(function(){ _timestamp = null; }, 10);
var msToNextTimestamp = 1000 - _timestamp % 1000;
setTimeout(function(){ _timestamp = null; }, Math.min(msToNextTimestamp - 1, 100));
_timestamp -= _timestamp % 1000;
_timestampStr = hexFormat(_timestamp/1000, 8);
}
return _timestampStr;
}
Expand All @@ -76,7 +78,9 @@ MongoId.prototype._getTimestampStr = timestampCache[1];

var _hexDigits = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'];
MongoId.prototype.fetch = function() {
this.sequenceId += 1;
if (this.sequenceId >= 0x1000000) {
// sequence wrapped, we can make an id only if the timestamp advanced
var _timestamp = this._getTimestamp();
if (_timestamp === this.sequenceStartTimestamp) {
// TODO: find a more elegant way to deal with overflow
Expand All @@ -86,8 +90,8 @@ MongoId.prototype.fetch = function() {
this.sequenceStartTimestamp = _timestamp;
}

if (++this.sequenceId % 16 === 0) {
this.sequencePrefix = hexFormat((this.sequenceId / 16 | 0).toString(16), 5);
if ((this.sequenceId & 0xF) === 0) {
this.sequencePrefix = hexFormat((this.sequenceId >>> 4).toString(16), 5);
}
return this._getTimestampStr() + this.processIdStr + this.sequencePrefix + _hexDigits[this.sequenceId % 16];
};
Expand Down Expand Up @@ -124,7 +128,7 @@ MongoId.prototype.parse = function( idstring ) {
MongoId.getTimestamp = function( idstring ) {
return parseInt(idstring.slice(0, 8), 16) * 1000;
};
MongoId.prototype.getTimestamp = function( idstring ) {
MongoId.prototype.getTimestamp = function( ) {
return MongoId.getTimestamp(this.toString());
};

22 changes: 21 additions & 1 deletion test/test-mongoid.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ module.exports.require = {
module.exports.mongoid_function = {
testShouldReturn24CharHexString: function(test) {
var id = mongoid();
test.ok(id.match(/[0-9a-fA-F]{24}/), "should return a 24-char id string");
test.ok(id.match(/^[0-9a-fA-F]{24}$/), "should return a 24-char id string");
test.done();
},

Expand All @@ -76,6 +76,26 @@ module.exports.mongoid_function = {
test.ok(t2-t1 < 100, "should generate > 100k ids / sec");
test.done();
},

'should throw Error if wrapped in same second': function(t) {
factory = new MongoId(0x111111);
factory.sequenceId = 0xffffff;
factory.sequencePrefix = "fffff";
// note: race condition: this test will fail if the seconds increase before the fetch
t.throws(function(){ factory.fetch() }, 'should throw');
t.done();
},

'should wrap at max id': function(t) {
factory = new MongoId(0x222222);
factory.sequenceId = 0xfffffe;
factory.sequencePrefix = "fffff";
factory.sequenceStartTimestamp -= 1000;
t.equal(factory.fetch().slice(-6), 'ffffff');
t.equal(factory.fetch().slice(-6), '000000');
t.equal(factory.fetch().slice(-6), '000001');
t.done();
},
};

module.exports.MongoId_class = {
Expand Down