From 9797dc0eb4098c116e77560db515cbf2be833935 Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Thu, 9 Oct 2025 16:08:49 +0200 Subject: [PATCH] Improve performance of the struct tree build (bug 1987914) For the pdf in bug 1987914, the overall time spent in `addTopLevelNode` is dropping from ~6s to ~70ms. --- src/core/struct_tree.js | 52 ++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/src/core/struct_tree.js b/src/core/struct_tree.js index f8eafbc17..6ed379e3b 100644 --- a/src/core/struct_tree.js +++ b/src/core/struct_tree.js @@ -35,6 +35,31 @@ class StructTreeRoot { this.ref = rootRef instanceof Ref ? rootRef : null; this.roleMap = new Map(); this.structParentIds = null; + this.kidRefToPosition = undefined; + } + + getKidPosition(kidRef) { + if (this.kidRefToPosition === undefined) { + const obj = this.dict.get("K"); + if (Array.isArray(obj)) { + const map = (this.kidRefToPosition = new Map()); + for (let i = 0, ii = obj.length; i < ii; i++) { + const ref = obj[i]; + if (ref) { + map.set(ref.toString(), i); + } + } + } else if (obj instanceof Dict) { + this.kidRefToPosition = new Map([[obj.objId, 0]]); + } else if (!obj) { + this.kidRefToPosition = new Map(); + } else { + this.kidRefToPosition = null; + } + } + return this.kidRefToPosition + ? (this.kidRefToPosition.get(kidRef) ?? NaN) + : -1; } init() { @@ -785,31 +810,14 @@ class StructTreePage { } addTopLevelNode(dict, element) { - const obj = this.rootDict.get("K"); - if (!obj) { + const index = this.root.getKidPosition(dict.objId); + if (isNaN(index)) { return false; } - - if (obj instanceof Dict) { - if (obj.objId !== dict.objId) { - return false; - } - this.nodes[0] = element; - return true; + if (index !== -1) { + this.nodes[index] = element; } - - if (!Array.isArray(obj)) { - return true; - } - let save = false; - for (let i = 0; i < obj.length; i++) { - const kidRef = obj[i]; - if (kidRef?.toString() === dict.objId) { - this.nodes[i] = element; - save = true; - } - } - return save; + return true; } /**