Merge pull request #11268 from ahocevar/cache-size

Cache size
This commit is contained in:
Andreas Hocevar
2020-07-13 11:57:49 +02:00
committed by GitHub
16 changed files with 69 additions and 35 deletions

View File

@@ -597,6 +597,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
const wantedTiles = frameState.wantedTiles[tileSourceKey];
const tileQueue = frameState.tileQueue;
const minZoom = tileGrid.getMinZoom();
let tileCount = 0;
let tile, tileRange, tileResolution, x, y, z;
for (z = minZoom; z <= currentZ; ++z) {
tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z, tileRange);
@@ -604,6 +605,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
if (currentZ - z <= preload) {
++tileCount;
tile = tileSource.getTile(z, x, y, pixelRatio, projection);
if (tile.getState() == TileState.IDLE) {
wantedTiles[tile.getKey()] = true;
@@ -625,6 +627,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
}
}
}
tileSource.updateCacheSize(tileCount, projection);
}
}

View File

@@ -48,7 +48,7 @@ const TOS_ATTRIBUTION =
/**
* @typedef {Object} Options
* @property {number} [cacheSize] Tile cache size. The default depends on the screen size. Will be ignored if too small.
* @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least the number of tiles in the viewport.
* @property {boolean} [hidpi=false] If `true` hidpi tiles will be requested.
* @property {string} [culture='en-us'] Culture code.
* @property {string} key Bing Maps API key. Get yours at http://www.bingmapsportal.com/.

View File

@@ -9,7 +9,7 @@ import {assign} from '../obj.js';
/**
* @typedef {Object} Options
* @property {import("./Source.js").AttributionLike} [attributions] Attributions.
* @property {number} [cacheSize] Tile cache size. The default depends on the screen size. Will be ignored if too small.
* @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least the number of tiles in the viewport.
* @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images. Note that
* you must provide a `crossOrigin` value if you want to access pixel data with the Canvas renderer.
* See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.

View File

@@ -19,7 +19,7 @@ export const ATTRIBUTION =
/**
* @typedef {Object} Options
* @property {import("./Source.js").AttributionLike} [attributions] Attributions.
* @property {number} [cacheSize] Tile cache size. The default depends on the screen size. Will be ignored if too small.
* @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least the number of tiles in the viewport.
* @property {null|string} [crossOrigin='anonymous'] The `crossOrigin` attribute for loaded images. Note that
* you must provide a `crossOrigin` value if you want to access pixel data with the Canvas renderer.
* See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.

View File

@@ -86,7 +86,7 @@ const ProviderConfig = {
/**
* @typedef {Object} Options
* @property {number} [cacheSize] Tile cache size. The default depends on the screen size. Will be ignored if too small.
* @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least the number of tiles in the viewport.
* @property {boolean} [imageSmoothing=true] Enable image smoothing.
* @property {string} layer Layer name.
* @property {number} [minZoom] Minimum zoom.

View File

@@ -75,19 +75,12 @@ class TileSource extends Source {
if (tileGrid) {
toSize(tileGrid.getTileSize(tileGrid.getMinZoom()), tileSize);
}
const canUseScreen = typeof screen !== 'undefined';
const width = canUseScreen ? screen.availWidth || screen.width : 1920;
const height = canUseScreen ? screen.availHeight || screen.height : 1080;
const minCacheSize =
4 * Math.ceil(width / tileSize[0]) * Math.ceil(height / tileSize[1]);
/**
* @protected
* @type {import("../TileCache.js").default}
*/
this.tileCache = new TileCache(
Math.max(minCacheSize, options.cacheSize || 0)
);
this.tileCache = new TileCache(options.cacheSize || 0);
/**
* @protected
@@ -325,6 +318,18 @@ class TileSource extends Source {
super.refresh();
}
/**
* Increases the cache size if needed
* @param {number} tileCount Minimum number of tiles needed.
* @param {import("../proj/Projection.js").default} projection Projection.
*/
updateCacheSize(tileCount, projection) {
const tileCache = this.getTileCacheForProjection(projection);
if (tileCount > tileCache.highWaterMark) {
tileCache.highWaterMark = tileCount;
}
}
/**
* Marks a tile coord as being used, without triggering a load.
* @abstract

View File

@@ -13,7 +13,7 @@ import {hash as tileCoordHash} from '../tilecoord.js';
/**
* @typedef {Object} Options
* @property {import("./Source.js").AttributionLike} [attributions] Attributions.
* @property {number} [cacheSize] Tile cache size. The default depends on the screen size. Will be ignored if too small.
* @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least the number of tiles in the viewport.
* @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images. Note that
* you must provide a `crossOrigin` value if you want to access pixel data with the Canvas renderer.
* See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.

View File

@@ -18,7 +18,7 @@ import {getUid} from '../util.js';
* @typedef {Object} Options
* @property {import("./Source.js").AttributionLike} [attributions] Attributions.
* @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.
* @property {number} [cacheSize] Tile cache size. The default depends on the screen size. Will be ignored if too small.
* @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least the number of tiles in the viewport.
* @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images. Note that
* you must provide a `crossOrigin` value if you want to access pixel data with the Canvas renderer.
* See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.

View File

@@ -36,7 +36,7 @@ import {jsonp as requestJSONP} from '../net.js';
/**
* @typedef {Object} Options
* @property {import("./Source.js").AttributionLike} [attributions] Attributions.
* @property {number} [cacheSize] Tile cache size. The default depends on the screen size. Will be ignored if too small.
* @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least the number of tiles in the viewport.
* @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images. Note that
* you must provide a `crossOrigin` value if you want to access pixel data with the Canvas renderer.
* See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.

View File

@@ -20,7 +20,7 @@ import {hash as tileCoordHash} from '../tilecoord.js';
/**
* @typedef {Object} Options
* @property {import("./Source.js").AttributionLike} [attributions] Attributions.
* @property {number} [cacheSize] Tile cache size. The default depends on the screen size. Will be ignored if too small.
* @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least the number of tiles in the viewport.
* @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images. Note that
* you must provide a `crossOrigin` value if you want to access pixel data with the Canvas renderer.
* See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.

View File

@@ -27,7 +27,7 @@ import {toSize} from '../size.js';
* @typedef {Object} Options
* @property {import("./Source.js").AttributionLike} [attributions] Attributions.
* @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.
* @property {number} [cacheSize=128] Cache size.
* @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least twice the number of tiles in the viewport.
* @property {import("../extent.js").Extent} [extent]
* @property {import("../format/Feature.js").default} [format] Feature format for tiles. Used and required by the default.
* @property {boolean} [overlaps=true] This source may have overlapping geometries. Setting this
@@ -509,6 +509,15 @@ class VectorTile extends UrlTile {
Math.round(tileSize[1] * pixelRatio),
];
}
/**
* Increases the cache size if needed
* @param {number} tileCount Minimum number of tiles needed.
* @param {import("../proj/Projection.js").default} projection Projection.
*/
updateCacheSize(tileCount, projection) {
super.updateCacheSize(tileCount * 2, projection);
}
}
export default VectorTile;

