Skip to content

Commit

Permalink
feat(Cache): Change to LRUCache almost everywhere
Browse files Browse the repository at this point in the history
  • Loading branch information
ftoromanoff committed Jan 22, 2025
1 parent cecc413 commit d51d491
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 52 deletions.
13 changes: 8 additions & 5 deletions src/Layer/Layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as THREE from 'three';
import { STRATEGY_MIN_NETWORK_TRAFFIC } from 'Layer/LayerUpdateStrategy';
import InfoLayer from 'Layer/InfoLayer';
import Source from 'Source/Source';
import Cache from 'Core/Scheduler/Cache';
import { LRUCache } from 'lru-cache';
import Style from 'Core/Style';

/**
Expand Down Expand Up @@ -198,7 +198,10 @@ class Layer extends THREE.EventDispatcher {
/**
* @type {Cache}
*/
this.cache = new Cache(cacheLifeTime);
this.cache = new LRUCache({
max: 500,
...(cacheLifeTime !== Infinity && { ttl: cacheLifeTime }),
});

this.mergeFeatures = mergeFeatures;
}
Expand Down Expand Up @@ -271,14 +274,14 @@ class Layer extends THREE.EventDispatcher {
}

getData(from, to) {
const key = this.source.keysFromExtent(this.source.isVectorSource ? to : from);
let data = this.cache.get(...key);
const key = this.source.getDataKey(this.source.isVectorSource ? to : from);
let data = this.cache.get(key);
if (!data) {
data = this.source.loadData(from, this)
.then(feat => this.convert(feat, to), (err) => {
throw err;
});
this.cache.set(data, ...key);
this.cache.set(key, data);
}
return data;
}
Expand Down
8 changes: 4 additions & 4 deletions src/Source/FileSource.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Source from 'Source/Source';
import Cache from 'Core/Scheduler/Cache';
import { LRUCache } from 'lru-cache';

