Merge pull request #11284 from Snuffleupagus/ObjectLoader-allChunksLoaded

Make the `ObjectLoader` use more efficient methods when determining if data needs to be loaded
This commit is contained in:
Tim van der Meij 2019-10-30 22:48:48 +01:00 committed by GitHub
commit 72bd8e8bdb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 15 deletions

View File

@ -285,6 +285,12 @@ class ChunkedStream {
} }
return missingChunks; return missingChunks;
}; };
ChunkedStreamSubstream.prototype.allChunksLoaded = function() {
if (this.numChunksLoaded === this.numChunks) {
return true;
}
return this.getMissingChunks().length === 0;
};
const subStream = new ChunkedStreamSubstream(); const subStream = new ChunkedStreamSubstream();
subStream.pos = subStream.start = start; subStream.pos = subStream.start = start;

View File

@ -27,7 +27,6 @@ import { Lexer, Parser } from './parser';
import { import {
MissingDataException, toRomanNumerals, XRefEntryException, XRefParseException MissingDataException, toRomanNumerals, XRefEntryException, XRefParseException
} from './core_utils'; } from './core_utils';
import { ChunkedStream } from './chunked_stream';
import { CipherTransformFactory } from './crypto'; import { CipherTransformFactory } from './crypto';
import { ColorSpace } from './colorspace'; import { ColorSpace } from './colorspace';
@ -2039,13 +2038,13 @@ var FileSpec = (function FileSpecClosure() {
*/ */
let ObjectLoader = (function() { let ObjectLoader = (function() {
function mayHaveChildren(value) { function mayHaveChildren(value) {
return isRef(value) || isDict(value) || Array.isArray(value) || return (value instanceof Ref) || (value instanceof Dict) ||
isStream(value); Array.isArray(value) || isStream(value);
} }
function addChildren(node, nodesToVisit) { function addChildren(node, nodesToVisit) {
if (isDict(node) || isStream(node)) { if ((node instanceof Dict) || isStream(node)) {
let dict = isDict(node) ? node : node.dict; let dict = (node instanceof Dict) ? node : node.dict;
let dictKeys = dict.getKeys(); let dictKeys = dict.getKeys();
for (let i = 0, ii = dictKeys.length; i < ii; i++) { for (let i = 0, ii = dictKeys.length; i < ii; i++) {
let rawValue = dict.getRaw(dictKeys[i]); let rawValue = dict.getRaw(dictKeys[i]);
@ -2072,14 +2071,14 @@ let ObjectLoader = (function() {
} }
ObjectLoader.prototype = { ObjectLoader.prototype = {
load() { async load() {
this.capability = createPromiseCapability(); // Don't walk the graph if all the data is already loaded; note that only
// Don't walk the graph if all the data is already loaded. // `ChunkedStream` instances have a `allChunksLoaded` method.
if (!(this.xref.stream instanceof ChunkedStream) || if (!this.xref.stream.allChunksLoaded ||
this.xref.stream.getMissingChunks().length === 0) { this.xref.stream.allChunksLoaded()) {
this.capability.resolve(); return undefined;
return this.capability.promise;
} }
this.capability = createPromiseCapability();
let { keys, dict, } = this; let { keys, dict, } = this;
this.refSet = new RefSet(); this.refSet = new RefSet();
@ -2105,7 +2104,7 @@ let ObjectLoader = (function() {
let currentNode = nodesToVisit.pop(); let currentNode = nodesToVisit.pop();
// Only references or chunked streams can cause missing data exceptions. // Only references or chunked streams can cause missing data exceptions.
if (isRef(currentNode)) { if (currentNode instanceof Ref) {
// Skip nodes that have already been visited. // Skip nodes that have already been visited.
if (this.refSet.has(currentNode)) { if (this.refSet.has(currentNode)) {
continue; continue;
@ -2126,7 +2125,7 @@ let ObjectLoader = (function() {
let foundMissingData = false; let foundMissingData = false;
for (let i = 0, ii = baseStreams.length; i < ii; i++) { for (let i = 0, ii = baseStreams.length; i < ii; i++) {
let stream = baseStreams[i]; let stream = baseStreams[i];
if (stream.getMissingChunks && stream.getMissingChunks().length) { if (stream.allChunksLoaded && !stream.allChunksLoaded()) {
foundMissingData = true; foundMissingData = true;
pendingRequests.push({ begin: stream.start, end: stream.end, }); pendingRequests.push({ begin: stream.start, end: stream.end, });
} }
@ -2145,7 +2144,7 @@ let ObjectLoader = (function() {
let node = nodesToRevisit[i]; let node = nodesToRevisit[i];
// Remove any reference nodes from the current `RefSet` so they // Remove any reference nodes from the current `RefSet` so they
// aren't skipped when we revist them. // aren't skipped when we revist them.
if (isRef(node)) { if (node instanceof Ref) {
this.refSet.remove(node); this.refSet.remove(node);
} }
} }