sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 02/03: Provides a mechanism for creating transforms without caching them. It can improve performances when creating a lot of transforms living for a short time.
Date Wed, 01 Jul 2020 14:33:22 GMT
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

commit b0405ddc77b3e50a2636d03f4bd91f1bfaee519b
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Wed Jul 1 13:05:20 2020 +0200

    Provides a mechanism for creating transforms without caching them.
    It can improve performances when creating a lot of transforms living for a short time.
---
 .../internal/referencing/provider/Providers.java   |  2 +
 .../transform/DefaultMathTransformFactory.java     | 88 ++++++++++++++++++++--
 .../transform/DefaultMathTransformFactoryTest.java | 15 ++++
 3 files changed, 100 insertions(+), 5 deletions(-)

diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Providers.java
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Providers.java
index 8176e21..6ed48e5 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Providers.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Providers.java
@@ -19,6 +19,7 @@ package org.apache.sis.internal.referencing.provider;
 import java.util.List;
 import org.opengis.referencing.operation.OperationMethod;
 import org.apache.sis.internal.referencing.LazySet;
+import org.apache.sis.util.Workaround;
 
 
 /**
@@ -34,6 +35,7 @@ import org.apache.sis.internal.referencing.LazySet;
  * @since   0.7
  * @module
  */
+@Workaround(library="JDK", version="1.8")
 public final class Providers extends LazySet<OperationMethod> {
     /**
      * Creates new set of provider.
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
index c07fbfa..f84d11d 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
@@ -163,7 +163,7 @@ import org.apache.sis.util.resources.Errors;
  * There is typically only one {@code MathTransformFactory} instance for the whole application.
  *
  * @author  Martin Desruisseaux (Geomatys, IRD)
- * @version 0.8
+ * @version 1.1
  *
  * @see MathTransformProvider
  * @see AbstractMathTransform
@@ -227,8 +227,9 @@ public class DefaultMathTransformFactory extends AbstractFactory implements
Math
     private final ThreadLocal<OperationMethod> lastMethod;
 
     /**
-     * The math transforms created so far. This pool is used in order
-     * to return instances of existing math transforms when possible.
+     * The math transforms created so far. This pool is used in order to return instances
of existing
+     * math transforms when possible. If {@code null}, then no pool should be used. A null
value is
+     * preferable when the transforms are known to be short-lived, for avoiding the cost
of caching them.
      */
     private final WeakHashSet<MathTransform> pool;
 
@@ -240,6 +241,13 @@ public class DefaultMathTransformFactory extends AbstractFactory implements
Math
     private final AtomicReference<Parser> parser;
 
     /**
+     * The factory with opposite caching factory, or {@code null} if not yet created.
+     *
+     * @see #caching(boolean)
+     */
+    private DefaultMathTransformFactory oppositeCachingPolicy;
+
+    /**
      * Creates a new factory which will discover operation methods with a {@link ServiceLoader}.
      * The {@link OperationMethod} implementations shall be listed in the following file:
      *
@@ -313,6 +321,74 @@ public class DefaultMathTransformFactory extends AbstractFactory implements
Math
     }
 
     /**
+     * Creates a new factory with the same configuration than given factory but without caching.
+     */
+    private DefaultMathTransformFactory(final DefaultMathTransformFactory parent) {
+        methods       = parent.methods;
+        methodsByName = parent.methodsByName;
+        methodsByType = parent.methodsByType;
+        lastMethod    = new ThreadLocal<>();
+        pool          = null;
+        parser        = parent.parser;
+        oppositeCachingPolicy = parent;
+    }
+
+    /**
+     * Returns a factory for the same transforms than this factory, but with caching potentially
disabled.
+     * By default, {@code DefaultMathTransformFactory} caches the {@link MathTransform} instances
for sharing
+     * existing instances when transforms are created many times with the same set of parameters.
+     * However this caching may be unnecessarily costly when the transforms to create are
known to be short lived.
+     * This method allows to get a factory better suited for short-lived objects.
+     *
+     * <p>This method does not modify the state of this factory. Instead different
factory instances for the
+     * different caching policy are returned.</p>
+     *
+     * @param  enabled  whether caching should be enabled.
+     * @return a factory for the given caching policy.
+     *
+     * @since 1.1
+     */
+    public DefaultMathTransformFactory caching(final boolean enabled) {
+        if (enabled) {
+            return this;
+        }
+        synchronized (this) {
+            if (oppositeCachingPolicy == null) {
+                oppositeCachingPolicy = new NoCache(this);
+            }
+            return oppositeCachingPolicy;
+        }
+    }
+
+    /**
+     * Accessor for {@link NoCache} implementation.
+     */
+    final DefaultMathTransformFactory oppositeCachingPolicy() {
+        return oppositeCachingPolicy;
+    }
+
+    /**
+     * A factory performing no caching.
+     * This factory shares the same operation methods than the parent factory.
+     */
+    private static final class NoCache extends DefaultMathTransformFactory {
+        /** Creates a new factory with the same configuration than given factory. */
+        NoCache(final DefaultMathTransformFactory parent) {
+            super(parent);
+        }
+
+        /** Returns a factory for the same transforms but given caching policy. */
+        @Override public DefaultMathTransformFactory caching(final boolean enabled) {
+            return enabled ? oppositeCachingPolicy() : this;
+        }
+
+        /** Notifies parent factory that the set of operation methods may have changed. */
+        @Override public void reload() {
+            oppositeCachingPolicy().reload();
+        }
+    }
+
+    /**
      * Returns a set of available methods for coordinate operations of the given type.
      * The {@code type} argument can be used for filtering the kind of operations described
by the returned
      * {@code OperationMethod}s. The argument is usually (but not restricted to) one of the
following types:
@@ -1417,7 +1493,7 @@ public class DefaultMathTransformFactory extends AbstractFactory implements
Math
      * Replaces the given transform by a unique instance, if one already exists.
      */
     private MathTransform unique(final MathTransform tr) {
-        return pool.unique(tr);
+        return (pool != null) ? pool.unique(tr) : tr;
     }
 
     /**
@@ -1467,7 +1543,9 @@ public class DefaultMathTransformFactory extends AbstractFactory implements
Math
                     c.reset();
                 }
             }
-            pool.clear();
+            if (pool != null) {
+                pool.clear();
+            }
         }
     }
 }
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactoryTest.java
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactoryTest.java
index cc4ab05..6d5092b 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactoryTest.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactoryTest.java
@@ -279,4 +279,19 @@ public final strictfp class DefaultMathTransformFactoryTest extends TestCase
{
             assertEquals(classification, projection.getMethod().getName().getCode());
         }
     }
+
+    /**
+     * Tests {@link DefaultMathTransformFactory#caching(boolean)}.
+     */
+    @Test
+    public void testCaching() {
+        final DefaultMathTransformFactory mtFactory = DefaultFactories.forBuildin(
+                    MathTransformFactory.class, DefaultMathTransformFactory.class);
+        final DefaultMathTransformFactory caching = mtFactory.caching(false);
+
+        assertNotSame(mtFactory, caching);
+        assertSame   (mtFactory, mtFactory.caching(true));
+        assertSame   (mtFactory,   caching.caching(true));
+        assertSame   (caching,     caching.caching(false));
+    }
 }


Mime
View raw message