This is an automated email from the ASF dual-hosted git repository. desruisseaux pushed a commit to branch geoapi-4.0 in repository https://gitbox.apache.org/repos/asf/sis.git
The following commit(s) were added to refs/heads/geoapi-4.0 by this push: new 733f1f8 Add one more check of tile consistency with tiled images. 733f1f8 is described below commit 733f1f83df77a7bfa33edd50d0730e04a13a2188 Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Mon Feb 14 17:00:02 2022 +0100 Add one more check of tile consistency with tiled images. --- .../sis/internal/storage/TiledGridCoverage.java | 38 ++++++++++++++++++---- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/TiledGridCoverage.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/TiledGridCoverage.java index 8dcd8dd..2b2a802 100644 --- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/TiledGridCoverage.java +++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/TiledGridCoverage.java @@ -812,18 +812,44 @@ public abstract class TiledGridCoverage extends GridCoverage { } /** - * Stores the given raster in the cache. + * Stores the given raster in the cache. If another raster existed previously in the cache, + * the old raster will be reused if it has the same size and model, or discarded otherwise. + * The later case may happen if {@link AOI#getCachedTile()} determined that a cached raster + * exists but can not be reused. * - * @param raster the raster to cache. + * @param tile the raster to cache. * @return the cached raster. Should be the given {@code raster} instance, * but this method check for concurrent caching as a paranoiac check. * * @see AOI#getCachedTile() */ - public Raster cache(final Raster raster) { - final Raster existing = coverage.rasters.putIfAbsent( - coverage.createCacheKey(indexInTileVector), raster); - return (existing != null) ? existing : raster; + public Raster cache(final Raster tile) { + final TiledGridResource.CacheKey key = coverage.createCacheKey(indexInTileVector); + Raster existing = coverage.rasters.put(key, tile); + if (existing != null) { + /* + * If a tile already exists, verify if its layout is compatible with the given tile. + * If yes, we assume that the two tiles have the same content. We do this check as a + * safety but it should not happen if the caller synchronized the tile read actions. + */ + Raster sentinel = tile; + while (existing.getSampleModel().equals(tile.getSampleModel()) + && existing.getWidth() == tile.getWidth() + && existing.getHeight() == tile.getHeight()) + { + final int x = tile.getMinX(); + final int y = tile.getMinY(); + if (existing.getMinX() != x || existing.getMinY() != y) { + existing = existing.createTranslatedChild(x, y); + } + final Raster c = coverage.rasters.put(key, existing); + if (c == null || c == sentinel) { + return existing; + } + sentinel = existing = c; // Cache content changed concurrently. + } + } + return tile; } }