Author: desruisseaux
Date: Sun Feb  8 14:35:52 2015
New Revision: 1658178

URL: http://svn.apache.org/r1658178
Log:
Explain a design choice about OperationMethodSet.contains(Object).

Modified:
    
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/OperationMethodSet.java

Modified: 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/OperationMethodSet.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/OperationMethodSet.java?rev=1658178&r1=1658177&r2=1658178&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/OperationMethodSet.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/OperationMethodSet.java
 [UTF-8] Sun Feb  8 14:35:52 2015
@@ -114,6 +114,7 @@ final class OperationMethodSet extends A
                 methodIterator = null;
             }
         }
+        // Maintenance note: following check shall be consistent with the one 
in 'contains(Object)'.
         if (method instanceof DefaultOperationMethod) {
             if (!type.isAssignableFrom(((DefaultOperationMethod) 
method).getOperationType())) {
                 return false;
@@ -206,4 +207,47 @@ final class OperationMethodSet extends A
             }
         };
     }
+
+    /**
+     * Returns {@code true} if this set contains the given object.
+     * This implementation overrides the default one with a quick check 
allowing us to filter
+     * {@code OperationMethod} instances of the wrong type before to iterate 
over the elements.
+     */
+    @Override
+    public boolean contains(final Object object) {
+        // Maintenance note: following check shall be consistent with the one 
in 'transfer()'.
+        if (object instanceof DefaultOperationMethod) {
+            if (!type.isAssignableFrom(((DefaultOperationMethod) 
object).getOperationType())) {
+                return false;
+            }
+        } else if (!(object instanceof OperationMethod)) {
+            return false;
+        }
+        /*
+         * NOTE: we could optimize this method here with the following code, 
which would be
+         * much more efficient than the default implementation if 'methods' is 
a HashSet:
+         *
+         *   if (methods instanceof Collection<?>) {
+         *       synchronized (methods) {
+         *           return ((Collection<?>) methods).contains(object);
+         *       }
+         *   }
+         *
+         * However we don't do that because it would bring 2 issues:
+         *
+         *   1) There is no guarantee that implementation of the 'methods' 
collection uses the 'equals(Object)'
+         *      method. For example TreeSet rather uses 'compareTo(Object)'. 
Since the OperationMethodSet class
+         *      uses 'equals', there is a risk of inconsistency.
+         *
+         *   2) The 'synchronized (methods)' statement introduces a risk of 
deadlock if some implementations of
+         *      'OperationMethod.equals(Object)' invokes 
DefaultMathTransformFactory methods. Of course no such
+         *      callbacks should exist (and Apache SIS don't do that), but the 
OperationMethods can be supplied
+         *      by users and Murphy's law said that if something can go wrong, 
it will go wrong.
+         *
+         * Since there is no evidence at this time that we need an efficient 
OperationMethodSet.contains(Object)
+         * implementation, we keep for now the slowest but more conservative 
approach inherited from AbstractSet.
+         * However this choice may be revisited in any future SIS version if 
necessary.
+         */
+        return super.contains(object);
+    }
 }


Reply via email to