Skip to content

Commit 58de077

Browse files
committed
perf: improve TernarySearchTree
1 parent d4ce0b1 commit 58de077

File tree

3 files changed

+33
-2
lines changed

3 files changed

+33
-2
lines changed

benchmarks/TernarySearchTree.mjs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { bench, group, run } from 'mitata'
2+
import { tree } from '../lib/core/tree.js'
3+
4+
const contentLength = Buffer.from('Content-Length')
5+
const contentLengthUpperCase = Buffer.from('Content-Length'.toUpperCase())
6+
const contentLengthLowerCase = Buffer.from('Content-Length'.toLowerCase())
7+
8+
group('tree.search', () => {
9+
bench('content-length', () => {
10+
tree.lookup(contentLengthLowerCase)
11+
})
12+
bench('CONTENT-LENGTH', () => {
13+
tree.lookup(contentLengthUpperCase)
14+
})
15+
bench('Content-Length', () => {
16+
tree.lookup(contentLength)
17+
})
18+
})
19+
20+
await run()

lib/core/tree.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,10 @@ class TstNode {
8383
while (node !== null && index < keylength) {
8484
let code = key[index]
8585
// A-Z
86-
if (code >= 0x41 && code <= 0x5a) {
86+
// First check if it is bigger than 0x5a.
87+
// Lowercase letters have higher char codes than uppercase ones.
88+
// Also we assume that headers will mostly contain lowercase characters.
89+
if (code <= 0x5a && code >= 0x41) {
8790
// Lowercase for uppercase.
8891
code |= 32
8992
}
@@ -109,7 +112,7 @@ class TernarySearchTree {
109112

110113
/**
111114
* @param {Uint8Array} key
112-
* @param {any} value
115+
* @param {void}
113116
* */
114117
insert (key, value) {
115118
if (this.node === null) {
@@ -121,6 +124,7 @@ class TernarySearchTree {
121124

122125
/**
123126
* @param {Uint8Array} key
127+
* @return {TstNode | null}
124128
*/
125129
lookup (key) {
126130
return this.node?.search(key)?.value ?? null

test/node-test/tree.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ describe('Ternary Search Tree', () => {
1313
assert.throws(() => tst.insert(Buffer.from(''), ''))
1414
})
1515

16+
test('looking up not inserted key returns null', () => {
17+
assert.throws(() => new TernarySearchTree().insert(Buffer.from(''), ''))
18+
const tst = new TernarySearchTree()
19+
tst.insert(Buffer.from('a'), 'a')
20+
assert.strictEqual(tst.lookup(Buffer.from('non-existant')), null)
21+
})
22+
1623
test('duplicate key', () => {
1724
const tst = new TernarySearchTree()
1825
const key = Buffer.from('a')

0 commit comments

Comments
 (0)