Cache the children after a getBinaryNodeChild/ren call to avoid traversing arrays (#2093)
* generic-utils: cache the get * generic-utils: increased type safety * chore: lint
This commit is contained in:
@@ -4,12 +4,32 @@ import { type BinaryNode } from './types'
|
|||||||
|
|
||||||
// some extra useful utilities
|
// some extra useful utilities
|
||||||
|
|
||||||
|
const indexCache = new WeakMap<BinaryNode, Map<string, BinaryNode[]>>()
|
||||||
|
|
||||||
export const getBinaryNodeChildren = (node: BinaryNode | undefined, childTag: string) => {
|
export const getBinaryNodeChildren = (node: BinaryNode | undefined, childTag: string) => {
|
||||||
if (Array.isArray(node?.content)) {
|
if (!node || !Array.isArray(node.content)) return []
|
||||||
return node.content.filter(item => item.tag === childTag)
|
|
||||||
|
let index = indexCache.get(node)
|
||||||
|
|
||||||
|
// Build the index once per node
|
||||||
|
if (!index) {
|
||||||
|
index = new Map<string, BinaryNode[]>()
|
||||||
|
|
||||||
|
for (const child of node.content) {
|
||||||
|
let arr = index.get(child.tag)
|
||||||
|
if (!arr) index.set(child.tag, (arr = []))
|
||||||
|
arr.push(child)
|
||||||
|
}
|
||||||
|
|
||||||
|
indexCache.set(node, index)
|
||||||
}
|
}
|
||||||
|
|
||||||
return []
|
// Return first matching child
|
||||||
|
return index.get(childTag) || []
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getBinaryNodeChild = (node: BinaryNode | undefined, childTag: string) => {
|
||||||
|
return getBinaryNodeChildren(node, childTag)[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getAllBinaryNodeChildren = ({ content }: BinaryNode) => {
|
export const getAllBinaryNodeChildren = ({ content }: BinaryNode) => {
|
||||||
@@ -20,12 +40,6 @@ export const getAllBinaryNodeChildren = ({ content }: BinaryNode) => {
|
|||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getBinaryNodeChild = (node: BinaryNode | undefined, childTag: string) => {
|
|
||||||
if (Array.isArray(node?.content)) {
|
|
||||||
return node?.content.find(item => item.tag === childTag)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getBinaryNodeChildBuffer = (node: BinaryNode | undefined, childTag: string) => {
|
export const getBinaryNodeChildBuffer = (node: BinaryNode | undefined, childTag: string) => {
|
||||||
const child = getBinaryNodeChild(node, childTag)?.content
|
const child = getBinaryNodeChild(node, childTag)?.content
|
||||||
if (Buffer.isBuffer(child) || child instanceof Uint8Array) {
|
if (Buffer.isBuffer(child) || child instanceof Uint8Array) {
|
||||||
|
|||||||
Reference in New Issue
Block a user