From a18b581f004af934eb3862b13414dbfae51aefea Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Wed, 15 Jul 2026 13:19:37 +0200 Subject: [PATCH] Add a `getOrPutComputed` method in the `RefSetCache` class This is equivalent to the native `Map.prototype.getOrInsertComputed()` method, and it helps simplify/shorten some existing code. --- src/core/editor/pdf_editor.js | 7 +------ src/core/image_utils.js | 6 +----- src/core/primitives.js | 10 ++++++++++ src/core/struct_tree.js | 15 ++++----------- test/unit/primitives_spec.js | 6 ++++++ 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/core/editor/pdf_editor.js b/src/core/editor/pdf_editor.js index 181039bd5..24bac8aaa 100644 --- a/src/core/editor/pdf_editor.js +++ b/src/core/editor/pdf_editor.js @@ -455,12 +455,7 @@ class PDFEditor { // Re-entry means a (malformed) cycle back to this stream: allocate its // reference now to break the loop, like the generic path's eager alloc. if (resourceStreamPath.has(oldRef)) { - let ref = oldRefMapping.get(oldRef); - if (!ref) { - ref = this.newRef; - oldRefMapping.put(oldRef, ref); - } - return ref; + return oldRefMapping.getOrPutComputed(oldRef, () => this.newRef); } const key = oldRef.toString(); diff --git a/src/core/image_utils.js b/src/core/image_utils.js index a907d5ceb..42089251b 100644 --- a/src/core/image_utils.js +++ b/src/core/image_utils.js @@ -228,11 +228,7 @@ class GlobalImageCache { } shouldCache(ref, pageIndex) { - let pageIndexSet = this._refCache.get(ref); - if (!pageIndexSet) { - pageIndexSet = new Set(); - this._refCache.put(ref, pageIndexSet); - } + const pageIndexSet = this._refCache.getOrPutComputed(ref, () => new Set()); pageIndexSet.add(pageIndex); if (pageIndexSet.size < GlobalImageCache.NUM_PAGES_THRESHOLD) { diff --git a/src/core/primitives.js b/src/core/primitives.js index b0dff908d..277989c4a 100644 --- a/src/core/primitives.js +++ b/src/core/primitives.js @@ -398,6 +398,16 @@ class RefSetCache { this._map.set(ref.toString(), this.get(aliasRef)); } + getOrPutComputed(ref, callback) { + const map = this._map, + refStr = ref.toString(); + + if (!map.has(refStr)) { + map.set(refStr, callback(ref)); + } + return map.get(refStr); + } + [Symbol.iterator]() { return this._map.values(); } diff --git a/src/core/struct_tree.js b/src/core/struct_tree.js index 722927a8b..c85449a77 100644 --- a/src/core/struct_tree.js +++ b/src/core/struct_tree.js @@ -93,12 +93,7 @@ class StructTreeRoot { return; } this.structParentIds ||= new RefSetCache(); - let ids = this.structParentIds.get(pageRef); - if (!ids) { - ids = []; - this.structParentIds.put(pageRef, ids); - } - ids.push([id, type]); + this.structParentIds.getOrPutComputed(pageRef, makeArr).push([id, type]); } addAnnotationIdToPage(pageRef, id) { @@ -537,11 +532,9 @@ class StructTreeRoot { return; } - let cachedParentDict = cache.get(parentRef); - if (!cachedParentDict) { - cachedParentDict = parentDict.clone(); - cache.put(parentRef, cachedParentDict); - } + const cachedParentDict = cache.getOrPutComputed(parentRef, () => + parentDict.clone() + ); const parentKidsRaw = cachedParentDict.getRaw("K"); let cachedParentKids = parentKidsRaw instanceof Ref ? cache.get(parentKidsRaw) : null; diff --git a/test/unit/primitives_spec.js b/test/unit/primitives_spec.js index 1c89c8650..d6cf82f87 100644 --- a/test/unit/primitives_spec.js +++ b/test/unit/primitives_spec.js @@ -568,6 +568,12 @@ describe("primitives", function () { cache.put(ref2, obj2); expect([...cache.keys()]).toEqual([ref1, ref2]); }); + + it("should handle getOrPutComputed correctly", function () { + expect(cache.getOrPutComputed(ref1, () => obj1)).toEqual(obj1); + // Trying to set it again should be ignored. + expect(cache.getOrPutComputed(ref1, () => obj2)).toEqual(obj1); + }); }); describe("isName", function () {