From ffa7ac7a9167caaf3b0573102ca6f10acdac7a18 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Fri, 12 Jun 2026 23:21:16 +0200 Subject: [PATCH] Use `Map.prototype.getOrInsertComputed()` more in the code-base --- src/core/chunked_stream.js | 14 +++++++------- src/core/editor/pdf_editor.js | 23 +++++++++-------------- src/core/primitives.js | 10 ++++------ src/display/annotation_storage.js | 7 ++++--- src/display/canvas.js | 19 +++++++++---------- src/display/editor/tools.js | 3 ++- web/debugger.mjs | 8 +++----- 7 files changed, 38 insertions(+), 46 deletions(-) diff --git a/src/core/chunked_stream.js b/src/core/chunked_stream.js index 86f7d7660..9b2f1d32c 100644 --- a/src/core/chunked_stream.js +++ b/src/core/chunked_stream.js @@ -346,13 +346,13 @@ class ChunkedStreamManager { const chunksToRequest = []; for (const chunk of chunksNeeded) { - let requestIds = this._requestsByChunk.get(chunk); - if (!requestIds) { - requestIds = []; - this._requestsByChunk.set(chunk, requestIds); - - chunksToRequest.push(chunk); - } + const requestIds = this._requestsByChunk.getOrInsertComputed( + chunk, + () => { + chunksToRequest.push(chunk); + return []; + } + ); requestIds.push(requestId); } diff --git a/src/core/editor/pdf_editor.js b/src/core/editor/pdf_editor.js index 2ed888c73..e9e8b252e 100644 --- a/src/core/editor/pdf_editor.js +++ b/src/core/editor/pdf_editor.js @@ -29,7 +29,7 @@ import { } from "../core_utils.js"; import { Dict, isName, Name, Ref, RefSet, RefSetCache } from "../primitives.js"; import { incrementalUpdate, writeValue } from "../writer.js"; -import { isArrayEqual, stringToBytes } from "../../shared/util.js"; +import { isArrayEqual, makeArr, stringToBytes } from "../../shared/util.js"; import { NameTree, NumberTree } from "../name_number_tree.js"; import { stringToAsciiOrUTF16BE, stringToPDFString } from "../string_utils.js"; import { AnnotationFactory } from "../annotation.js"; @@ -510,20 +510,15 @@ class PDFEditor { const bytes = this.#rawStreamBytes(stream); const key = this.#resourceStreamKey(dictStr, bytes); - let bucket = this.#resourceStreamCache.get(key); - if (bucket) { - // Same key only means "maybe equal": confirm with an exact comparison. - for (const entry of bucket) { - if ( - entry.dictStr === dictStr && - isArrayEqual(this.#rawStreamBytes(entry.stream), bytes) - ) { - return entry.ref; - } + const bucket = this.#resourceStreamCache.getOrInsertComputed(key, makeArr); + // Same key only means "maybe equal": confirm with an exact comparison. + for (const entry of bucket) { + if ( + entry.dictStr === dictStr && + isArrayEqual(this.#rawStreamBytes(entry.stream), bytes) + ) { + return entry.ref; } - } else { - bucket = []; - this.#resourceStreamCache.set(key, bucket); } const ref = this.newRef; this.xref[ref.num] = stream; diff --git a/src/core/primitives.js b/src/core/primitives.js index eb5cb0193..b0dff908d 100644 --- a/src/core/primitives.js +++ b/src/core/primitives.js @@ -13,7 +13,7 @@ * limitations under the License. */ -import { assert, shadow, unreachable } from "../shared/util.js"; +import { assert, makeArr, shadow, unreachable } from "../shared/util.js"; const CIRCULAR_REF = Symbol("CIRCULAR_REF"); const EOF = Symbol("EOF"); @@ -242,11 +242,9 @@ class Dict { continue; } for (const [key, value] of dict.getRawEntries()) { - let property = properties.get(key); - if (property === undefined) { - property = []; - properties.set(key, property); - } else if (!mergeSubDicts || !(value instanceof Dict)) { + const property = properties.getOrInsertComputed(key, makeArr); + + if (property.length && !(mergeSubDicts && value instanceof Dict)) { // Ignore additional entries, if either: // - This is a "shallow" merge, where only the first element matters. // - The value is *not* a `Dict`, since other types cannot be merged. diff --git a/src/display/annotation_storage.js b/src/display/annotation_storage.js index 0a1ce895d..a150c2a51 100644 --- a/src/display/annotation_storage.js +++ b/src/display/annotation_storage.js @@ -241,9 +241,10 @@ class AnnotationStorage { continue; } const { type } = editorStats; - if (!typeToEditor.has(type)) { - typeToEditor.set(type, Object.getPrototypeOf(value).constructor); - } + typeToEditor.getOrInsertComputed( + type, + () => Object.getPrototypeOf(value).constructor + ); stats ||= Object.create(null); const map = (stats[type] ||= new Map()); for (const [key, val] of Object.entries(editorStats)) { diff --git a/src/display/canvas.js b/src/display/canvas.js index b8d8fecb8..9e282b58e 100644 --- a/src/display/canvas.js +++ b/src/display/canvas.js @@ -23,6 +23,7 @@ import { FONT_IDENTITY_MATRIX, ImageKind, info, + makeArr, makeMap, OPS, shadow, @@ -1507,11 +1508,10 @@ class CanvasGraphics { } let knockoutFilter = "none"; if (needsAlphaScaling && this.#knockoutFilterCache instanceof Map) { - knockoutFilter = this.#knockoutFilterCache.get(alpha); - if (!knockoutFilter) { - knockoutFilter = this.filterFactory.addKnockoutFilter(alpha); - this.#knockoutFilterCache.set(alpha, knockoutFilter); - } + knockoutFilter = this.#knockoutFilterCache.getOrInsertComputed( + alpha, + () => this.filterFactory.addKnockoutFilter(alpha) + ); } if (!needsAlphaScaling || knockoutFilter !== "none") { @@ -3682,11 +3682,10 @@ class CanvasGraphics { ); const { canvas, context } = this.annotationCanvas; if (canvasName) { - let canvases = this.annotationCanvasMap.get(id); - if (!canvases) { - canvases = []; - this.annotationCanvasMap.set(id, canvases); - } + const canvases = this.annotationCanvasMap.getOrInsertComputed( + id, + makeArr + ); canvas.setAttribute("data-canvas-name", canvasName); // Replace any same-named canvas from a previous render so stale // low-resolution canvases don't pile up across zooms. diff --git a/src/display/editor/tools.js b/src/display/editor/tools.js index 636661361..ac3358493 100644 --- a/src/display/editor/tools.js +++ b/src/display/editor/tools.js @@ -23,6 +23,7 @@ import { AnnotationEditorType, FeatureTest, getUuid, + makeArr, shadow, SVG_NS, Util, @@ -550,7 +551,7 @@ class KeyboardManager { continue; } this.callbacks - .getOrInsertComputed(keyName, () => []) + .getOrInsertComputed(keyName, makeArr) .push({ callback, options, modifiers }); } } diff --git a/web/debugger.mjs b/web/debugger.mjs index 5953b1791..5f6fd2b2b 100644 --- a/web/debugger.mjs +++ b/web/debugger.mjs @@ -459,11 +459,9 @@ class Stepper { const dependents = new Map(); for (const [dependentIdx, { dependencies: ownDependencies }] of metadata) { for (const dependencyIdx of ownDependencies) { - let ownDependents = dependents.get(dependencyIdx); - if (!ownDependents) { - dependents.set(dependencyIdx, (ownDependents = new Set())); - } - ownDependents.add(dependentIdx); + dependents + .getOrInsertComputed(dependencyIdx, () => new Set()) + .add(dependentIdx); } }