/**
* An object defining the source of a single resource to get from a direct
Expand Down Expand Up @@ -136,8 +136,8 @@ class FileSource extends Source {
this.fetchedData = f;
});
} else if (source.features) {
this._featuresCaches[source.features.crs] = new Cache();
this._featuresCaches[source.features.crs].set(Promise.resolve(source.features), 0);
this._featuresCaches[source.features.crs] = new LRUCache({ max: 500 });
this._featuresCaches[source.features.crs].set(0, Promise.resolve(source.features));
}

this.whenReady.then(() => this.fetchedData);
Expand All @@ -159,7 +159,7 @@ class FileSource extends Source {
options.out.forcedExtentCrs = options.out.crs != 'EPSG:4978' ? options.out.crs : this.crs;
}
features = this.parser(this.fetchedData, options);
this._featuresCaches[options.out.crs].set(features, 0);
this._featuresCaches[options.out.crs].set(0, features);
}
features.then((data) => {
if (data.extent) {
Expand Down
4 changes: 2 additions & 2 deletions src/Source/OrientedImageSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ class OrientedImageSource extends Source {
return this.imageUrl(imageInfo.cameraId, imageInfo.panoId);
}

keysFromExtent(image) {
return [image.cameraId, image.panoId];
getDataKey(image) {
return `c${image.cameraId}p${image.panoId}`;
}

/**
Expand Down
32 changes: 13 additions & 19 deletions src/Source/Source.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import GTXParser from 'Parser/GTXParser';
import ISGParser from 'Parser/ISGParser';
import VectorTileParser from 'Parser/VectorTileParser';
import Fetcher from 'Provider/Fetcher';
import Cache from 'Core/Scheduler/Cache';
// import Cache from 'Core/Scheduler/Cache';
import { LRUCache } from 'lru-cache';

/** @private */
export const supportedParsers = new Map([
Expand Down Expand Up @@ -133,8 +134,8 @@ class Source {
throw new Error('In extended Source, you have to implement the method urlFromExtent!');
}

keysFromExtent(extent) {
return [extent.zoom, extent.row, extent.col];
getDataKey(extent) {
return `z${extent.zoom}r${extent.row}c${extent.col}`;
}

/**
Expand All @@ -147,24 +148,17 @@ class Source {
*/
loadData(extent, out) {
const cache = this._featuresCaches[out.crs];
const key = this.keysFromExtent(extent);
const key = this.getDataKey(extent);
// console.log('Source.loadData', key);
// try to get parsed data from cache
let features = cache.get(...key);
let features = cache.get(key);
if (!features) {
// otherwise fetch/parse the data
features = cache.set(
this.fetcher(this.urlFromExtent(extent), this.networkOptions)
.then(file => this.parser(file, { out, in: this, extent }))
.catch(err => this.handlingError(err)),
...key);

if (this.onParsedFile) {
features.then((feat) => {
this.onParsedFile(feat);
console.warn('Source.onParsedFile was deprecated');
return feat;
});
}
features = this.fetcher(this.urlFromExtent(extent), this.networkOptions)
.then(file => this.parser(file, { out, in: this, extent }))
.catch(err => this.handlingError(err));

cache.set(key, features);
}
return features;
}
Expand All @@ -180,7 +174,7 @@ class Source {
// Cache feature only if it's vector data, the feature are cached in source.
// It's not necessary to cache raster in Source,
// because it's already cached on layer.
this._featuresCaches[options.out.crs] = this.isVectorSource ? new Cache() : noCache;
this._featuresCaches[options.out.crs] = this.isVectorSource ? new LRUCache({ max: 500 }) : noCache;
}
}

Expand Down
25 changes: 9 additions & 16 deletions src/Source/VectorTilesSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,26 +171,19 @@ class VectorTilesSource extends TMSSource {

loadData(extent, out) {
const cache = this._featuresCaches[out.crs];
const key = this.keysFromExtent(extent);
const key = this.getDataKey(extent);
console.log('VectorTileSource.loadData', key);

Check warning on line 175 in src/Source/VectorTilesSource.js

View workflow job for this annotation

GitHub Actions / Build bundle, check Linter and generate documentation

Unexpected console statement
// try to get parsed data from cache
let features = cache.get(...key);
let features = cache.get(key);
if (!features) {
// otherwise fetch/parse the data
features = cache.set(
Promise.all(this.urls.map(url =>
this.fetcher(this.urlFromExtent(extent, url), this.networkOptions)
.then(file => this.parser(file, { out, in: this, extent }))))
.then(collections => mergeCollections(collections))
.catch(err => this.handlingError(err)),
...key);
features = Promise.all(this.urls.map(url =>
this.fetcher(this.urlFromExtent(extent, url), this.networkOptions)
.then(file => this.parser(file, { out, in: this, extent }))))
.then(collections => mergeCollections(collections))
.catch(err => this.handlingError(err));

if (this.onParsedFile) {
features.then((feat) => {
this.onParsedFile(feat);
console.warn('Source.onParsedFile was deprecated');
return feat;
});
}
cache.set(key, features);
}
return features;
}
Expand Down
6 changes: 3 additions & 3 deletions src/Source/WFSSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,11 @@ class WFSSource extends Source {
return super.handlingError(err);
}

keysFromExtent(extent) {
getDataKey(extent) {
if (extent.isTile) {
return super.keysFromExtent(extent);
return super.getDataKey(extent);
} else {
return [extent.zoom, extent.south, extent.west];
return `z${extent.zoom}s${extent.south}w${extent.west}`;
}
}

Expand Down
2 changes: 1 addition & 1 deletion test/unit/source/orientedimagesource.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('OrientedImageSource', function () {
it('should return keys OrientedImageSource from request', function () {
const source = new OrientedImageSource({ url: 'http://source.test' });
const image = { cameraId: 5, panoId: 10 };
const keys = source.keysFromExtent(image);
const keys = source.getDataKey(image);
assert.equal(image.cameraId, keys[0]);
assert.equal(image.panoId, keys[1]);
});
Expand Down
4 changes: 2 additions & 2 deletions test/unit/source/wfssource.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ describe('WFSSource', function () {
it('should return keys from request', function () {
const source = new WFSSource(paramsWFS);
const tile = new Tile('TMS:4326', 5, 10, 15);
const keys = source.keysFromExtent(tile);
const keys = source.getDataKey(tile);
assert.equal(tile.zoom, keys[0]);
assert.equal(tile.row, keys[1]);
assert.equal(tile.col, keys[2]);
const extentepsg = new Extent('EPSG:4326', 5.5, 10, 22.3, 89.34);
const keysepsg = source.keysFromExtent(extentepsg);
const keysepsg = source.getDataKey(extentepsg);
assert.equal(extentepsg.south, keysepsg[1]);
assert.equal(extentepsg.west, keysepsg[2]);
});
Expand Down

0 comments on commit d51d491

Please sign in to comment.