core: optimize bson objectid generation & add benchmarks

This commit is contained in:
Abdullah Atta
2023-10-09 11:11:42 +05:00
parent 94f7e8cd08
commit 07d2a701c7
5 changed files with 75 additions and 32 deletions

View File

@@ -17,35 +17,16 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { BufferPool } from "./buffer-pool";
import { randomBytes, randomInt } from "./random";
const PROCESS_UNIQUE = randomBytes(5);
const PROCESS_UNIQUE = randomBytes(5).toString("hex");
let index = ~~(randomInt() * 0xffffff);
const objectIdPool = new BufferPool(12);
export function createObjectId(date = Date.now()): string {
const buffer = objectIdPool.alloc();
index = (index + 1) % 0xffffff;
const time = ~~(date / 1000);
// 4-byte timestamp
new DataView(buffer.buffer, 0, 4).setUint32(0, time);
// 5-byte process unique
buffer[4] = PROCESS_UNIQUE[0];
buffer[5] = PROCESS_UNIQUE[1];
buffer[6] = PROCESS_UNIQUE[2];
buffer[7] = PROCESS_UNIQUE[3];
buffer[8] = PROCESS_UNIQUE[4];
// 3-byte counter
buffer[11] = index & 0xff;
buffer[10] = (index >> 8) & 0xff;
buffer[9] = (index >> 16) & 0xff;
const objectId = buffer.toString("hex");
objectIdPool.free(buffer);
return objectId;
index++;
const time = Math.floor(date / 1000);
return time.toString(16) + PROCESS_UNIQUE + swap16(index).toString(16);
}
function swap16(val: number) {
return ((val & 0xff) << 16) | (val & 0xff00) | ((val >> 16) & 0xff);
}

View File

@@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
export function randomBytes(size: number) {
export function randomBytes(size: number): Buffer {
if (!globalThis.crypto || !crypto)
throw new Error("Crypto is not supported on this platform.");
if ("randomBytes" in crypto && typeof crypto.randomBytes === "function")
@@ -34,8 +34,5 @@ export function randomBytes(size: number) {
}
export function randomInt() {
const randomBuffer = randomBytes(1);
const randomNumber = randomBuffer[0] / 0xff; // / (0xffffffff + 1);
return Math.floor(randomNumber * 0xffffff);
return randomBytes(4).readInt32BE();
}