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;
         }
     }
 

Reply via email to