From 58de0772998bfd510ed3054cd9f1e8d294592f2f Mon Sep 17 00:00:00 2001 From: uzlopak Date: Mon, 19 Feb 2024 16:51:29 +0100 Subject: [PATCH 1/3] perf: improve TernarySearchTree --- benchmarks/TernarySearchTree.mjs | 20 ++++++++++++++++++++ lib/core/tree.js | 8 ++++++-- test/node-test/tree.js | 7 +++++++ 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 benchmarks/TernarySearchTree.mjs diff --git a/benchmarks/TernarySearchTree.mjs b/benchmarks/TernarySearchTree.mjs new file mode 100644 index 00000000000..413288a6af3 --- /dev/null +++ b/benchmarks/TernarySearchTree.mjs @@ -0,0 +1,20 @@ +import { bench, group, run } from 'mitata' +import { tree } from '../lib/core/tree.js' + +const contentLength = Buffer.from('Content-Length') +const contentLengthUpperCase = Buffer.from('Content-Length'.toUpperCase()) +const contentLengthLowerCase = Buffer.from('Content-Length'.toLowerCase()) + +group('tree.search', () => { + bench('content-length', () => { + tree.lookup(contentLengthLowerCase) + }) + bench('CONTENT-LENGTH', () => { + tree.lookup(contentLengthUpperCase) + }) + bench('Content-Length', () => { + tree.lookup(contentLength) + }) +}) + +await run() diff --git a/lib/core/tree.js b/lib/core/tree.js index 366fc7d3207..889b935b608 100644 --- a/lib/core/tree.js +++ b/lib/core/tree.js @@ -83,7 +83,10 @@ class TstNode { while (node !== null && index < keylength) { let code = key[index] // A-Z - if (code >= 0x41 && code <= 0x5a) { + // First check if it is bigger than 0x5a. + // Lowercase letters have higher char codes than uppercase ones. + // Also we assume that headers will mostly contain lowercase characters. + if (code <= 0x5a && code >= 0x41) { // Lowercase for uppercase. code |= 32 } @@ -109,7 +112,7 @@ class TernarySearchTree { /** * @param {Uint8Array} key - * @param {any} value + * @param {void} * */ insert (key, value) { if (this.node === null) { @@ -121,6 +124,7 @@ class TernarySearchTree { /** * @param {Uint8Array} key + * @return {TstNode | null} */ lookup (key) { return this.node?.search(key)?.value ?? null diff --git a/test/node-test/tree.js b/test/node-test/tree.js index eee3fa85eac..44a7d7960ac 100644 --- a/test/node-test/tree.js +++ b/test/node-test/tree.js @@ -13,6 +13,13 @@ describe('Ternary Search Tree', () => { assert.throws(() => tst.insert(Buffer.from(''), '')) }) + test('looking up not inserted key returns null', () => { + assert.throws(() => new TernarySearchTree().insert(Buffer.from(''), '')) + const tst = new TernarySearchTree() + tst.insert(Buffer.from('a'), 'a') + assert.strictEqual(tst.lookup(Buffer.from('non-existant')), null) + }) + test('duplicate key', () => { const tst = new TernarySearchTree() const key = Buffer.from('a') From 0cd1a00f0151dfeb97004dc371fd32e347ecf451 Mon Sep 17 00:00:00 2001 From: Aras Abbasi Date: Mon, 19 Feb 2024 22:39:34 +0100 Subject: [PATCH 2/3] Apply suggestions from code review --- lib/core/tree.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/tree.js b/lib/core/tree.js index 889b935b608..5ed179f304b 100644 --- a/lib/core/tree.js +++ b/lib/core/tree.js @@ -112,7 +112,7 @@ class TernarySearchTree { /** * @param {Uint8Array} key - * @param {void} + * @param {any} value * */ insert (key, value) { if (this.node === null) { From 5ca863c1d27a5570ff47f0e47ab5ddab0c789514 Mon Sep 17 00:00:00 2001 From: Aras Abbasi Date: Tue, 20 Feb 2024 00:13:27 +0100 Subject: [PATCH 3/3] Apply suggestions from code review Co-authored-by: tsctx <91457664+tsctx@users.noreply.github.com> --- lib/core/tree.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/tree.js b/lib/core/tree.js index 5ed179f304b..9b50767c6d3 100644 --- a/lib/core/tree.js +++ b/lib/core/tree.js @@ -124,7 +124,7 @@ class TernarySearchTree { /** * @param {Uint8Array} key - * @return {TstNode | null} + * @return {any} */ lookup (key) { return this.node?.search(key)?.value ?? null