View File

@@ -14,7 +14,7 @@ import {find, findIndex, includes} from '../array.js';
/**
* @typedef {Object} Options
* @property {import("./Source.js").AttributionLike} [attributions] Attributions.
* @property {number} [cacheSize] Tile cache size. The default depends on the screen size. Will be ignored if too small.
* @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least the number of tiles in the viewport.
* @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images. Note that
* you must provide a `crossOrigin` value if you want to access pixel data with the Canvas renderer.
* See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.

View File

@@ -9,7 +9,7 @@ import {createXYZ, extentFromProjection} from '../tilegrid.js';
* @typedef {Object} Options
* @property {import("./Source.js").AttributionLike} [attributions] Attributions.
* @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.
* @property {number} [cacheSize] Tile cache size. The default depends on the screen size. Will be ignored if too small.
* @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least the number of tiles in the viewport.
* @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images. Note that
* you must provide a `crossOrigin` value if you want to access pixel data with the Canvas renderer.
* See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.

View File

@@ -83,7 +83,7 @@ export class CustomTile extends ImageTile {
/**
* @typedef {Object} Options
* @property {import("./Source.js").AttributionLike} [attributions] Attributions.
* @property {number} [cacheSize] Tile cache size. The default depends on the screen size. Will be ignored if too small.
* @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least the number of tiles in the viewport.
* @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images. Note that
* you must provide a `crossOrigin` value you want to access pixel data with the Canvas renderer.
* See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.

View File

@@ -27,6 +27,8 @@ class LRUCache {
*/
constructor(opt_highWaterMark) {
/**
* Desired max cache size after expireCache(). If set to 0, no cache entries
* will be pruned at all.
* @type {number}
*/
this.highWaterMark =
@@ -61,7 +63,7 @@ class LRUCache {
* @return {boolean} Can expire cache.
*/
canExpireCache() {
return this.getCount() > this.highWaterMark;
return this.highWaterMark > 0 && this.getCount() > this.highWaterMark;
}
/**

View File

@@ -1,9 +1,13 @@
import Map from '../../../../src/ol/Map.js';
import Projection from '../../../../src/ol/proj/Projection.js';
import Source from '../../../../src/ol/source/Source.js';
import Tile from '../../../../src/ol/Tile.js';
import TileDebugSource from '../../../../src/ol/source/TileDebug.js';
import TileGrid from '../../../../src/ol/tilegrid/TileGrid.js';
import TileLayer from '../../../../src/ol/layer/Tile.js';
import TileRange from '../../../../src/ol/TileRange.js';
import TileSource from '../../../../src/ol/source/Tile.js';
import View from '../../../../src/ol/View.js';
import {getKeyZXY} from '../../../../src/ol/tilecoord.js';
import {get as getProjection} from '../../../../src/ol/proj.js';
@@ -53,23 +57,34 @@ describe('ol.source.Tile', function () {
expect(source).to.be.a(Source);
expect(source).to.be.a(TileSource);
});
it('sets a screen dependent cache size', function () {
it('sets 0 as initial cache size', function () {
const source = new TileSource({});
expect(source.tileCache.highWaterMark).to.be(
4 *
Math.ceil(screen.availWidth / 256) *
Math.ceil(screen.availHeight / 256)
);
expect(source.tileCache.highWaterMark).to.be(0);
});
it('ignores a cache size that is too small', function () {
const source = new TileSource({
cacheSize: 1,
it('grows the cache', function () {
const source = new TileDebugSource();
const layer = new TileLayer({
source: source,
});
expect(source.tileCache.highWaterMark).to.be(
4 *
Math.ceil(screen.availWidth / 256) *
Math.ceil(screen.availHeight / 256)
);
const target = document.createElement('div');
target.style.width = '100px';
target.style.height = '100px';
document.body.appendChild(target);
const map = new Map({
layers: [layer],
view: new View({
center: [0, 0],
zoom: 2,
}),
target: target,
});
map.renderSync();
expect(
source.getTileCacheForProjection(map.getView().getProjection())
.highWaterMark
).to.be(4);
map.setTarget(null);
document.body.removeChild(target);
});
it('sets a custom cache size', function () {
const projection = getProjection('EPSG:4326');