Avoid re-parsing global images that failed decoding (issue 18042, PR 17428 follow-up)

For images that failed to decode once we want to avoid a pointless round-trip to the main-thread, which could otherwise happen for globally cached images.
This commit is contained in:
Jonas Jenwald 2024-05-04 15:59:07 +02:00
parent bb9bb34721
commit c5f92437f7
6 changed files with 109 additions and 23 deletions

View file

@ -19,7 +19,7 @@ import {
unreachable,
warn,
} from "../shared/util.js";
import { RefSetCache } from "./primitives.js";
import { RefSet, RefSetCache } from "./primitives.js";
class BaseLocalCache {
constructor(options) {
@ -178,6 +178,8 @@ class GlobalImageCache {
static MAX_BYTE_SIZE = 5 * MAX_IMAGE_SIZE_TO_CACHE;
#decodeFailedSet = new RefSet();
constructor() {
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
assert(
@ -189,7 +191,7 @@ class GlobalImageCache {
this._imageCache = new RefSetCache();
}
get _byteSize() {
get #byteSize() {
let byteSize = 0;
for (const imageData of this._imageCache) {
byteSize += imageData.byteSize;
@ -197,11 +199,11 @@ class GlobalImageCache {
return byteSize;
}
get _cacheLimitReached() {
get #cacheLimitReached() {
if (this._imageCache.size < GlobalImageCache.MIN_IMAGES_TO_CACHE) {
return false;
}
if (this._byteSize < GlobalImageCache.MAX_BYTE_SIZE) {
if (this.#byteSize < GlobalImageCache.MAX_BYTE_SIZE) {
return false;
}
return true;
@ -218,12 +220,20 @@ class GlobalImageCache {
if (pageIndexSet.size < GlobalImageCache.NUM_PAGES_THRESHOLD) {
return false;
}
if (!this._imageCache.has(ref) && this._cacheLimitReached) {
if (!this._imageCache.has(ref) && this.#cacheLimitReached) {
return false;
}
return true;
}
addDecodeFailed(ref) {
this.#decodeFailedSet.put(ref);
}
hasDecodeFailed(ref) {
return this.#decodeFailedSet.has(ref);
}
/**
* PLEASE NOTE: Must be called *after* the `setData` method.
*/
@ -265,7 +275,7 @@ class GlobalImageCache {
if (this._imageCache.has(ref)) {
return;
}
if (this._cacheLimitReached) {
if (this.#cacheLimitReached) {
warn("GlobalImageCache.setData - cache limit reached.");
return;
}
@ -274,6 +284,7 @@ class GlobalImageCache {
clear(onlyData = false) {
if (!onlyData) {
this.#decodeFailedSet.clear();
this._refCache.clear();
}
this._imageCache.clear();