From 1491459deaa145ea875be6bdc9480921403de1c4 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Wed, 29 Dec 2021 15:57:34 +0100 Subject: [PATCH] Improve caching for the `Catalog.getPageIndex` method (PR 13319 follow-up) This method is now being used a lot more, compared to when it's added, since it's now used together with scripting as part of the `PDFDocument.fieldObjects` parsing (called during viewer initialization). For /Page Dictionaries that we've already parsed, the `pageIndex` corresponding to a particular Reference is already known and we're thus able to skip *all* parsing in the `Catalog.getPageIndex` method for those cases. --- src/core/catalog.js | 17 ++++++++++++++--- src/core/document.js | 7 ++++++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/core/catalog.js b/src/core/catalog.js index 54c6849ef..30ccddf16 100644 --- a/src/core/catalog.js +++ b/src/core/catalog.js @@ -1099,7 +1099,8 @@ class Catalog { visitedNodes.put(pagesRef); } const xref = this.xref, - pageKidsCountCache = this.pageKidsCountCache; + pageKidsCountCache = this.pageKidsCountCache, + pageIndexCache = this.pageIndexCache; let currentPageIndex = 0; while (nodesToVisit.length) { @@ -1128,9 +1129,13 @@ class Catalog { // Cache the Page reference, since it can *greatly* improve // performance by reducing redundant lookups in long documents // where all nodes are found at *one* level of the tree. - if (currentNode && !pageKidsCountCache.has(currentNode)) { + if (!pageKidsCountCache.has(currentNode)) { pageKidsCountCache.put(currentNode, 1); } + // Help improve performance of the `getPageIndex` method. + if (!pageIndexCache.has(currentNode)) { + pageIndexCache.put(currentNode, currentPageIndex); + } if (currentPageIndex === pageIndex) { return [obj, currentNode]; @@ -1215,10 +1220,16 @@ class Catalog { if (pagesRef instanceof Ref) { visitedNodes.put(pagesRef); } - const map = new Map(); + const map = new Map(), + pageIndexCache = this.pageIndexCache; let pageIndex = 0; function addPageDict(pageDict, pageRef) { + // Help improve performance of the `getPageIndex` method. + if (pageRef && !pageIndexCache.has(pageRef)) { + pageIndexCache.put(pageRef, pageIndex); + } + map.set(pageIndex++, [pageDict, pageRef]); } function addPageError(error) { diff --git a/src/core/document.js b/src/core/document.js index 5daeeb186..06b3f3895 100644 --- a/src/core/document.js +++ b/src/core/document.js @@ -1285,9 +1285,14 @@ class PDFDocument { type = await xref.fetchAsync(type); } if (isName(type, "Page") || (!obj.has("Type") && !obj.has("Kids"))) { - if (ref && !catalog.pageKidsCountCache.has(ref)) { + if (!catalog.pageKidsCountCache.has(ref)) { catalog.pageKidsCountCache.put(ref, 1); // Cache the Page reference. } + // Help improve performance of the `Catalog.getPageIndex` method. + if (!catalog.pageIndexCache.has(ref)) { + catalog.pageIndexCache.put(ref, 0); + } + return [obj, ref]; } }