Skip to content

Commit 3476633

Browse files
Cache loaded parents
1 parent dfae15d commit 3476633

File tree

1 file changed

+57
-8
lines changed

1 file changed

+57
-8
lines changed

src/source/source_cache.js

+57-8
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class SourceCache extends Evented {
5757
_isIdRenderable: (id: string, symbolLayer?: boolean) => boolean;
5858
used: boolean;
5959
_state: SourceFeatureState;
60+
_loadedParentTiles: {[string]: ?Tile};
6061

6162
static maxUnderzooming: number;
6263
static maxOverzooming: number;
@@ -93,6 +94,7 @@ class SourceCache extends Evented {
9394
this._timers = {};
9495
this._cacheTimers = {};
9596
this._maxTileCacheSize = null;
97+
this._loadedParentTiles = {};
9698

9799
this._coveredTiles = {};
98100
this._state = new SourceFeatureState();
@@ -367,19 +369,32 @@ class SourceCache extends Evented {
367369
* Find a loaded parent of the given tile (up to minCoveringZoom)
368370
*/
369371
findLoadedParent(tileID: OverscaledTileID, minCoveringZoom: number): ?Tile {
372+
if (tileID.key in this._loadedParentTiles) {
373+
const parent = this._loadedParentTiles[tileID.key];
374+
if (parent && parent.tileID.overscaledZ >= minCoveringZoom) {
375+
return parent;
376+
} else {
377+
return null;
378+
}
379+
}
370380
for (let z = tileID.overscaledZ - 1; z >= minCoveringZoom; z--) {
371-
const parentKey = tileID.calculateScaledKey(z, true);
372-
const tile = this._tiles[parentKey];
373-
if (tile && tile.hasData()) {
381+
const parentTileID = tileID.scaledTo(z);
382+
const tile = this._getLoadedTile(parentTileID);
383+
if (tile)
374384
return tile;
375-
}
376-
// TileCache ignores wrap in lookup.
377-
const parentWrappedKey = tileID.calculateScaledKey(z, false);
378-
const cachedTile = this._cache.getByKey(parentWrappedKey);
379-
if (cachedTile) return cachedTile;
380385
}
381386
}
382387

388+
_getLoadedTile(tileID: OverscaledTileID): ?Tile {
389+
const tile = this._tiles[tileID.key];
390+
if (tile && tile.hasData()) {
391+
return tile;
392+
}
393+
// TileCache ignores wrap in lookup.
394+
const cachedTile = this._cache.getByKey(tileID.wrapped().key);
395+
return cachedTile;
396+
}
397+
383398
/**
384399
* Resizes the tile cache based on the current viewport's size
385400
* or the maxTileCacheSize option passed during map creation
@@ -537,6 +552,40 @@ class SourceCache extends Evented {
537552
this._removeTile(tileID);
538553
}
539554
}
555+
556+
// Construct a cache of loaded parents
557+
this._loadedParentTiles = {};
558+
559+
for (const tile of (Object.values(this._tiles): any)) {
560+
const path = [];
561+
let parentTile: ?Tile;
562+
let currentId = tile.tileID;
563+
564+
// Find the closest loaded ancestor by traversing the tile tree towards the root and
565+
// caching results along the way
566+
while (currentId.overscaledZ > 0) {
567+
const parentId = currentId.scaledTo(currentId.overscaledZ - 1);
568+
path.push(currentId.key);
569+
570+
// Do we have a cached result from previous traversals?
571+
if (parentId.key in this._loadedParentTiles) {
572+
parentTile = this._loadedParentTiles[parentId.key];
573+
break;
574+
}
575+
576+
parentTile = this._getLoadedTile(parentId);
577+
if (parentTile) {
578+
break;
579+
}
580+
581+
currentId = parentId;
582+
}
583+
584+
// Cache the result of this traversal to all newly visited tiles
585+
for (let i = 0; i < path.length; i++) {
586+
this._loadedParentTiles[path[i]] = parentTile;
587+
}
588+
}
540589
}
541590

542591
releaseSymbolFadeTiles() {

0 commit comments

Comments
 (0)