From a361e29a68bbad78318715e6aee696f0006f4b34 Mon Sep 17 00:00:00 2001
From: awwit <ignatius.awwit@gmail.com>
Date: Fri, 22 May 2020 00:33:21 +0300
Subject: [PATCH 1/3] feat: slightly improved v1 perf

---
 examples/benchmark/benchmark.js |  8 ++++++-
 src/bytesToUuid.js              | 42 +++++++++++++++------------------
 src/v1.js                       |  8 +++++--
 3 files changed, 32 insertions(+), 26 deletions(-)

diff --git a/examples/benchmark/benchmark.js b/examples/benchmark/benchmark.js
index b62b16ae..0c713c75 100644
--- a/examples/benchmark/benchmark.js
+++ b/examples/benchmark/benchmark.js
@@ -21,7 +21,13 @@ suite
     uuidv1();
   })
   .add('uuidv1() fill existing array', function () {
-    uuidv1(null, array, 0);
+    try {
+      uuidv1(null, array, 0);
+    } catch (err) {
+      if (err.code !== 'UUID_V1_LIMIT_PER_SEC') {
+        throw err;
+      }
+    }
   })
   .add('uuidv4()', function () {
     uuidv4();
diff --git a/src/bytesToUuid.js b/src/bytesToUuid.js
index 7e90bdb9..dd95b87a 100644
--- a/src/bytesToUuid.js
+++ b/src/bytesToUuid.js
@@ -2,40 +2,36 @@
  * Convert array of 16 byte values to UUID string format of the form:
  * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
  */
-const byteToHex = [];
+const bth = [];
 
 for (let i = 0; i < 256; ++i) {
-  byteToHex.push((i + 0x100).toString(16).substr(1));
+  bth.push((i + 0x100).toString(16).substr(1));
 }
 
-function bytesToUuid(buf, offset) {
-  const i = offset || 0;
-
-  const bth = byteToHex;
-
+function bytesToUuid(buf, offset = 0) {
   // Note: Be careful editing this code!  It's been tuned for performance
   // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
   return (
-    bth[buf[i + 0]] +
-    bth[buf[i + 1]] +
-    bth[buf[i + 2]] +
-    bth[buf[i + 3]] +
+    bth[buf[offset + 0]] +
+    bth[buf[offset + 1]] +
+    bth[buf[offset + 2]] +
+    bth[buf[offset + 3]] +
     '-' +
-    bth[buf[i + 4]] +
-    bth[buf[i + 5]] +
+    bth[buf[offset + 4]] +
+    bth[buf[offset + 5]] +
     '-' +
-    bth[buf[i + 6]] +
-    bth[buf[i + 7]] +
+    bth[buf[offset + 6]] +
+    bth[buf[offset + 7]] +
     '-' +
-    bth[buf[i + 8]] +
-    bth[buf[i + 9]] +
+    bth[buf[offset + 8]] +
+    bth[buf[offset + 9]] +
     '-' +
-    bth[buf[i + 10]] +
-    bth[buf[i + 11]] +
-    bth[buf[i + 12]] +
-    bth[buf[i + 13]] +
-    bth[buf[i + 14]] +
-    bth[buf[i + 15]]
+    bth[buf[offset + 10]] +
+    bth[buf[offset + 11]] +
+    bth[buf[offset + 12]] +
+    bth[buf[offset + 13]] +
+    bth[buf[offset + 14]] +
+    bth[buf[offset + 15]]
   ).toLowerCase();
 }
 
diff --git a/src/v1.js b/src/v1.js
index 52a49f54..0c485810 100644
--- a/src/v1.js
+++ b/src/v1.js
@@ -16,7 +16,7 @@ let _lastNSecs = 0;
 // See https://github.com/uuidjs/uuid for API details
 function v1(options, buf, offset) {
   let i = (buf && offset) || 0;
-  const b = buf || [];
+  const b = buf || new Array(16);
 
   options = options || {};
   let node = options.node || _nodeId;
@@ -27,6 +27,7 @@ function v1(options, buf, offset) {
   // system entropy.  See #189
   if (node == null || clockseq == null) {
     const seedBytes = options.random || (options.rng || rng)();
+
     if (node == null) {
       // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
       node = _nodeId = [
@@ -38,6 +39,7 @@ function v1(options, buf, offset) {
         seedBytes[5],
       ];
     }
+
     if (clockseq == null) {
       // Per 4.2.2, randomize (14 bit) clockseq
       clockseq = _clockseq = ((seedBytes[6] << 8) | seedBytes[7]) & 0x3fff;
@@ -70,7 +72,9 @@ function v1(options, buf, offset) {
 
   // Per 4.2.1.2 Throw error if too many uuids are requested
   if (nsecs >= 10000) {
-    throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");
+    const error = new Error("uuid.v1(): Can't create more than 10M uuids/sec");
+    error.code = 'UUID_V1_LIMIT_PER_SEC';
+    throw error;
   }
 
   _lastMSecs = msecs;

From 056d3e32f78dddceadc810ec73315c5b85253d88 Mon Sep 17 00:00:00 2001
From: awwit <ignatius.awwit@gmail.com>
Date: Mon, 25 May 2020 15:25:45 +0300
Subject: [PATCH 2/3] revert: throw original Error

---
 .eslintrc.json                  |  8 +++++++-
 examples/benchmark/benchmark.js |  6 +-----
 src/bytesToUuid.js              | 36 ++++++++++++++++-----------------
 src/v1.js                       |  4 +---
 4 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/.eslintrc.json b/.eslintrc.json
index cd838aeb..4b2152a0 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -13,6 +13,12 @@
   },
   "parser": "babel-eslint",
   "rules": {
-    "no-var": ["error"]
+    "no-var": ["error"],
+    "no-empty": [
+      "error",
+      {
+        "allowEmptyCatch": true
+      }
+    ]
   }
 }
diff --git a/examples/benchmark/benchmark.js b/examples/benchmark/benchmark.js
index 0c713c75..cf4de836 100644
--- a/examples/benchmark/benchmark.js
+++ b/examples/benchmark/benchmark.js
@@ -23,11 +23,7 @@ suite
   .add('uuidv1() fill existing array', function () {
     try {
       uuidv1(null, array, 0);
-    } catch (err) {
-      if (err.code !== 'UUID_V1_LIMIT_PER_SEC') {
-        throw err;
-      }
-    }
+    } catch (err) {}
   })
   .add('uuidv4()', function () {
     uuidv4();
diff --git a/src/bytesToUuid.js b/src/bytesToUuid.js
index dd95b87a..0c27824b 100644
--- a/src/bytesToUuid.js
+++ b/src/bytesToUuid.js
@@ -2,36 +2,36 @@
  * Convert array of 16 byte values to UUID string format of the form:
  * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
  */
-const bth = [];
+const byteToHex = [];
 
 for (let i = 0; i < 256; ++i) {
-  bth.push((i + 0x100).toString(16).substr(1));
+  byteToHex.push((i + 0x100).toString(16).substr(1));
 }
 
 function bytesToUuid(buf, offset = 0) {
   // Note: Be careful editing this code!  It's been tuned for performance
   // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
   return (
-    bth[buf[offset + 0]] +
-    bth[buf[offset + 1]] +
-    bth[buf[offset + 2]] +
-    bth[buf[offset + 3]] +
+    byteToHex[buf[offset + 0]] +
+    byteToHex[buf[offset + 1]] +
+    byteToHex[buf[offset + 2]] +
+    byteToHex[buf[offset + 3]] +
     '-' +
-    bth[buf[offset + 4]] +
-    bth[buf[offset + 5]] +
+    byteToHex[buf[offset + 4]] +
+    byteToHex[buf[offset + 5]] +
     '-' +
-    bth[buf[offset + 6]] +
-    bth[buf[offset + 7]] +
+    byteToHex[buf[offset + 6]] +
+    byteToHex[buf[offset + 7]] +
     '-' +
-    bth[buf[offset + 8]] +
-    bth[buf[offset + 9]] +
+    byteToHex[buf[offset + 8]] +
+    byteToHex[buf[offset + 9]] +
     '-' +
-    bth[buf[offset + 10]] +
-    bth[buf[offset + 11]] +
-    bth[buf[offset + 12]] +
-    bth[buf[offset + 13]] +
-    bth[buf[offset + 14]] +
-    bth[buf[offset + 15]]
+    byteToHex[buf[offset + 10]] +
+    byteToHex[buf[offset + 11]] +
+    byteToHex[buf[offset + 12]] +
+    byteToHex[buf[offset + 13]] +
+    byteToHex[buf[offset + 14]] +
+    byteToHex[buf[offset + 15]]
   ).toLowerCase();
 }
 
diff --git a/src/v1.js b/src/v1.js
index 0c485810..dbf4f5ca 100644
--- a/src/v1.js
+++ b/src/v1.js
@@ -72,9 +72,7 @@ function v1(options, buf, offset) {
 
   // Per 4.2.1.2 Throw error if too many uuids are requested
   if (nsecs >= 10000) {
-    const error = new Error("uuid.v1(): Can't create more than 10M uuids/sec");
-    error.code = 'UUID_V1_LIMIT_PER_SEC';
-    throw error;
+    throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");
   }
 
   _lastMSecs = msecs;

From 1b158ff41d055913d4c3548eefb10ca4d72a99ba Mon Sep 17 00:00:00 2001
From: awwit <ignatius.awwit@gmail.com>
Date: Mon, 25 May 2020 18:41:47 +0300
Subject: [PATCH 3/3] test: added comment for v1 in benchmark

---
 .eslintrc.json                  | 8 +-------
 examples/benchmark/benchmark.js | 6 +++++-
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/.eslintrc.json b/.eslintrc.json
index 4b2152a0..cd838aeb 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -13,12 +13,6 @@
   },
   "parser": "babel-eslint",
   "rules": {
-    "no-var": ["error"],
-    "no-empty": [
-      "error",
-      {
-        "allowEmptyCatch": true
-      }
-    ]
+    "no-var": ["error"]
   }
 }
diff --git a/examples/benchmark/benchmark.js b/examples/benchmark/benchmark.js
index cf4de836..dc3ff19f 100644
--- a/examples/benchmark/benchmark.js
+++ b/examples/benchmark/benchmark.js
@@ -23,7 +23,11 @@ suite
   .add('uuidv1() fill existing array', function () {
     try {
       uuidv1(null, array, 0);
-    } catch (err) {}
+    } catch (err) {
+      // The spec (https://tools.ietf.org/html/rfc4122#section-4.2.1.2) defines that only 10M/s v1
+      // UUIDs can be generated on a single node. This library throws an error if we hit that limit
+      // (which can happen on modern hardware and modern Node.js versions).
+    }
   })
   .add('uuidv4()', function () {
     uuidv4();