sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1740276 - in /sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation: CRSPair.java CoordinateOperationFinder.java DefaultCoordinateOperationFactory.java
Date Thu, 21 Apr 2016 10:23:50 GMT
Author: desruisseaux
Date: Thu Apr 21 10:23:50 2016
New Revision: 1740276

URL: http://svn.apache.org/viewvc?rev=1740276&view=rev
Log:
Add limited caching in CoordinateOperationFactory.

Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CRSPair.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CRSPair.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CRSPair.java?rev=1740276&r1=1740275&r2=1740276&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CRSPair.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CRSPair.java
[UTF-8] Thu Apr 21 10:23:50 2016
@@ -59,7 +59,7 @@ final class CRSPair {
      */
     @Override
     public int hashCode() {
-        return sourceCRS.hashCode() * 31 + targetCRS.hashCode();
+        return Objects.hashCode(sourceCRS) * 31 + Objects.hashCode(targetCRS);
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java?rev=1740276&r1=1740275&r2=1740276&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
[UTF-8] Thu Apr 21 10:23:50 2016
@@ -146,6 +146,11 @@ public class CoordinateOperationFinder e
     private final Map<CRSPair,Boolean> previousSearches;
 
     /**
+     * Whether this finder instance is allowed to use {@link DefaultCoordinateOperationFactory#cache}.
+     */
+    private final boolean useCache;
+
+    /**
      * Creates a new instance for the given factory and context.
      *
      * @param  registry  the factory to use for creating operations as defined by authority,
or {@code null} if none.
@@ -160,6 +165,7 @@ public class CoordinateOperationFinder e
         super(registry, factory, context);
         identifierOfStepCRS = new HashMap<>(8);
         previousSearches    = new HashMap<>(8);
+        useCache = (context == null) && (factory == factorySIS);
     }
 
     /**
@@ -190,13 +196,31 @@ public class CoordinateOperationFinder e
     {
         ArgumentChecks.ensureNonNull("sourceCRS", sourceCRS);
         ArgumentChecks.ensureNonNull("targetCRS", targetCRS);
-        if (!previousSearches.isEmpty()) {
-            // TODO: verify here if the path is defined in EPSG database.
+        if (equalsIgnoreMetadata(sourceCRS, targetCRS)) try {
+            return createFromAffineTransform(AXIS_CHANGES, sourceCRS, targetCRS,
+                    CoordinateSystems.swapAndScaleAxes(sourceCRS.getCoordinateSystem(), targetCRS.getCoordinateSystem()));
+        } catch (IllegalArgumentException | ConversionException e) {
+            throw new FactoryException(Errors.format(Errors.Keys.CanNotInstantiate_1, new
CRSPair(sourceCRS, targetCRS)), e);
         }
+        /*
+         * If this method is invoked recursively, verify if the requested operation is already
in the cache.
+         * We do not perform this verification on the first invocation because it was already
verified by
+         * DefaultCoordinateOperationFactory.createOperation(…). We do not block if the
operation is in
+         * process of being computed in another thread because of the risk of deadlock. If
the operation
+         * is not in the cache, store the keys in our internal map for preventing infinite
recursivity.
+         */
         final CRSPair key = new CRSPair(sourceCRS, targetCRS);
+        if (useCache && !previousSearches.isEmpty()) {
+            final CoordinateOperation op = factorySIS.cache.peek(key);
+            if (op != null) return op;
+        }
         if (previousSearches.put(key, Boolean.TRUE) != null) {
             throw new FactoryException(Errors.format(Errors.Keys.RecursiveCreateCallForCode_2,
CoordinateOperation.class, key));
         }
+        /*
+         * If the user did not specified an area of interest, use the domain of validity
of the CRS.
+         * Then verify in the EPSG dataset if the operation is explicitely defined by an
authority.
+         */
         GeographicBoundingBox bbox = Extents.getGeographicBoundingBox(areaOfInterest);
         if (bbox == null) {
             bbox = Extents.intersection(CRS.getGeographicBoundingBox(sourceCRS),

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java?rev=1740276&r1=1740275&r2=1740276&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
[UTF-8] Thu Apr 21 10:23:50 2016
@@ -44,6 +44,7 @@ import org.apache.sis.referencing.factor
 import org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory;
 import org.apache.sis.util.collection.WeakHashSet;
 import org.apache.sis.util.collection.Containers;
+import org.apache.sis.util.collection.Cache;
 import org.apache.sis.util.iso.AbstractFactory;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.ArgumentChecks;
@@ -121,10 +122,21 @@ public class DefaultCoordinateOperationF
     /**
      * Weak references to existing objects.
      * This set is used in order to return a pre-existing object instead of creating a new
one.
+     * This apply to object created explicitly, not to coordinate operations inferred by
a call
+     * to {@link #createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem)}.
      */
     private final WeakHashSet<IdentifiedObject> pool;
 
     /**
+     * The cache of coordinate operations found for a given pair of source and target CRS.
+     * If current implementation, we cache only operations found without context (otherwise
+     * we would need to take in account the area of interest and desired accuracy in the
key).
+     *
+     * @see #createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, CoordinateOperationContext)
+     */
+    final Cache<CRSPair,CoordinateOperation> cache;
+
+    /**
      * Constructs a factory with no default properties.
      */
     public DefaultCoordinateOperationFactory() {
@@ -167,6 +179,7 @@ public class DefaultCoordinateOperationF
             mtFactory = factory;
         }
         pool = new WeakHashSet<>(IdentifiedObject.class);
+        cache = new Cache<>(12, 50, true);
     }
 
     /**
@@ -699,9 +712,32 @@ next:   for (int i=components.size(); --
                                                final CoordinateOperationContext context)
             throws OperationNotFoundException, FactoryException
     {
-        final AuthorityFactory registry = USE_EPSG_FACTORY ? CRS.getAuthorityFactory(Constants.EPSG)
: null;
-        return new CoordinateOperationFinder((registry instanceof CoordinateOperationAuthorityFactory)
?
-                (CoordinateOperationAuthorityFactory) registry : null, this, context).createOperation(sourceCRS,
targetCRS);
+        final Cache.Handler<CoordinateOperation> handler;
+        CoordinateOperation op;
+        if (context == null) {
+            final CRSPair key = new CRSPair(sourceCRS, targetCRS);
+            op = cache.peek(key);
+            if (op != null) {
+                return op;
+            }
+            handler = cache.lock(key);
+        } else {
+            // We currently do not cache the operation when the result may depend on the
context (see 'this.cache' javadoc).
+            handler = null;
+            op = null;
+        }
+        try {
+            if (handler == null || (op = handler.peek()) == null) {
+                final AuthorityFactory registry = USE_EPSG_FACTORY ? CRS.getAuthorityFactory(Constants.EPSG)
: null;
+                op = new CoordinateOperationFinder((registry instanceof CoordinateOperationAuthorityFactory)
?
+                        (CoordinateOperationAuthorityFactory) registry : null, this, context).createOperation(sourceCRS,
targetCRS);
+            }
+        } finally {
+            if (handler != null) {
+                handler.putAndUnlock(op);
+            }
+        }
+        return op;
     }
 
     /**



Mime
View raw message