Author: desruisseaux
Date: Fri May 11 10:46:42 2018
New Revision: 1831399
URL: http://svn.apache.org/viewvc?rev=1831399&view=rev
Log:
Reduce redundancies in the test and add a parallelization test.
Modified:
sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/JoinFeatureSetTest.java
Modified:
sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/JoinFeatureSetTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/JoinFeatureSetTest.java?rev=1831399&r1=1831398&r2=1831399&view=diff
==============================================================================
---
sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/JoinFeatureSetTest.java
[UTF-8] (original)
+++
sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/JoinFeatureSetTest.java
[UTF-8] Fri May 11 10:46:42 2018
@@ -18,15 +18,16 @@ package org.apache.sis.internal.storage;
import java.util.Map;
import java.util.HashMap;
-import java.util.List;
-import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Iterator;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.sis.feature.builder.FeatureTypeBuilder;
import org.apache.sis.filter.DefaultFilterFactory;
import org.apache.sis.internal.feature.AttributeConvention;
import org.apache.sis.storage.DataStoreException;
import org.apache.sis.storage.FeatureSet;
+import org.apache.sis.test.DependsOnMethod;
import org.apache.sis.test.TestCase;
import org.junit.Test;
@@ -43,6 +44,7 @@ import org.opengis.filter.PropertyIsEqua
* Tests {@link JoinFeatureSet}.
*
* @author Johann Sorel (Geomatys)
+ * @author Martin Desruisseaux (Geomatys)
* @version 1.0
* @since 1.0
* @module
@@ -54,6 +56,12 @@ public final strictfp class JoinFeatureS
private final FeatureSet featureSet1, featureSet2;
/**
+ * {@code true} if testing parallel execution, or {@code false} for
testing sequential execution.
+ * Parallel execution will be tested only if all sequential execution
succeed.
+ */
+ private boolean parallel;
+
+ /**
* Creates a new test case.
*/
public JoinFeatureSetTest() {
@@ -62,88 +70,49 @@ public final strictfp class JoinFeatureS
builder.addAttribute( String.class).setName("myNameSpace", "att1");
builder.addAttribute(Integer.class).setName("myNameSpace", "att2");
final FeatureType type1 = builder.build();
-
- List<Feature> features = new ArrayList<>(5);
-
- Feature f = type1.newInstance();
- f.setPropertyValue(AttributeConvention.IDENTIFIER, "fid_1_0");
- f.setPropertyValue("att1", "str1");
- f.setPropertyValue("att2", 1);
- features.add(f);
-
- f = type1.newInstance();
- f.setPropertyValue(AttributeConvention.IDENTIFIER, "fid_1_1");
- f.setPropertyValue("att1", "str2");
- f.setPropertyValue("att2", 2);
- features.add(f);
-
- f = type1.newInstance();
- f.setPropertyValue(AttributeConvention.IDENTIFIER, "fid_1_2");
- f.setPropertyValue("att1", "str3");
- f.setPropertyValue("att2", 3);
- features.add(f);
-
- f = type1.newInstance();
- f.setPropertyValue(AttributeConvention.IDENTIFIER, "fid_1_3");
- f.setPropertyValue("att1", "str50");
- f.setPropertyValue("att2", 50);
- features.add(f);
-
- f = type1.newInstance();
- f.setPropertyValue(AttributeConvention.IDENTIFIER, "fid_1_4");
- f.setPropertyValue("att1", "str51");
- f.setPropertyValue("att2", 51);
- features.add(f);
-
- featureSet1 = new MemoryFeatureSet(null, null, type1, features);
-
- //
----------------------------------------------------------------------
+ featureSet1 = new MemoryFeatureSet(null, null, type1, Arrays.asList(
+ newFeature1(type1, "fid_1_0", "str1", 1),
+ newFeature1(type1, "fid_1_1", "str2", 2),
+ newFeature1(type1, "fid_1_2", "str3", 3),
+ newFeature1(type1, "fid_1_3", "str50", 50),
+ newFeature1(type1, "fid_1_4", "str51", 51)));
builder = new FeatureTypeBuilder().setName("Type2");
builder.addAttribute(
String.class).setName(AttributeConvention.IDENTIFIER_PROPERTY);
builder.addAttribute(Integer.class).setName("otherNameSpace", "att3");
builder.addAttribute( Double.class).setName("otherNameSpace", "att4");
final FeatureType type2 = builder.build();
+ featureSet2 = new MemoryFeatureSet(null, null, type2, Arrays.asList(
+ newFeature2(type2, "fid_2_0", 1, 10),
+ newFeature2(type2, "fid_2_1", 2, 20),
+ newFeature2(type2, "fid_2_2", 2, 30),
+ newFeature2(type2, "fid_2_3", 3, 40),
+ newFeature2(type2, "fid_2_4", 60, 60),
+ newFeature2(type2, "fid_2_5", 61, 61)));
+ }
- features = new ArrayList<>(6);
-
- f = type2.newInstance();
- f.setPropertyValue(AttributeConvention.IDENTIFIER, "fid_2_0");
- f.setPropertyValue("att3", 1);
- f.setPropertyValue("att4", 10d);
- features.add(f);
-
- f = type2.newInstance();
- f.setPropertyValue(AttributeConvention.IDENTIFIER, "fid_2_1");
- f.setPropertyValue("att3", 2);
- f.setPropertyValue("att4", 20d);
- features.add(f);
-
- f = type2.newInstance();
- f.setPropertyValue(AttributeConvention.IDENTIFIER, "fid_2_2");
- f.setPropertyValue("att3", 2);
- f.setPropertyValue("att4", 30d);
- features.add(f);
-
- f = type2.newInstance();
- f.setPropertyValue(AttributeConvention.IDENTIFIER, "fid_2_3");
- f.setPropertyValue("att3", 3);
- f.setPropertyValue("att4", 40d);
- features.add(f);
-
- f = type2.newInstance();
- f.setPropertyValue(AttributeConvention.IDENTIFIER, "fid_2_4");
- f.setPropertyValue("att3", 60);
- f.setPropertyValue("att4", 60d);
- features.add(f);
-
- f = type2.newInstance();
- f.setPropertyValue(AttributeConvention.IDENTIFIER, "fid_2_5");
- f.setPropertyValue("att3", 61);
- f.setPropertyValue("att4", 61d);
- features.add(f);
+ /**
+ * Creates a new feature of type 1 with the given identifier and attribute
values.
+ * This is a helper method for the constructor only.
+ */
+ private static Feature newFeature1(final FeatureType type, final String
id, final String att1, final int att2) {
+ final Feature f = type.newInstance();
+ f.setPropertyValue(AttributeConvention.IDENTIFIER, id);
+ f.setPropertyValue("att1", att1);
+ f.setPropertyValue("att2", att2);
+ return f;
+ }
- featureSet2 = new MemoryFeatureSet(null, null, type2, features);
+ /**
+ * Creates a new feature of type 2 with the given identifier and attribute
values.
+ * This is a helper method for the constructor only.
+ */
+ private static Feature newFeature2(final FeatureType type, final String
id, final int att3, final double att4) {
+ final Feature f = type.newInstance();
+ f.setPropertyValue(AttributeConvention.IDENTIFIER, id);
+ f.setPropertyValue("att3", att3);
+ f.setPropertyValue("att4", att4);
+ return f;
}
/**
@@ -159,6 +128,19 @@ public final strictfp class JoinFeatureS
}
/**
+ * Creates a stream over the features from the given set. If
parallelization is enabled,
+ * then this method copies the features in a temporary list using
parallelized paths
+ * before to return the stream of that list.
+ */
+ private Stream<Feature> stream(final FeatureSet col) throws
DataStoreException {
+ if (parallel) {
+ return col.features(true).collect(Collectors.toList()).stream();
+ } else {
+ return col.features(false);
+ }
+ }
+
+ /**
* Returns the identifier of the given feature.
*/
private static String getId(final Feature feature) {
@@ -166,199 +148,163 @@ public final strictfp class JoinFeatureS
}
/**
- * Test inner join feature set.
+ * Tests inner join feature set.
*
* @throws DataStoreException if an error occurred while creating the
feature set.
*/
@Test
public void testInnerJoin() throws DataStoreException {
final FeatureSet col = create(JoinFeatureSet.Type.INNER);
- try (Stream<Feature> stream = col.features(false)) {
+ try (Stream<Feature> stream = stream(col)) {
final Iterator<Feature> ite = stream.iterator();
int count = 0;
while (ite.hasNext()) {
count++;
- final Feature f = ite.next();
- final Feature c1 = (Feature) f.getPropertyValue("s1");
- final Feature c2 = (Feature) f.getPropertyValue("s2");
+ final Feature f = ite.next();
+ final String att1; // Expected value of "att1".
+ final int join; // Expected value of "att2" and
"att3", on which the join operation is done.
+ final double att4; // Expected value of "att4".
switch (getId(f)) {
- case "fid_1_0 fid_2_0": {
- assertEquals("str1",
c1.getProperty("att1").getValue());
- assertEquals( 1,
c1.getProperty("att2").getValue());
- assertEquals( 1,
c2.getProperty("att3").getValue());
- assertEquals(10d,
c2.getProperty("att4").getValue());
- break;
- }
- case "fid_1_1 fid_2_1": {
- assertEquals("str2",
c1.getProperty("att1").getValue());
- assertEquals( 2,
c1.getProperty("att2").getValue());
- assertEquals( 2,
c2.getProperty("att3").getValue());
- assertEquals(20d,
c2.getProperty("att4").getValue());
- break;
- }
- case "fid_1_1 fid_2_2": {
- assertEquals("str2",
c1.getProperty("att1").getValue());
- assertEquals( 2,
c1.getProperty("att2").getValue());
- assertEquals( 2,
c2.getProperty("att3").getValue());
- assertEquals(30d,
c2.getProperty("att4").getValue());
- break;
- }
- case "fid_1_2 fid_2_3": {
- assertEquals("str3",
c1.getProperty("att1").getValue());
- assertEquals( 3,
c1.getProperty("att2").getValue());
- assertEquals( 3,
c2.getProperty("att3").getValue());
- assertEquals(40d,
c2.getProperty("att4").getValue());
- break;
- }
- default: {
- fail("unexpected feature");
- break;
- }
+ case "fid_1_0 fid_2_0": att1 = "str1"; join = 1; att4 =
10; break;
+ case "fid_1_1 fid_2_1": att1 = "str2"; join = 2; att4 =
20; break;
+ case "fid_1_1 fid_2_2": att1 = "str2"; join = 2; att4 =
30; break;
+ case "fid_1_2 fid_2_3": att1 = "str3"; join = 3; att4 =
40; break;
+ default: fail("unexpected feature"); continue;
}
+ final Feature c1 = (Feature) f.getPropertyValue("s1");
+ final Feature c2 = (Feature) f.getPropertyValue("s2");
+ assertEquals("att1", att1, c1.getProperty("att1").getValue());
+ assertEquals("att2", join, c1.getProperty("att2").getValue());
+ assertEquals("att3", join, c2.getProperty("att3").getValue());
+ assertEquals("att4", att4, c2.getProperty("att4").getValue());
}
assertEquals("Unexpected amount of features.", 4, count);
}
}
/**
- * Test outer join feature set.
+ * Tests outer join feature set.
*
* @throws DataStoreException if an error occurred while creating the
feature set.
*/
@Test
public void testOuterLeft() throws DataStoreException {
final FeatureSet col = create(JoinFeatureSet.Type.LEFT_OUTER);
- try (Stream<Feature> stream = col.features(false)) {
- final Iterator<Feature> ite = stream.iterator();
- boolean foundStr1 = false;
- boolean foundStr20 = false;
- boolean foundStr21 = false;
- boolean foundStr3 = false;
- boolean foundStr50 = false;
- boolean foundStr51 = false;
- int count = 0;
- while (ite.hasNext()) {
- final Feature f = ite.next();
- final Feature c1 = (Feature) f.getPropertyValue("s1");
- final Feature c2 = (Feature) f.getPropertyValue("s2");
- final String att1 =
c1.getProperty("att1").getValue().toString();
- switch (att1) {
- case "str1": {
- foundStr1 = true;
- assertEquals( 1, c1.getProperty("att2").getValue());
- assertEquals( 1, c2.getProperty("att3").getValue());
- assertEquals(10d, c2.getProperty("att4").getValue());
- break;
- }
- case "str2": {
- assertEquals(2, c1.getProperty("att2").getValue());
- assertEquals(2, c2.getProperty("att3").getValue());
- double att4 = (Double)
c2.getProperty("att4").getValue();
- foundStr20 |= (att4 == 20);
- foundStr21 |= (att4 == 30);
- break;
- }
- case "str3": {
- foundStr3 = true;
- assertEquals( 3, c1.getProperty("att2").getValue());
- assertEquals( 3, c2.getProperty("att3").getValue());
- assertEquals(40d, c2.getProperty("att4").getValue());
- break;
- }
- case "str50": {
- foundStr50 = true;
- assertEquals(50, c1.getProperty("att2").getValue());
- assertNull(c2);
- break;
- }
- case "str51": {
- foundStr51 = true;
- assertEquals(51, c1.getProperty("att2").getValue());
- assertNull(c2);
- break;
- }
- default: {
- fail("unexpected feature");
- break;
- }
- }
- count++;
- }
- assertTrue(foundStr1);
- assertTrue(foundStr20);
- assertTrue(foundStr21);
- assertTrue(foundStr3);
- assertTrue(foundStr50);
- assertTrue(foundStr51);
- assertEquals("Unexpected amount of features.", 6, count);
- }
+ testOuter(col, 1, 0);
}
/**
- * Test outer join feature set.
+ * Tests outer join feature set.
*
* @throws DataStoreException if an error occurred while creating the
feature set.
*/
@Test
public void testOuterRight() throws DataStoreException {
final FeatureSet col = create(JoinFeatureSet.Type.RIGHT_OUTER);
- try (Stream<Feature> stream = col.features(false)) {
+ testOuter(col, 0, 1);
+ }
+
+ /**
+ * Implementation of {@link #testOuterLeft()} and {@link
#testOuterRight()}.
+ *
+ * @param nl 1 if testing outer left, 0 otherwise.
+ * @param nr 1 if testing outer right, 0 otherwise.
+ */
+ private void testOuter(final FeatureSet col, final int nl, final int nr)
throws DataStoreException {
+ try (Stream<Feature> stream = stream(col)) {
final Iterator<Feature> ite = stream.iterator();
- boolean foundStr1 = false;
- boolean foundStr20 = false;
- boolean foundStr21 = false;
- boolean foundStr3 = false;
- boolean foundStr60 = false;
- boolean foundStr61 = false;
- int count = 0;
+ int foundStr1 = 0, foundStr20 = 0, foundStr50 = 0, foundStr60 = 0,
+ foundStr3 = 0, foundStr21 = 0, foundStr51 = 0, foundStr61 = 0,
count = 0;
while (ite.hasNext()) {
final Feature f = ite.next();
final Feature c1 = (Feature) f.getPropertyValue("s1");
final Feature c2 = (Feature) f.getPropertyValue("s2");
if (c1 != null) {
- switch (c1.getProperty("att1").getValue().toString()) {
+ switch ((String) c1.getProperty("att1").getValue()) {
case "str1": {
- foundStr1 = true;
- assertEquals( 1,
c1.getProperty("att2").getValue());
- assertEquals( 1,
c2.getProperty("att3").getValue());
- assertEquals(10d,
c2.getProperty("att4").getValue());
+ assertEquals("att2", 1,
c1.getProperty("att2").getValue());
+ assertEquals("att3", 1,
c2.getProperty("att3").getValue());
+ assertEquals("att4", 10d,
c2.getProperty("att4").getValue());
+ foundStr1++;
break;
}
case "str2": {
- assertEquals(2, c1.getProperty("att2").getValue());
- assertEquals(2, c2.getProperty("att3").getValue());
- double att4 = (Double)
c2.getProperty("att4").getValue();
- foundStr20 |= (att4 == 20d);
- foundStr21 |= (att4 == 30d);
+ assertEquals("att2", 2,
c1.getProperty("att2").getValue());
+ assertEquals("att3", 2,
c2.getProperty("att3").getValue());
+ double att4 = (Double)
c2.getProperty("att4").getValue();
+ if (att4 == 20) foundStr20++;
+ if (att4 == 30) foundStr21++;
break;
}
case "str3": {
- foundStr3 = true;
- assertEquals( 3,
c1.getProperty("att2").getValue());
- assertEquals( 3,
c2.getProperty("att3").getValue());
-
assertEquals(40d,c2.getProperty("att4").getValue());
+ assertEquals("att2", 3,
c1.getProperty("att2").getValue());
+ assertEquals("att3", 3,
c2.getProperty("att3").getValue());
+ assertEquals("att4", 40d,
c2.getProperty("att4").getValue());
+ foundStr3++;
+ break;
+ }
+ case "str50": {
+ assertEquals("att2", 50,
c1.getProperty("att2").getValue());
+ assertNull("right", c2);
+ foundStr50++;
+ break;
+ }
+ case "str51": {
+ assertEquals("att2", 51,
c1.getProperty("att2").getValue());
+ assertNull("right", c2);
+ foundStr51++;
+ break;
+ }
+ default: {
+ fail("unexpected feature");
break;
}
}
} else {
- int att3 = (Integer) c2.getProperty("att3").getValue();
- if (att3 == 60) {
- assertEquals(c2.getProperty("att4").getValue(), 60d);
- foundStr60 = true;
- } else if (att3 == 61) {
- assertEquals(c2.getProperty("att4").getValue(), 61d);
- foundStr61 = true;
+ switch ((Integer) c2.getProperty("att3").getValue()) {
+ case 60: {
+ assertEquals(c2.getProperty("att4").getValue(),
60d);
+ foundStr60++;
+ break;
+ }
+ case 61: {
+ assertEquals(c2.getProperty("att4").getValue(),
61d);
+ foundStr61++;
+ break;
+ }
+ default: {
+ fail("unexpected feature");
+ break;
+ }
}
}
count++;
}
- assertTrue(foundStr1);
- assertTrue(foundStr20);
- assertTrue(foundStr21);
- assertTrue(foundStr3);
- assertTrue(foundStr60);
- assertTrue(foundStr61);
- assertEquals(6, count);
+ assertEquals("str1", 1, foundStr1);
+ assertEquals("str2", 1, foundStr20);
+ assertEquals("str2", 1, foundStr21);
+ assertEquals("str3", 1, foundStr3);
+ assertEquals("str50", nl, foundStr50);
+ assertEquals("str51", nl, foundStr51);
+ assertEquals("str60", nr, foundStr60);
+ assertEquals("str61", nr, foundStr61);
+ assertEquals("Unexpected amount of features.", 6, count);
}
}
+
+ /**
+ * Tests inner join, outer left and outer right using parallelized paths.
This will test the
+ * {@code Spliterator.trySplit()} / {@code forEachRemaining(Consumer)}
implementations of
+ * {@link JoinFeatureSet}.
+ *
+ * @throws DataStoreException if an error occurred while creating the
feature set.
+ */
+ @Test
+ @DependsOnMethod({"testInnerJoin", "testOuterLeft", "testOuterRight"})
+ public void testParallelization() throws DataStoreException {
+ parallel = true;
+ testInnerJoin();
+ testOuterLeft();
+ testOuterRight();
+ }
}