You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2017/04/10 10:49:21 UTC
svn commit: r1790801 - in /sis/trunk: ./
core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/
core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/
core/sis-referencing/src/main/resources/META-IN...
Author: desruisseaux
Date: Mon Apr 10 10:49:21 2017
New Revision: 1790801
URL: http://svn.apache.org/viewvc?rev=1790801&view=rev
Log:
Merge the new operation methods and the Quantity implementation from JDK7 branch.
Added:
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AxisOrderReversal.java
- copied unchanged from r1790799, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AxisOrderReversal.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AxisOrderReversal3D.java
- copied unchanged from r1790799, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/AxisOrderReversal3D.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicAndVerticalOffsets.java
- copied unchanged from r1790799, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicAndVerticalOffsets.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Quantities.java
- copied unchanged from r1790799, sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/Quantities.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Scalar.java
- copied unchanged from r1790799, sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/Scalar.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/ScalarFactory.java
- copied unchanged from r1790799, sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/ScalarFactory.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/ScalarFallback.java
- copied unchanged from r1790799, sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/measure/ScalarFallback.java
sis/trunk/core/sis-utility/src/test/java/org/apache/sis/measure/QuantitiesTest.java
- copied unchanged from r1790799, sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/measure/QuantitiesTest.java
sis/trunk/core/sis-utility/src/test/java/org/apache/sis/measure/ScalarTest.java
- copied unchanged from r1790799, sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/measure/ScalarTest.java
Modified:
sis/trunk/ (props changed)
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicOffsets.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CopyTransform.java
sis/trunk/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod
sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/ProvidersTest.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractConverter.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractUnit.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/LinearConverter.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/SystemUnit.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/UnitServices.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/package-info.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/FrequencySortedSet.java
sis/trunk/core/sis-utility/src/test/java/org/apache/sis/measure/SystemUnitTest.java
sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
sis/trunk/core/sis-utility/src/test/java/org/apache/sis/util/collection/FrequencySortedSetTest.java
sis/trunk/pom.xml
Propchange: sis/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Apr 10 10:49:21 2017
@@ -1,5 +1,5 @@
/sis/branches/Android:1430670-1480699
/sis/branches/JDK6:1394364-1758914
-/sis/branches/JDK7:1394913-1790136
-/sis/branches/JDK8:1584960-1790133
+/sis/branches/JDK7:1394913-1790799
+/sis/branches/JDK8:1584960-1790797
/sis/branches/JDK9:1773327-1789983
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicOffsets.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicOffsets.java?rev=1790801&r1=1790800&r2=1790801&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicOffsets.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicOffsets.java [UTF-8] Mon Apr 10 10:49:21 2017
@@ -87,7 +87,7 @@ public class GeographicOffsets extends G
}
/**
- * For subclasses constructor only.
+ * For default constructors in this class and subclasses.
*/
GeographicOffsets(int sourceDimensions, int targetDimensions,
ParameterDescriptorGroup parameters, GeodeticOperation[] redimensioned)
@@ -96,6 +96,13 @@ public class GeographicOffsets extends G
}
/**
+ * Returns the parameter descriptor for the vertical axis.
+ */
+ ParameterDescriptor<Double> vertical() {
+ return TZ;
+ }
+
+ /**
* Creates a transform from the specified group of parameter values.
* The parameter values are unconditionally converted to degrees and metres.
*
@@ -112,7 +119,7 @@ public class GeographicOffsets extends G
final Matrix4 t = new Matrix4();
t.m03 = pv.doubleValue(TX);
t.m13 = pv.doubleValue(TY);
- t.m23 = pv.doubleValue(TZ);
+ t.m23 = pv.doubleValue(vertical());
return MathTransforms.linear(t);
}
}
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CopyTransform.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CopyTransform.java?rev=1790801&r1=1790800&r2=1790801&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CopyTransform.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CopyTransform.java [UTF-8] Mon Apr 10 10:49:21 2017
@@ -329,7 +329,7 @@ final class CopyTransform extends Abstra
* Creates the inverse transform of this object.
*/
@Override
- @SuppressWarnings("DoubleCheckedLocking") // Okay since 'inverse' is volatile.
+ @SuppressWarnings("DoubleCheckedLocking") // Okay since 'inverse' is volatile.
public LinearTransform inverse() throws NoninvertibleTransformException {
LinearTransform inv = inverse;
if (inv == null) {
@@ -379,8 +379,8 @@ final class CopyTransform extends Abstra
}
/*
* At this point, we know that we can create the inverse transform.
- * If this transform is the identity transform (we should never happen,
- * but we are paranoiac), then the old and new arrays would be equal.
+ * If this transform is the identity transform or an anti-diagonal matrix except last row
+ * (e.g. matrix used for swapping axis order), then the old and new arrays would be equal.
*/
CopyTransform copyInverse = this;
if (!Arrays.equals(reverse, indices)) {
Modified: sis/trunk/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod?rev=1790801&r1=1790800&r2=1790801&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod [UTF-8] Mon Apr 10 10:49:21 2017
@@ -1,10 +1,13 @@
# Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.
# Heavier classes (e.g. having more dependencies) or classes less likely to be used, should be last.
org.apache.sis.internal.referencing.provider.Affine
+org.apache.sis.internal.referencing.provider.AxisOrderReversal
+org.apache.sis.internal.referencing.provider.AxisOrderReversal3D
org.apache.sis.internal.referencing.provider.Geographic3Dto2D
org.apache.sis.internal.referencing.provider.Geographic2Dto3D
org.apache.sis.internal.referencing.provider.GeographicOffsets
org.apache.sis.internal.referencing.provider.GeographicOffsets2D
+org.apache.sis.internal.referencing.provider.GeographicAndVerticalOffsets
org.apache.sis.internal.referencing.provider.VerticalOffset
org.apache.sis.internal.referencing.provider.LongitudeRotation
org.apache.sis.internal.referencing.provider.GeocentricTranslation
Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/ProvidersTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/ProvidersTest.java?rev=1790801&r1=1790800&r2=1790801&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/ProvidersTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/ProvidersTest.java [UTF-8] Mon Apr 10 10:49:21 2017
@@ -53,8 +53,11 @@ public final strictfp class ProvidersTes
private static Class<?>[] methods() {
return new Class<?>[] {
Affine.class,
+ AxisOrderReversal.class,
+ AxisOrderReversal3D.class,
GeographicOffsets.class,
GeographicOffsets2D.class,
+ GeographicAndVerticalOffsets.class,
VerticalOffset.class,
LongitudeRotation.class,
CoordinateFrameRotation.class,
@@ -114,6 +117,7 @@ public final strictfp class ProvidersTes
LongitudeRotation.class,
GeographicOffsets.class,
GeographicOffsets2D.class,
+ GeographicAndVerticalOffsets.class,
CoordinateFrameRotation2D.class,
CoordinateFrameRotation3D.class,
PositionVector7Param2D.class,
Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractConverter.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractConverter.java?rev=1790801&r1=1790800&r2=1790801&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractConverter.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractConverter.java [UTF-8] Mon Apr 10 10:49:21 2017
@@ -18,6 +18,7 @@ package org.apache.sis.measure;
import java.io.Serializable;
import javax.measure.UnitConverter;
+import org.apache.sis.math.DecimalFunctions;
/**
@@ -67,4 +68,12 @@ abstract class AbstractConverter impleme
}
return Double.NaN;
}
+
+ /**
+ * Returns the value of the given number, with special handling for {@link Float} value on the assumption
+ * that the original value was written in base 10. This is usually the case for unit conversion factors.
+ */
+ static double doubleValue(final Number n) {
+ return (n instanceof Float) ? DecimalFunctions.floatToDouble(n.floatValue()) : n.doubleValue();
+ }
}
Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractUnit.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractUnit.java?rev=1790801&r1=1790800&r2=1790801&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractUnit.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractUnit.java [UTF-8] Mon Apr 10 10:49:21 2017
@@ -93,13 +93,25 @@ abstract class AbstractUnit<Q extends Qu
*
* <p>This information may be approximative since we can not always guess correctly whether the result of
* an operation is part of SI or not. Values given to the field may be adjusted in any future version.</p>
+ *
+ * <p>This information is not serialized because {@link #readResolve()} will replace the deserialized instance
+ * by a hard-coded instance with appropriate value, if possible.</p>
+ *
+ * @see #equals(short, short)
*/
- final byte scope;
+ final transient byte scope;
/**
* The EPSG code, or 0 if this unit has no EPSG code.
+ *
+ * <p>This information is not serialized because {@link #readResolve()} will replace the deserialized instance
+ * by a hard-coded instance with appropriate value, if possible. Note that EPSG codes are not included in the
+ * {@code sis-uom} module (a module containing a subset of {@code sis-utility} module), so we need to ignore
+ * this field at serialization time if we want compatible serialization forms.</p>
+ *
+ * @see #equals(short, short)
*/
- final short epsg;
+ final transient short epsg;
/**
* Creates a new unit having the given symbol and EPSG code.
@@ -294,7 +306,18 @@ abstract class AbstractUnit<Q extends Qu
return true;
}
final AbstractUnit<?> that = (AbstractUnit<?>) other;
- return epsg == that.epsg && scope == that.scope && Objects.equals(symbol, that.symbol);
+ return equals(epsg, that.epsg) && equals(scope, that.scope) && Objects.equals(symbol, that.symbol);
+ }
+
+ /**
+ * Compares the given values only if both of them are non-zero. If at least one value is zero (meaning "unknown"),
+ * assume that values are equal. We do that because deserialized {@code AbstractUnit} instances have {@link #epsg}
+ * and {@link #scope} fields initialized to 0, and we need to ignore those values when comparing the deserialized
+ * instances with instances hard-coded in {@link Units} class. We should not have inconsistencies because there is
+ * no public way to set those fields; they can only be defined in the {@code Units} hard-coded constants.
+ */
+ private static boolean equals(final short a, final short b) {
+ return (a == 0) || (b == 0) || (a == b);
}
/**
@@ -302,7 +325,8 @@ abstract class AbstractUnit<Q extends Qu
*/
@Override
public int hashCode() {
- return epsg + 31 * Objects.hashCode(symbol);
+ // Do not use EPSG code or scope because they are not serialized.
+ return 31 * Objects.hashCode(symbol);
}
/**
Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/LinearConverter.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/LinearConverter.java?rev=1790801&r1=1790800&r2=1790801&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/LinearConverter.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/LinearConverter.java [UTF-8] Mon Apr 10 10:49:21 2017
@@ -27,7 +27,6 @@ import org.apache.sis.util.ArgumentCheck
import org.apache.sis.util.StringBuilders;
import org.apache.sis.util.ComparisonMode;
import org.apache.sis.util.LenientComparable;
-import org.apache.sis.math.DecimalFunctions;
import org.apache.sis.math.MathFunctions;
import org.apache.sis.math.Fraction;
import org.apache.sis.internal.util.Numerics;
@@ -333,14 +332,7 @@ final class LinearConverter extends Abst
}
value = ((BigDecimal) value).multiply(scale10).add(offset10);
} else {
- final double x;
- if (value instanceof Float) {
- // Because unit conversion factors are usually defined in base 10.
- x = DecimalFunctions.floatToDouble((Float) value);
- } else {
- x = value.doubleValue();
- }
- value = convert(x);
+ value = convert(doubleValue(value));
}
}
return value;
Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/SystemUnit.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/SystemUnit.java?rev=1790801&r1=1790800&r2=1790801&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/SystemUnit.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/SystemUnit.java [UTF-8] Mon Apr 10 10:49:21 2017
@@ -26,6 +26,7 @@ import javax.measure.Dimension;
import javax.measure.UnitConverter;
import javax.measure.UnconvertibleException;
import javax.measure.IncommensurableException;
+import javax.measure.spi.QuantityFactory;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.ObjectConverters;
import org.apache.sis.util.ComparisonMode;
@@ -48,7 +49,7 @@ import org.apache.sis.math.Fraction;
* @since 0.8
* @module
*/
-final class SystemUnit<Q extends Quantity<Q>> extends AbstractUnit<Q> {
+final class SystemUnit<Q extends Quantity<Q>> extends AbstractUnit<Q> implements QuantityFactory<Q> {
/**
* For cross-version compatibility.
*/
@@ -65,6 +66,13 @@ final class SystemUnit<Q extends Quantit
final UnitDimension dimension;
/**
+ * The factory to use for creating quantities, or {@code null} if none.
+ * This field does not need to be serialized because {@link AbstractUnit#readResolve()}
+ * replaces deserialized instances by corresponding {@link Units} hard-coded instances.
+ */
+ final transient ScalarFactory<Q> factory;
+
+ /**
* Units for the same quantity but with scale factors that are not the SI one.
* This is initialized by {@link Units} only and shall not change anymore after.
* All units in this array shall use an instance of {@link LinearConverter}.
@@ -81,11 +89,15 @@ final class SystemUnit<Q extends Quantit
* @param symbol the unit symbol, or {@code null} if this unit has no specific symbol.
* @param scope {@link UnitRegistry#SI}, {@link UnitRegistry#ACCEPTED}, other constants or 0 if unknown.
* @param epsg the EPSG code, or 0 if this unit has no EPSG code.
+ * @param factory the factory to use for creating quantities, or {@code null} if none.
*/
- SystemUnit(final Class<Q> quantity, final UnitDimension dimension, final String symbol, final byte scope, final short epsg) {
+ SystemUnit(final Class<Q> quantity, final UnitDimension dimension, final String symbol,
+ final byte scope, final short epsg, final ScalarFactory<Q> factory)
+ {
super(symbol, scope, epsg);
this.quantity = quantity;
this.dimension = dimension;
+ this.factory = factory;
}
/**
@@ -99,7 +111,7 @@ final class SystemUnit<Q extends Quantit
}
SystemUnit<?> result = Units.get(dim);
if (result == null) {
- result = new SystemUnit(null, dim, null, (byte) 0, (short) 0);
+ result = new SystemUnit(null, dim, null, (byte) 0, (short) 0, null);
}
return result;
}
@@ -241,7 +253,7 @@ final class SystemUnit<Q extends Quantit
*/
SystemUnit<T> unit = Units.get(type);
if (unit == null) {
- unit = new SystemUnit<>(type, dimension, null, (byte) 0, (short) 0); // Intentionally no symbol.
+ unit = new SystemUnit<>(type, dimension, null, (byte) 0, (short) 0, null); // Intentionally no symbol.
}
if (!dimension.equals(unit.dimension)) {
throw new ClassCastException(Errors.format(Errors.Keys.IncompatibleUnitDimension_5, new Object[] {
@@ -358,7 +370,7 @@ final class SystemUnit<Q extends Quantit
if (symbol.equals(getSymbol())) {
return this;
}
- final SystemUnit<Q> alt = new SystemUnit<>(quantity, dimension, symbol, (byte) 0, (short) 0);
+ final SystemUnit<Q> alt = new SystemUnit<>(quantity, dimension, symbol, (byte) 0, (short) 0, factory);
if (quantity != null) {
/*
* Use the cache only if this unit has a non-null quantity type. Do not use the cache even
@@ -509,4 +521,17 @@ final class SystemUnit<Q extends Quantit
public int hashCode() {
return super.hashCode() + 37 * dimension.hashCode();
}
+
+ /**
+ * Creates a quantity for the given value and unit of measurement.
+ */
+ @Override
+ public Quantity<Q> create(final Number value, final Unit<Q> unit) {
+ final double v = AbstractConverter.doubleValue(value);
+ if (factory != null) {
+ return factory.create(v, unit);
+ } else {
+ return ScalarFallback.factory(v, unit, quantity);
+ }
+ }
}
Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/UnitServices.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/UnitServices.java?rev=1790801&r1=1790800&r2=1790801&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/UnitServices.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/UnitServices.java [UTF-8] Mon Apr 10 10:49:21 2017
@@ -20,6 +20,7 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
+import javax.measure.Unit;
import javax.measure.Quantity;
import javax.measure.format.UnitFormat;
import javax.measure.spi.QuantityFactory;
@@ -220,15 +221,31 @@ public class UnitServices extends Servic
}
/**
- * Return a factory for the given {@code Quantity} type, or {@code null} if none.
- * Current implementation returns {@code null}.
+ * Return a factory for the given {@code Quantity} type. In the particular case of Apache SIS implementation,
+ * {@link Quantities#create(double, Unit)} provides a more direct way to instantiate quantities.
*
* @param <Q> compile-time value of the {@code type} argument.
* @param type type of the desired the quantity.
* @return the service to obtain {@link Quantity} instances, or {@code null} if none.
+ *
+ * @see Quantities#create(double, Unit)
*/
@Override
public <Q extends Quantity<Q>> QuantityFactory<Q> getQuantityFactory(final Class<Q> type) {
- return null;
+ QuantityFactory<Q> factory = Units.get(type);
+ if (factory == null) {
+ factory = new QuantityFactory<Q>() {
+ @Override
+ public Quantity<Q> create(final Number value, final Unit<Q> unit) {
+ return ScalarFallback.factory(AbstractConverter.doubleValue(value), unit, type);
+ }
+
+ @Override
+ public Unit<Q> getSystemUnit() {
+ return null;
+ }
+ };
+ }
+ return factory;
}
}
Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java?rev=1790801&r1=1790800&r2=1790801&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java [UTF-8] Mon Apr 10 10:49:21 2017
@@ -1060,15 +1060,17 @@ public final class Units extends Static
final UnitDimension dimensionless = UnitDimension.NONE;
/*
* Base, derived or alternate units that we need to reuse more than once in this static initializer.
+ * Note: JDK8 branch uses much more compact method references instead than following inner classes.
*/
- final SystemUnit<Length> m = add(Length.class, length, "m", UnitRegistry.SI, Constants.EPSG_METRE);
- final SystemUnit<Area> m2 = add(Area.class, area, "m�", UnitRegistry.SI, (short) 0);
- final SystemUnit<Time> s = add(Time.class, time, "s", UnitRegistry.SI, (short) 1040);
- final SystemUnit<Temperature> K = add(Temperature.class, temperature, "\u212a", UnitRegistry.SI, (short) 0);
- final SystemUnit<Speed> mps = add(Speed.class, speed, "m\u2215s", UnitRegistry.SI, (short) 1026);
- final SystemUnit<Pressure> Pa = add(Pressure.class, pressure, "Pa", UnitRegistry.SI, (short) 0);
- final SystemUnit<Angle> rad = add(Angle.class, dimensionless, "rad", UnitRegistry.SI, (short) 9101);
- final SystemUnit<Dimensionless> one = add(Dimensionless.class, dimensionless, "", UnitRegistry.SI, (short) 9201);
+ ScalarFactory<Dimensionless> dimensionlessFactory = new ScalarFactory<Dimensionless>() {@Override public Dimensionless create(double value, Unit<Dimensionless> unit) {return new Scalar.Dimensionless(value, unit);}};
+ final SystemUnit<Length> m = add(Length.class, new ScalarFactory<Length> () {@Override public Length create(double value, Unit<Length> unit) {return new Scalar.Length (value, unit);}}, length, "m", UnitRegistry.SI, Constants.EPSG_METRE);
+ final SystemUnit<Area> m2 = add(Area.class, new ScalarFactory<Area> () {@Override public Area create(double value, Unit<Area> unit) {return new Scalar.Area (value, unit);}}, area, "m�", UnitRegistry.SI, (short) 0);
+ final SystemUnit<Time> s = add(Time.class, new ScalarFactory<Time> () {@Override public Time create(double value, Unit<Time> unit) {return new Scalar.Time (value, unit);}}, time, "s", UnitRegistry.SI, (short) 1040);
+ final SystemUnit<Temperature> K = add(Temperature.class, new ScalarFactory<Temperature> () {@Override public Temperature create(double value, Unit<Temperature> unit) {return new Scalar.Temperature (value, unit);}}, temperature, "\u212a", UnitRegistry.SI, (short) 0);
+ final SystemUnit<Speed> mps = add(Speed.class, new ScalarFactory<Speed> () {@Override public Speed create(double value, Unit<Speed> unit) {return new Scalar.Speed (value, unit);}}, speed, "m\u2215s", UnitRegistry.SI, (short) 1026);
+ final SystemUnit<Pressure> Pa = add(Pressure.class, new ScalarFactory<Pressure> () {@Override public Pressure create(double value, Unit<Pressure> unit) {return new Scalar.Pressure (value, unit);}}, pressure, "Pa", UnitRegistry.SI, (short) 0);
+ final SystemUnit<Angle> rad = add(Angle.class, new ScalarFactory<Angle> () {@Override public Angle create(double value, Unit<Angle> unit) {return new Scalar.Angle (value, unit);}}, dimensionless, "rad", UnitRegistry.SI, (short) 9101);
+ final SystemUnit<Dimensionless> one = add(Dimensionless.class, dimensionlessFactory, dimensionless, "", UnitRegistry.SI, (short) 9201);
/*
* All SI prefix to be used below, with additional converters to be used more than once.
*/
@@ -1144,39 +1146,41 @@ public final class Units extends Static
/*
* Electricity and magnetism.
*/
- AMPERE = add(ElectricCurrent.class, current, "A", UnitRegistry.SI, (short) 0);
- COULOMB = add(ElectricCharge.class, charge, "C", UnitRegistry.SI, (short) 0);
- VOLT = add(ElectricPotential.class, potential, "V", UnitRegistry.SI, (short) 0);
- FARAD = add(ElectricCapacitance.class, charge.divide(potential), "F", UnitRegistry.SI, (short) 0);
- SIEMENS = add(ElectricConductance.class, current.divide(potential), "S", UnitRegistry.SI, (short) 0);
- OHM = add(ElectricResistance.class, potential.divide(current), "\u03a9", UnitRegistry.SI, (short) 0);
- WEBER = add(MagneticFlux.class, magneticFlux, "Wb", UnitRegistry.SI, (short) 0);
- TESLA = add(MagneticFluxDensity.class, magneticFlux.divide(area), "T", UnitRegistry.SI, (short) 0);
- HENRY = add(ElectricInductance.class, magneticFlux.divide(current), "H", UnitRegistry.SI, (short) 0);
+ AMPERE = add(ElectricCurrent.class, null, current, "A", UnitRegistry.SI, (short) 0);
+ COULOMB = add(ElectricCharge.class, null, charge, "C", UnitRegistry.SI, (short) 0);
+ VOLT = add(ElectricPotential.class, null, potential, "V", UnitRegistry.SI, (short) 0);
+ FARAD = add(ElectricCapacitance.class, null, charge.divide(potential), "F", UnitRegistry.SI, (short) 0);
+ SIEMENS = add(ElectricConductance.class, null, current.divide(potential), "S", UnitRegistry.SI, (short) 0);
+ OHM = add(ElectricResistance.class, null, potential.divide(current), "\u03a9", UnitRegistry.SI, (short) 0);
+ WEBER = add(MagneticFlux.class, null, magneticFlux, "Wb", UnitRegistry.SI, (short) 0);
+ TESLA = add(MagneticFluxDensity.class, null, magneticFlux.divide(area), "T", UnitRegistry.SI, (short) 0);
+ HENRY = add(ElectricInductance.class, null, magneticFlux.divide(current), "H", UnitRegistry.SI, (short) 0);
/*
* Other units.
+ * Note: JDK8 branch uses method references instead than inner classes.
*/
SQUARE_METRE = m2;
- HECTARE = add(m2, ten4, "ha", UnitRegistry.ACCEPTED, (short) 0);
- CUBIC_METRE = add(Volume.class, length.pow(3), "m�", UnitRegistry.SI, (short) 0);
- HERTZ = add(Frequency.class, time.pow(-1), "Hz", UnitRegistry.SI, (short) 0);
- KILOGRAM = add(Mass.class, mass, "kg", UnitRegistry.SI, (short) 0);
- NEWTON = add(Force.class, force, "N", UnitRegistry.SI, (short) 0);
- JOULE = add(Energy.class, energy, "J", UnitRegistry.SI, (short) 0);
- WATT = add(Power.class, power, "W", UnitRegistry.SI, (short) 0);
- LUX = add(Illuminance.class, luminous.divide(area), "lx", UnitRegistry.SI, (short) 0);
- LUMEN = add(LuminousFlux.class, luminous, "lm", UnitRegistry.SI, (short) 0);
- CANDELA = add(LuminousIntensity.class, luminous, "cd", UnitRegistry.SI, (short) 0); // Must be after Lumen.
- MOLE = add(AmountOfSubstance.class, amount, "mol", UnitRegistry.SI, (short) 0);
- STERADIAN = add(SolidAngle.class, dimensionless, "sr", UnitRegistry.SI, (short) 0);
+ HECTARE = add(m2, ten4, "ha", UnitRegistry.ACCEPTED, (short) 0);
+ CUBIC_METRE = add(Volume.class, new ScalarFactory<Volume> () {@Override public Volume create(double value, Unit<Volume> unit) {return new Scalar.Volume (value, unit);}}, length.pow(3), "m�", UnitRegistry.SI, (short) 0);
+ HERTZ = add(Frequency.class, new ScalarFactory<Frequency>() {@Override public Frequency create(double value, Unit<Frequency> unit) {return new Scalar.Frequency(value, unit);}}, time.pow(-1), "Hz", UnitRegistry.SI, (short) 0);
+ KILOGRAM = add(Mass.class, new ScalarFactory<Mass> () {@Override public Mass create(double value, Unit<Mass> unit) {return new Scalar.Mass (value, unit);}}, mass, "kg", UnitRegistry.SI, (short) 0);
+ NEWTON = add(Force.class, new ScalarFactory<Force> () {@Override public Force create(double value, Unit<Force> unit) {return new Scalar.Force (value, unit);}}, force, "N", UnitRegistry.SI, (short) 0);
+ JOULE = add(Energy.class, new ScalarFactory<Energy> () {@Override public Energy create(double value, Unit<Energy> unit) {return new Scalar.Energy (value, unit);}}, energy, "J", UnitRegistry.SI, (short) 0);
+ WATT = add(Power.class, new ScalarFactory<Power> () {@Override public Power create(double value, Unit<Power> unit) {return new Scalar.Power (value, unit);}}, power, "W", UnitRegistry.SI, (short) 0);
+ LUX = add(Illuminance.class, null, luminous.divide(area), "lx", UnitRegistry.SI, (short) 0);
+ LUMEN = add(LuminousFlux.class, null, luminous, "lm", UnitRegistry.SI, (short) 0);
+ CANDELA = add(LuminousIntensity.class, null, luminous, "cd", UnitRegistry.SI, (short) 0); // Must be after Lumen.
+ MOLE = add(AmountOfSubstance.class, null, amount, "mol", UnitRegistry.SI, (short) 0);
+ STERADIAN = add(SolidAngle.class, null, dimensionless, "sr", UnitRegistry.SI, (short) 0);
/*
* All Unit<Dimensionless>.
+ * Note: JDK8 branch uses method references instead than inner classes.
*/
- PERCENT = add(one, centi, "%", UnitRegistry.OTHER, (short) 0);
- PPM = add(one, micro, "ppm", UnitRegistry.OTHER, (short) 9202);
- PSU = add(Dimensionless.class, dimensionless, "psu", UnitRegistry.OTHER, (short) 0);
- SIGMA = add(Dimensionless.class, dimensionless, "sigma", UnitRegistry.OTHER, (short) 0);
- PIXEL = add(Dimensionless.class, dimensionless, "px", UnitRegistry.OTHER, (short) 0);
+ PERCENT = add(one, centi, "%", UnitRegistry.OTHER, (short) 0);
+ PPM = add(one, micro, "ppm", UnitRegistry.OTHER, (short) 9202);
+ PSU = add(Dimensionless.class, dimensionlessFactory, dimensionless, "psu", UnitRegistry.OTHER, (short) 0);
+ SIGMA = add(Dimensionless.class, dimensionlessFactory, dimensionless, "sigma", UnitRegistry.OTHER, (short) 0);
+ PIXEL = add(Dimensionless.class, dimensionlessFactory, dimensionless, "px", UnitRegistry.OTHER, (short) 0);
UNITY = UnitRegistry.init(one); // Must be last in order to take precedence over all other units associated to UnitDimension.NONE.
UnitRegistry.alias(UNITY, Short.valueOf((short) 9203));
@@ -1198,8 +1202,10 @@ public final class Units extends Static
* Invoked by {@code Units} static class initializer for registering SI base and derived units.
* This method shall be invoked in a single thread by the {@code Units} class initializer only.
*/
- private static <Q extends Quantity<Q>> SystemUnit<Q> add(Class<Q> quantity, UnitDimension dimension, String symbol, byte scope, short epsg) {
- return UnitRegistry.init(new SystemUnit<>(quantity, dimension, symbol, scope, epsg));
+ private static <Q extends Quantity<Q>> SystemUnit<Q> add(Class<Q> quantity, ScalarFactory<Q> factory,
+ UnitDimension dimension, String symbol, byte scope, short epsg)
+ {
+ return UnitRegistry.init(new SystemUnit<>(quantity, dimension, symbol, scope, epsg, factory));
}
/**
Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/package-info.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/package-info.java?rev=1790801&r1=1790800&r2=1790801&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/package-info.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/package-info.java [UTF-8] Mon Apr 10 10:49:21 2017
@@ -46,6 +46,8 @@
* In relation to units of measurement, this package also defines:
*
* <ul>
+ * <li>{@linkplain org.apache.sis.measure.Quantities}
+ * as a {@code double} value value associated to a {@code Unit} instance.</li>
* <li>{@link org.apache.sis.measure.Angle} and its subclasses
* ({@link org.apache.sis.measure.Longitude},
* {@link org.apache.sis.measure.Latitude},
@@ -54,9 +56,10 @@
* ({@link org.apache.sis.measure.NumberRange},
* {@link org.apache.sis.measure.MeasurementRange}) or annotation
* ({@link org.apache.sis.measure.ValueRange})</li>
- * <li>Formatters
+ * <li>Parsers and formatters
* ({@link org.apache.sis.measure.AngleFormat},
- * {@link org.apache.sis.measure.RangeFormat})</li>
+ * {@link org.apache.sis.measure.RangeFormat},
+ * {@link org.apache.sis.measure.UnitFormat})</li>
* </ul>
*
* @author Martin Desruisseaux (MPO, IRD, Geomatys)
Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/FrequencySortedSet.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/FrequencySortedSet.java?rev=1790801&r1=1790800&r2=1790801&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/FrequencySortedSet.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/collection/FrequencySortedSet.java [UTF-8] Mon Apr 10 10:49:21 2017
@@ -31,9 +31,9 @@ import org.apache.sis.util.ArgumentCheck
/**
* A set with elements ordered by the amount of time they were {@linkplain #add added}.
- * Less frequently added elements are first, and most frequently added ones are last.
- * If some elements were added the same amount of time, then the iterator will traverse
- * them in their insertion order.
+ * By default, less frequently added elements are first and most frequently added elements are last.
+ * If some elements were added the same amount of time, then the iterator will traverse them in their
+ * insertion order.
*
* <p>An optional boolean argument in the constructor allows the construction of set in reversed order
* (most frequently added elements first, less frequently added last). This is similar but not identical
@@ -46,7 +46,7 @@ import org.apache.sis.util.ArgumentCheck
* @author Martin Desruisseaux (Geomatys)
* @version 0.8
*
- * @param <E> the type of elements in the set.
+ * @param <E> the type of elements in the set.
*
* @since 0.8
* @module
@@ -64,8 +64,19 @@ public class FrequencySortedSet<E> exten
private final Map<E,Integer> count;
/**
- * {@code +1} if the element should be sorted in the usual order, or {@code -1}
+ * {@code 0} if the element should be sorted in the usual order, or {@code -1}
* if the elements should be sorted in reverse order (most frequent element first).
+ * This value is XORed with the number of times <var>n</var> that an element is added: {@code n ^ order}.
+ * The intend is to store negative numbers in the {@link #count} map if this {@code FrequencySortedSet}
+ * has been created for reverse order.
+ *
+ * <div class="note"><b>Implementation note:</b>
+ * we could have used {@code +1} and {@code -1} for the usual and reverse order respectively, and store the
+ * multiplication result {@code n * order} in the {@link #count} map. We rather use XOR for two reasons:
+ * first, XOR is a simpler operation for the CPU than multiplication. Second, XOR guarantees us that all
+ * negative numbers can be made positive in {@link #frequencies()}, by applying again {@code n ^ order}.
+ * By contrast, the multiplication approach (or just the {@code -n} negation) would fail to convert
+ * {@link Integer#MIN_VALUE}.</div>
*/
private final int order;
@@ -84,17 +95,19 @@ public class FrequencySortedSet<E> exten
* Creates an initially empty set with less frequent elements first.
*/
public FrequencySortedSet() {
- this(false);
+ count = new LinkedHashMap<>(); // Default constructor in JDK implementation applies lazy array allocation.
+ order = 0;
}
/**
* Creates an initially empty set with the default initial capacity.
*
* @param reversed {@code true} if the elements should be sorted in reverse order
- * (most frequent element first, less frequent last).
+ * (most frequent element first, less frequent element last).
*/
public FrequencySortedSet(final boolean reversed) {
- this(16, reversed);
+ count = new LinkedHashMap<>();
+ order = reversed ? -1 : 0;
}
/**
@@ -102,11 +115,11 @@ public class FrequencySortedSet<E> exten
*
* @param initialCapacity the initial capacity.
* @param reversed {@code true} if the elements should be sorted in reverse order
- * (most frequent element first, less frequent last).
+ * (most frequent element first, less frequent element last).
*/
public FrequencySortedSet(final int initialCapacity, final boolean reversed) {
count = new LinkedHashMap<>(initialCapacity);
- order = reversed ? -1 : +1;
+ order = reversed ? -1 : 0;
}
/**
@@ -126,11 +139,11 @@ public class FrequencySortedSet<E> exten
}
/**
- * Adds the specified element to this set. Returns {@code true} if this set changed as a result
- * of this operation. Changes in element order are not notified by the returned value.
+ * Repetitively adds the specified element to this set. Returns {@code true} if this set changed
+ * as a result of this operation. Changes in element order are not notified by the returned value.
*
- * @param element the element to add.
- * @param occurrence the number of time to add the given elements. The default value is 1.
+ * @param element the element to add (may be {@code null}).
+ * @param occurrence the number of time to add the given element. The default value is 1.
* @return {@code true} if this set changed as a result of this operation.
* @throws IllegalArgumentException if {@code occurrence} is negative.
*/
@@ -138,12 +151,12 @@ public class FrequencySortedSet<E> exten
if (occurrence != 0) {
ArgumentChecks.ensurePositive("occurrence", occurrence);
sorted = null;
- occurrence *= order;
- final Integer n = count.put(element, occurrence);
- if (n == null) {
+ occurrence ^= order;
+ final Integer old = count.put(element, occurrence);
+ if (old == null) {
return true;
}
- count.put(element, n + occurrence);
+ count.put(element, old + occurrence - order);
}
return false;
}
@@ -152,7 +165,9 @@ public class FrequencySortedSet<E> exten
* Adds the specified element to this set. Returns {@code true} if this set changed as a result
* of this operation. Changes in element order are not notified by the returned value.
*
- * @param element the element to add.
+ * <p>The default implementation delegates to <code>{@linkplain #add(Object, int) add}(element, 1)</code>.</p>
+ *
+ * @param element the element to add (may be {@code null}).
* @return {@code true} if this set changed as a result of this operation.
*/
@Override
@@ -204,7 +219,7 @@ public class FrequencySortedSet<E> exten
@Override
public Iterator<E> iterator() {
ensureSorted();
- return new Iter();
+ return new Iter(sorted, 0, sorted.length);
}
/**
@@ -218,6 +233,12 @@ public class FrequencySortedSet<E> exten
private final E[] elements;
/**
+ * Index of the first element ({@code lower}) and index after the last element ({@code upper})
+ * on which to iterate.
+ */
+ private final int lower, upper;
+
+ /**
* Index of the next element to return.
*/
private int index;
@@ -225,8 +246,11 @@ public class FrequencySortedSet<E> exten
/**
* Creates an new iterator.
*/
- Iter() {
+ Iter(final E[] sorted, final int lower, final int upper) {
elements = sorted;
+ this.index = lower;
+ this.lower = lower;
+ this.upper = upper;
}
/**
@@ -234,7 +258,7 @@ public class FrequencySortedSet<E> exten
*/
@Override
public boolean hasNext() {
- return index < elements.length;
+ return index < upper;
}
/**
@@ -242,10 +266,10 @@ public class FrequencySortedSet<E> exten
*/
@Override
public E next() {
- if (index >= elements.length) {
- throw new NoSuchElementException();
+ if (index < upper) {
+ return elements[index++];
}
- return elements[index++];
+ throw new NoSuchElementException();
}
/**
@@ -253,10 +277,7 @@ public class FrequencySortedSet<E> exten
*/
@Override
public void remove() {
- if (index == 0) {
- throw new IllegalStateException();
- }
- if (!FrequencySortedSet.this.remove(elements[index - 1])) {
+ if (index == lower || !FrequencySortedSet.this.remove(elements[index - 1])) {
// Could also be ConcurrentModificationException - we do not differentiate.
throw new IllegalStateException();
}
@@ -264,27 +285,213 @@ public class FrequencySortedSet<E> exten
}
/**
- * Not yet implemented.
+ * A view over a subset of {@link FrequencySortedSet}.
+ */
+ private final class SubSet extends AbstractSet<E> implements SortedSet<E>, Serializable {
+ /**
+ * For cross-version compatibility.
+ */
+ private static final long serialVersionUID = 6843072153603161179L;
+
+ /**
+ * Reference to the {@link FrequencySortedSet#sorted} array, used for detecting changes.
+ */
+ private transient E[] elements;
+
+ /**
+ * Low endpoint (inclusive) of the subset. May be {@code null}.
+ */
+ private final E fromElement;
+
+ /**
+ * High endpoint (exclusive) of the subset. May be {@code null}.
+ */
+ private final E toElement;
+
+ /**
+ * Whether the set should take in account {@link #fromElement} or {@link #toElement}.
+ * We have to use those booleans (we can not use {@code null} sentinel value instead)
+ * because {@code null} is a legal value for {@code from/toElement}.
+ */
+ private final boolean hasFrom, hasTo;
+
+ /**
+ * Lower and upper index computed from {@link #fromElement} and {@link #toElement}.
+ */
+ private transient int lower, upper;
+
+ /**
+ * Creates a new subset from the lower element (inclusive) to the upper element (exclusive).
+ * Each endpoint can be null.
+ */
+ SubSet(final boolean hasFrom, final E fromElement, final boolean hasTo, final E toElement) {
+ this.fromElement = fromElement;
+ this.toElement = toElement;
+ this.hasFrom = hasFrom;
+ this.hasTo = hasTo;
+ }
+
+ /**
+ * Returns the comparator, which is the same than {@link FrequencySortedSet#comparator()}.
+ */
+ @Override
+ public Comparator<E> comparator() {
+ return FrequencySortedSet.this;
+ }
+
+ /**
+ * Ensures that {@link #lower} and {@link #upper} indices are valid.
+ */
+ private void ensureValidRange() {
+ if (elements == null || elements != sorted) {
+ ensureSorted();
+ elements = sorted;
+ if (hasFrom) {
+ lower = Arrays.binarySearch(elements, fromElement, FrequencySortedSet.this);
+ if (lower < 0) lower = ~lower;
+ }
+ if (hasTo) {
+ upper = Arrays.binarySearch(elements, toElement, FrequencySortedSet.this);
+ if (upper < 0) upper = ~upper;
+ if (upper < lower) upper = lower;
+ } else {
+ upper = elements.length;
+ }
+ }
+ }
+
+ /**
+ * Returns an iterator over the elements in this subset.
+ */
+ @Override
+ public Iterator<E> iterator() {
+ ensureValidRange();
+ return new Iter(elements, lower, upper);
+ }
+
+ /**
+ * Returns the number of elements in this subset.
+ */
+ @Override
+ public int size() {
+ ensureValidRange();
+ return upper - lower;
+ }
+
+ /**
+ * Returns the first element in this subset.
+ *
+ * @see FrequencySortedSet#first()
+ */
+ @Override
+ public E first() {
+ ensureValidRange();
+ if (lower != upper) {
+ return elements[lower];
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+
+ /**
+ * Returns the last element in this subset.
+ *
+ * @see FrequencySortedSet#last()
+ */
+ @Override
+ public E last() {
+ ensureValidRange();
+ if (lower != upper) {
+ return elements[upper - 1];
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+
+ /**
+ * Returns a view of the portion of this subset whose elements occur
+ * with a frequency strictly less than {@code toElement} frequency.
+ *
+ * @see FrequencySortedSet#headSet(Object)
+ */
+ @Override
+ public SortedSet<E> headSet(final E to) {
+ return subSet(fromElement, to, hasFrom ? 0 : 2);
+ }
+
+ /**
+ * Returns a view of the portion of this subset whose elements occur with
+ * a frequency equal or greater than {@code fromElement} frequency.
+ *
+ * @see FrequencySortedSet#tailSet(Object)
+ */
+ @Override
+ public SortedSet<E> tailSet(final E from) {
+ return subSet(from, toElement, hasTo ? 0 : 1);
+ }
+
+ /**
+ * Returns a view of the portion of this subset whose elements occur with a frequency in the
+ * range of {@code fromElement} frequency inclusive to {@code toElement} frequency exclusive.
+ *
+ * @see FrequencySortedSet#subSet(Object, Object)
+ */
+ @Override
+ public SortedSet<E> subSet(final E from, final E to) {
+ return subSet(from, to, 0);
+ }
+
+ /**
+ * Implementation of {@link #headSet(Object)}, {@link #tailSet(Object)} and {@link #subSet(Object, Object)}.
+ * The {@code bounds} argument tell which {@link FrequencySortedSet} method to delegate to.
+ */
+ private SortedSet<E> subSet(E from, E to, final int bounded) {
+ if (hasFrom && compare(from, fromElement) < 0) from = fromElement;
+ if (hasTo && compare(to, toElement) > 0) to = toElement;
+ switch (bounded) {
+ default: throw new AssertionError(bounded);
+ case 0: return FrequencySortedSet.this.subSet(from, to);
+ case 1: return FrequencySortedSet.this.tailSet(from);
+ case 2: return FrequencySortedSet.this.headSet(to);
+ }
+ }
+ }
+
+ /**
+ * Returns a view of the portion of this set whose elements occur with a frequency strictly less than
+ * {@code toElement} frequency.
+ *
+ * @param toElement high endpoint (exclusive) of the returned set. May be {@code null}.
+ * @return a view of the portion of this set delimited by the given endpoint.
*/
@Override
- public SortedSet<E> headSet(E toElement) {
- throw new UnsupportedOperationException("Not supported yet.");
+ public SortedSet<E> headSet(final E toElement) {
+ return new SubSet(false, null, true, toElement);
}
/**
- * Not yet implemented.
+ * Returns a view of the portion of this set whose elements occur with a frequency equal or greater than
+ * {@code fromElement} frequency.
+ *
+ * @param fromElement low endpoint (inclusive) of the returned set. May be {@code null}.
+ * @return a view of the portion of this set delimited by the given endpoint.
*/
@Override
- public SortedSet<E> tailSet(E fromElement) {
- throw new UnsupportedOperationException("Not supported yet.");
+ public SortedSet<E> tailSet(final E fromElement) {
+ return new SubSet(true, fromElement, false, null);
}
/**
- * Not yet implemented.
+ * Returns a view of the portion of this set whose elements occur with a frequency in the range of
+ * {@code fromElement} frequency inclusive to {@code toElement} frequency exclusive.
+ *
+ * @param fromElement low endpoint (inclusive) of the returned set. May be {@code null}.
+ * @param toElement high endpoint (exclusive) of the returned set. May be {@code null}.
+ * @return a view of the portion of this set delimited by the given endpoints.
*/
@Override
- public SortedSet<E> subSet(E fromElement, E toElement) {
- throw new UnsupportedOperationException("Not supported yet.");
+ public SortedSet<E> subSet(final E fromElement, final E toElement) {
+ return new SubSet(true, fromElement, true, toElement);
}
/**
@@ -337,28 +544,27 @@ public class FrequencySortedSet<E> exten
}
/**
- * Sorts the elements in frequency order, if not already done. The sorted array will contains
+ * Sorts the elements in frequency order, if not already done. The sorted array will contain
* all elements without duplicated values, with the less frequent element first and the most
- * frequent last (or the converse if this set has been created for reverse order).
+ * frequent element last (or the converse if this set has been created for reverse order).
* If some elements appear at the same frequency, then their ordering will be preserved.
*/
@SuppressWarnings("unchecked")
private void ensureSorted() {
- if (sorted != null) {
- return;
- }
- @SuppressWarnings("rawtypes") // Generic array creation.
- final Map.Entry<E,Integer>[] entries = count.entrySet().toArray(new Map.Entry[count.size()]);
- Arrays.sort(entries, COMPARATOR);
- final int length = entries.length;
- sorted = (E[]) new Object[length];
- if (frequencies == null || frequencies.length != length) {
- frequencies = new int[length];
- }
- for (int i=0; i<length; i++) {
- final Map.Entry<E,Integer> entry = entries[i];
- sorted[i] = entry.getKey();
- frequencies[i] = Math.abs(entry.getValue());
+ if (sorted == null) {
+ @SuppressWarnings("rawtypes") // Generic array creation.
+ final Map.Entry<E,Integer>[] entries = count.entrySet().toArray(new Map.Entry[count.size()]);
+ Arrays.sort(entries, COMPARATOR);
+ final int length = entries.length;
+ sorted = (E[]) new Object[length];
+ if (frequencies == null || frequencies.length != length) {
+ frequencies = new int[length];
+ }
+ for (int i=0; i<length; i++) {
+ final Map.Entry<E,Integer> entry = entries[i];
+ sorted[i] = entry.getKey();
+ frequencies[i] = entry.getValue() ^ order;
+ }
}
}
@@ -412,16 +618,16 @@ public class FrequencySortedSet<E> exten
* Returns the frequency of the specified element in this set.
*
* @param element the element whose frequency is to be obtained.
- * @return the frequency of the given element, or {@code 0} if it doesn't occur in this set.
+ * @return the frequency of the given element, or {@code 0} if it does not occur in this set.
*/
public int frequency(final E element) {
- return Math.abs(signedFrequency(element));
+ return signedFrequency(element) ^ order;
}
/**
- * Returns the frequency of each element in this set, in iteration order.
+ * Returns the frequency of all elements in this set, in iteration order.
*
- * @return the frequency of each element in this set.
+ * @return the frequency of all elements in this set.
*/
public int[] frequencies() {
ensureSorted();
Modified: sis/trunk/core/sis-utility/src/test/java/org/apache/sis/measure/SystemUnitTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/test/java/org/apache/sis/measure/SystemUnitTest.java?rev=1790801&r1=1790800&r2=1790801&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/test/java/org/apache/sis/measure/SystemUnitTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/test/java/org/apache/sis/measure/SystemUnitTest.java [UTF-8] Mon Apr 10 10:49:21 2017
@@ -303,8 +303,8 @@ public final strictfp class SystemUnitTe
/*
* Test with units outside the pre-defined constants in the Units class.
*/
- final Unit<Length> anonymous = new SystemUnit<>(Length.class, (UnitDimension) Units.METRE.getDimension(), null, UnitRegistry.OTHER, (short) 0);
- final Unit<Length> otherName = new SystemUnit<>(Length.class, (UnitDimension) Units.METRE.getDimension(), "Foo", UnitRegistry.OTHER, (short) 0);
+ final Unit<Length> anonymous = new SystemUnit<>(Length.class, (UnitDimension) Units.METRE.getDimension(), null, UnitRegistry.OTHER, (short) 0, null);
+ final Unit<Length> otherName = new SystemUnit<>(Length.class, (UnitDimension) Units.METRE.getDimension(), "Foo", UnitRegistry.OTHER, (short) 0, null);
assertSame(Units.METRE, anonymous.asType(Length.class));
assertSame(otherName, otherName.asType(Length.class));
/*
Modified: sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java?rev=1790801&r1=1790800&r2=1790801&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java [UTF-8] Mon Apr 10 10:49:21 2017
@@ -110,6 +110,8 @@ import org.junit.BeforeClass;
org.apache.sis.measure.ConventionalUnitTest.class,
org.apache.sis.measure.UnitFormatTest.class,
org.apache.sis.measure.UnitsTest.class,
+ org.apache.sis.measure.ScalarTest.class,
+ org.apache.sis.measure.QuantitiesTest.class,
org.apache.sis.measure.UnitServicesTest.class,
org.apache.sis.measure.RangeTest.class,
org.apache.sis.measure.DateRangeTest.class,
Modified: sis/trunk/core/sis-utility/src/test/java/org/apache/sis/util/collection/FrequencySortedSetTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/test/java/org/apache/sis/util/collection/FrequencySortedSetTest.java?rev=1790801&r1=1790800&r2=1790801&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/test/java/org/apache/sis/util/collection/FrequencySortedSetTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/test/java/org/apache/sis/util/collection/FrequencySortedSetTest.java [UTF-8] Mon Apr 10 10:49:21 2017
@@ -16,7 +16,9 @@
*/
package org.apache.sis.util.collection;
+import java.util.Arrays;
import java.util.Collections;
+import org.apache.sis.test.DependsOnMethod;
import org.apache.sis.test.TestCase;
import org.junit.Test;
@@ -51,6 +53,7 @@ public final strictfp class FrequencySor
* Simple test with 2 elements.
*/
@Test
+ @DependsOnMethod("testSimple")
public void testTwoElements() {
final FrequencySortedSet<Integer> set = new FrequencySortedSet<>(true);
for (int i=0; i<10; i++) {
@@ -64,4 +67,30 @@ public final strictfp class FrequencySor
assertEquals(Integer.valueOf(11), set.last());
assertArrayEquals(new int[] {10, 4}, set.frequencies());
}
+
+ /**
+ * Tests creation of various subsets.
+ */
+ @Test
+ @DependsOnMethod("testTwoElements")
+ public void testSubSet() {
+ final FrequencySortedSet<Integer> set = new FrequencySortedSet<>();
+ set.addAll(Arrays.asList(2, 5, 3, 2, 4, 2, 3, 6, 2));
+ assertArrayEquals(new Integer[] {5, 4, 6, 3, 2}, set.toArray());
+ assertArrayEquals(new int[] {1, 1, 1, 2, 4}, set.frequencies());
+
+ assertArrayEquals("Expected all elements occurring less often than 2.",
+ new Integer[] {5, 4, 6, 3}, set.headSet(2).toArray());
+
+ assertArrayEquals("Expected all elements occurring less often than 3.",
+ new Integer[] {5, 4, 6}, set.headSet(3).toArray());
+
+ assertArrayEquals("Expected all elements occurring at least as often than 3.",
+ new Integer[] {3, 2}, set.tailSet(3).toArray());
+
+ assertArrayEquals("Expected all elements occurring at least as often than 3 but less than 2.",
+ new Integer[] {3}, set.subSet(3, 2).toArray());
+
+ assertTrue(set.subSet(2, 3).isEmpty());
+ }
}
Modified: sis/trunk/pom.xml
URL: http://svn.apache.org/viewvc/sis/trunk/pom.xml?rev=1790801&r1=1790800&r2=1790801&view=diff
==============================================================================
--- sis/trunk/pom.xml (original)
+++ sis/trunk/pom.xml Mon Apr 10 10:49:21 2017
@@ -594,6 +594,7 @@ Apache SIS is a free software, Java lang
<!-- Compile -->
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
+ <version>3.6.1</version>
<configuration>
<source>${maven.compile.source}</source>
<target>${maven.compile.target}</target>
@@ -609,6 +610,7 @@ Apache SIS is a free software, Java lang
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
+ <version>2.19.1</version>
<configuration>
<includes>
<include>**/*TestSuite.java</include>