Invalidate cache if a point has been deleted or changed geometry. Fix #865; review cache retention times and disable cache for external geojson datasets, fix #1660

This commit is contained in:
Pieter Vander Vennet 2024-02-26 15:52:40 +01:00
parent adaff94dbd
commit a399260bf0
6 changed files with 68 additions and 39 deletions

View file

@ -5,6 +5,8 @@ import { GeoOperations } from "../../GeoOperations"
import FeaturePropertiesStore from "./FeaturePropertiesStore"
import { UIEventSource } from "../../UIEventSource"
import { Utils } from "../../../Utils"
import { Tiles } from "../../../Models/TileRange"
import { BBox } from "../../BBox"
class SingleTileSaver {
private readonly _storage: UIEventSource<Feature[]>
@ -54,6 +56,8 @@ class SingleTileSaver {
* Also see the sibling class
*/
export default class SaveFeatureSourceToLocalStorage {
public readonly storage: TileLocalStorage<Feature[]>
private zoomlevel: number
constructor(
backend: string,
layername: string,
@ -62,7 +66,9 @@ export default class SaveFeatureSourceToLocalStorage {
featureProperties: FeaturePropertiesStore,
maxCacheAge: number
) {
this.zoomlevel = zoomlevel
const storage = TileLocalStorage.construct<Feature[]>(backend, layername, maxCacheAge)
this.storage = storage
const singleTileSavers: Map<number, SingleTileSaver> = new Map<number, SingleTileSaver>()
features.features.addCallbackAndRunD((features) => {
const sliced = GeoOperations.slice(zoomlevel, features)
@ -80,4 +86,12 @@ export default class SaveFeatureSourceToLocalStorage {
})
})
}
public invalidateCacheAround(bbox: BBox) {
const range = Tiles.tileRangeFrom(bbox, this.zoomlevel)
Tiles.MapRange(range, (x, y) => {
const index = Tiles.tile_index(this.zoomlevel, x, y)
this.storage.invalidate(index)
})
}
}

View file

@ -1,5 +1,6 @@
import { IdbLocalStorage } from "../../Web/IdbLocalStorage"
import { UIEventSource } from "../../UIEventSource"
import { Tiles } from "../../../Models/TileRange"
/**
* A class which allows to read/write a tile to local storage.
@ -91,9 +92,17 @@ export default class TileLocalStorage<T> {
await IdbLocalStorage.GetDirectly(this._layername + "_" + tileIndex + "_date")
)
const maxAge = this._maxAgeSeconds
const timeDiff = Date.now() - date
const timeDiff = (Date.now() - date) / 1000
if (timeDiff >= maxAge) {
console.debug("Dropping cache for", this._layername, tileIndex, "out of date")
console.debug(
"Dropping cache for",
this._layername,
tileIndex,
"out of date. Max allowed age is",
maxAge,
"current age is",
timeDiff
)
await IdbLocalStorage.SetDirectly(this._layername + "_" + tileIndex, undefined)
return undefined
@ -102,7 +111,8 @@ export default class TileLocalStorage<T> {
return <any>data
}
invalidate(zoomlevel: number, tileIndex) {
public invalidate(tileIndex: number) {
console.log("Invalidated tile", tileIndex)
this.getTileSource(tileIndex).setData(undefined)
}
}

View file

@ -27,7 +27,7 @@ export default class LayoutSource extends FeatureSourceMerger {
private readonly supportsForceDownload: UpdatableFeatureSource[]
private readonly fromCache: Map<string, LocalStorageFeatureSource>
private static readonly fromCacheZoomLevel = 15
public static readonly fromCacheZoomLevel = 15
constructor(
layers: LayerConfig[],
featureSwitches: FeatureSwitchState,

View file

@ -27,14 +27,14 @@ export default class LocalStorageFeatureSource extends DynamicTileSource {
options?.maxAge ?? 24 * 60 * 60
)
super(
new ImmutableStore(zoomlevel),
new ImmutableStore(zoomlevel),
layer.minzoom,
(tileIndex) =>
new StaticFeatureSource(
storage.getTileSource(tileIndex).mapD((features) => {
if (features.length === undefined) {
console.trace("These are not features:", features)
storage.invalidate(zoomlevel, tileIndex)
storage.invalidate(tileIndex)
return []
}
return features.filter((f) => !f.properties.id.match(/(node|way)\/-[0-9]+/))