Skip to content

Commit

Permalink
perf: improve TernarySearchTree (#2782)
Browse files Browse the repository at this point in the history
Co-authored-by: tsctx <91457664+tsctx@users.noreply.github.com>
  • Loading branch information
2 people authored and ronag committed Feb 22, 2024
1 parent 11b67df commit b798f30
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 1 deletion.
20 changes: 20 additions & 0 deletions benchmarks/TernarySearchTree.mjs
Original file line number Diff line number Diff line change
@@ -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()
6 changes: 5 additions & 1 deletion lib/core/tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -121,6 +124,7 @@ class TernarySearchTree {

/**
* @param {Uint8Array} key
* @return {any}
*/
lookup (key) {
return this.node?.search(key)?.value ?? null
Expand Down
7 changes: 7 additions & 0 deletions test/node-test/tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down

0 comments on commit b798f30

Please sign in to comment.