Merge pull request #14313 from Snuffleupagus/PDFDocument_pagePromises-map

Change the `_pagePromises` cache, in the worker, from an Array to a Map
This commit is contained in:
Tim van der Meij 2021-11-27 20:58:23 +01:00 committed by GitHub
commit 9a1e27efc5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -655,7 +655,7 @@ class PDFDocument {
this.pdfManager = pdfManager; this.pdfManager = pdfManager;
this.stream = stream; this.stream = stream;
this.xref = new XRef(stream, pdfManager); this.xref = new XRef(stream, pdfManager);
this._pagePromises = []; this._pagePromises = new Map();
this._version = null; this._version = null;
const idCounters = { const idCounters = {
@ -1261,7 +1261,7 @@ class PDFDocument {
]); ]);
} }
_getLinearizationPage(pageIndex) { async _getLinearizationPage(pageIndex) {
const { catalog, linearization } = this; const { catalog, linearization } = this;
if ( if (
typeof PDFJSDev === "undefined" || typeof PDFJSDev === "undefined" ||
@ -1274,61 +1274,43 @@ class PDFDocument {
} }
const ref = Ref.get(linearization.objectNumberFirst, 0); const ref = Ref.get(linearization.objectNumberFirst, 0);
return this.xref try {
.fetchAsync(ref) const obj = await this.xref.fetchAsync(ref);
.then(obj => { // Ensure that the object that was found is actually a Page dictionary.
// Ensure that the object that was found is actually a Page dictionary. if (
if ( isDict(obj, "Page") ||
isDict(obj, "Page") || (isDict(obj) && !obj.has("Type") && obj.has("Contents"))
(isDict(obj) && !obj.has("Type") && obj.has("Contents")) ) {
) { if (ref && !catalog.pageKidsCountCache.has(ref)) {
if (ref && !catalog.pageKidsCountCache.has(ref)) { catalog.pageKidsCountCache.put(ref, 1); // Cache the Page reference.
catalog.pageKidsCountCache.put(ref, 1); // Cache the Page reference.
}
return [obj, ref];
} }
throw new FormatError( return [obj, ref];
"The Linearization dictionary doesn't point " + }
"to a valid Page dictionary." throw new FormatError(
); "The Linearization dictionary doesn't point to a valid Page dictionary."
}) );
.catch(reason => { } catch (reason) {
info(reason); info(reason);
return catalog.getPageDict(pageIndex); return catalog.getPageDict(pageIndex);
}); }
} }
getPage(pageIndex) { getPage(pageIndex) {
if (this._pagePromises[pageIndex] !== undefined) { const cachedPromise = this._pagePromises.get(pageIndex);
return this._pagePromises[pageIndex]; if (cachedPromise) {
return cachedPromise;
} }
const { catalog, linearization } = this; const { catalog, linearization, xfaFactory } = this;
if (this.xfaFactory) { let promise;
return Promise.resolve( if (xfaFactory) {
new Page({ promise = Promise.resolve([Dict.empty, null]);
pdfManager: this.pdfManager, } else if (linearization && linearization.pageFirst === pageIndex) {
xref: this.xref, promise = this._getLinearizationPage(pageIndex);
pageIndex, } else {
pageDict: Dict.empty, promise = catalog.getPageDict(pageIndex);
ref: null,
globalIdFactory: this._globalIdFactory,
fontCache: catalog.fontCache,
builtInCMapCache: catalog.builtInCMapCache,
standardFontDataCache: catalog.standardFontDataCache,
globalImageCache: catalog.globalImageCache,
nonBlendModesSet: catalog.nonBlendModesSet,
xfaFactory: this.xfaFactory,
})
);
} }
promise = promise.then(([pageDict, ref]) => {
const promise =
linearization && linearization.pageFirst === pageIndex
? this._getLinearizationPage(pageIndex)
: catalog.getPageDict(pageIndex);
return (this._pagePromises[pageIndex] = promise.then(([pageDict, ref]) => {
return new Page({ return new Page({
pdfManager: this.pdfManager, pdfManager: this.pdfManager,
xref: this.xref, xref: this.xref,
@ -1341,9 +1323,12 @@ class PDFDocument {
standardFontDataCache: catalog.standardFontDataCache, standardFontDataCache: catalog.standardFontDataCache,
globalImageCache: catalog.globalImageCache, globalImageCache: catalog.globalImageCache,
nonBlendModesSet: catalog.nonBlendModesSet, nonBlendModesSet: catalog.nonBlendModesSet,
xfaFactory: null, xfaFactory,
}); });
})); });
this._pagePromises.set(pageIndex, promise);
return promise;
} }
checkFirstPage() { checkFirstPage() {
@ -1352,7 +1337,7 @@ class PDFDocument {
// Clear out the various caches to ensure that we haven't stored any // Clear out the various caches to ensure that we haven't stored any
// inconsistent and/or incorrect state, since that could easily break // inconsistent and/or incorrect state, since that could easily break
// subsequent `this.getPage` calls. // subsequent `this.getPage` calls.
this._pagePromises.length = 0; this._pagePromises.clear();
await this.cleanup(); await this.cleanup();
throw new XRefParseException(); throw new XRefParseException();