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..9b50767c6d3 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 } @@ -121,6 +124,7 @@ class TernarySearchTree { /** * @param {Uint8Array} key + * @return {any} */ 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')