mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-11 19:08:23 +00:00
8025067: Unconditionally throw NPE if null op provided to Arrays.parallelPrefix
Reviewed-by: henryjen, chegar, psandoz
This commit is contained in:
parent
8fd60ce581
commit
bf70514208
@ -1583,6 +1583,7 @@ public class Arrays {
|
||||
* @since 1.8
|
||||
*/
|
||||
public static <T> void parallelPrefix(T[] array, BinaryOperator<T> op) {
|
||||
Objects.requireNonNull(op);
|
||||
if (array.length > 0)
|
||||
new ArrayPrefixHelpers.CumulateTask<>
|
||||
(null, op, array, 0, array.length).invoke();
|
||||
@ -1606,6 +1607,7 @@ public class Arrays {
|
||||
*/
|
||||
public static <T> void parallelPrefix(T[] array, int fromIndex,
|
||||
int toIndex, BinaryOperator<T> op) {
|
||||
Objects.requireNonNull(op);
|
||||
rangeCheck(array.length, fromIndex, toIndex);
|
||||
if (fromIndex < toIndex)
|
||||
new ArrayPrefixHelpers.CumulateTask<>
|
||||
@ -1627,6 +1629,7 @@ public class Arrays {
|
||||
* @since 1.8
|
||||
*/
|
||||
public static void parallelPrefix(long[] array, LongBinaryOperator op) {
|
||||
Objects.requireNonNull(op);
|
||||
if (array.length > 0)
|
||||
new ArrayPrefixHelpers.LongCumulateTask
|
||||
(null, op, array, 0, array.length).invoke();
|
||||
@ -1649,6 +1652,7 @@ public class Arrays {
|
||||
*/
|
||||
public static void parallelPrefix(long[] array, int fromIndex,
|
||||
int toIndex, LongBinaryOperator op) {
|
||||
Objects.requireNonNull(op);
|
||||
rangeCheck(array.length, fromIndex, toIndex);
|
||||
if (fromIndex < toIndex)
|
||||
new ArrayPrefixHelpers.LongCumulateTask
|
||||
@ -1673,6 +1677,7 @@ public class Arrays {
|
||||
* @since 1.8
|
||||
*/
|
||||
public static void parallelPrefix(double[] array, DoubleBinaryOperator op) {
|
||||
Objects.requireNonNull(op);
|
||||
if (array.length > 0)
|
||||
new ArrayPrefixHelpers.DoubleCumulateTask
|
||||
(null, op, array, 0, array.length).invoke();
|
||||
@ -1695,6 +1700,7 @@ public class Arrays {
|
||||
*/
|
||||
public static void parallelPrefix(double[] array, int fromIndex,
|
||||
int toIndex, DoubleBinaryOperator op) {
|
||||
Objects.requireNonNull(op);
|
||||
rangeCheck(array.length, fromIndex, toIndex);
|
||||
if (fromIndex < toIndex)
|
||||
new ArrayPrefixHelpers.DoubleCumulateTask
|
||||
@ -1716,6 +1722,7 @@ public class Arrays {
|
||||
* @since 1.8
|
||||
*/
|
||||
public static void parallelPrefix(int[] array, IntBinaryOperator op) {
|
||||
Objects.requireNonNull(op);
|
||||
if (array.length > 0)
|
||||
new ArrayPrefixHelpers.IntCumulateTask
|
||||
(null, op, array, 0, array.length).invoke();
|
||||
@ -1738,6 +1745,7 @@ public class Arrays {
|
||||
*/
|
||||
public static void parallelPrefix(int[] array, int fromIndex,
|
||||
int toIndex, IntBinaryOperator op) {
|
||||
Objects.requireNonNull(op);
|
||||
rangeCheck(array.length, fromIndex, toIndex);
|
||||
if (fromIndex < toIndex)
|
||||
new ArrayPrefixHelpers.IntCumulateTask
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @test 8014076 8025067
|
||||
* @summary unit test for Arrays.ParallelPrefix().
|
||||
* @author Tristan Yan
|
||||
* @run testng ParallelPrefix
|
||||
@ -54,30 +54,44 @@ public class ParallelPrefix {
|
||||
private final static int LARGE_ARRAY_SIZE = 1 << 12;
|
||||
|
||||
private final static int[] ARRAY_SIZE_COLLECTION = new int[]{
|
||||
SMALL_ARRAY_SIZE, THRESHOLD_ARRAY_SIZE,MEDIUM_ARRAY_SIZE, LARGE_ARRAY_SIZE};
|
||||
SMALL_ARRAY_SIZE,
|
||||
THRESHOLD_ARRAY_SIZE,
|
||||
MEDIUM_ARRAY_SIZE,
|
||||
LARGE_ARRAY_SIZE
|
||||
};
|
||||
|
||||
@DataProvider
|
||||
public static Object[][] intSet(){
|
||||
return genericData(size -> IntStream.range(0, size).toArray(), new IntBinaryOperator[]{Integer::sum, Integer::min});
|
||||
return genericData(size -> IntStream.range(0, size).toArray(),
|
||||
new IntBinaryOperator[]{
|
||||
Integer::sum,
|
||||
Integer::min});
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public static Object[][] longSet(){
|
||||
return genericData(size -> LongStream.range(0, size).toArray(), new LongBinaryOperator[]{Long::sum, Long::min});
|
||||
return genericData(size -> LongStream.range(0, size).toArray(),
|
||||
new LongBinaryOperator[]{
|
||||
Long::sum,
|
||||
Long::min});
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public static Object[][] doubleSet(){
|
||||
return genericData(size -> IntStream.range(0, size).mapToDouble(i -> (double)i).toArray(),
|
||||
new DoubleBinaryOperator[]{Double::sum, Double::min});
|
||||
new DoubleBinaryOperator[]{
|
||||
Double::sum,
|
||||
Double::min});
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public static Object[][] stringSet(){
|
||||
Function<Integer, String[]> stringsFunc = size ->
|
||||
IntStream.range(0, size).mapToObj(Integer::toString).toArray(String[]::new);
|
||||
BinaryOperator<String> cancatBop = String::concat;
|
||||
return genericData(stringsFunc, new BinaryOperator[]{cancatBop});
|
||||
BinaryOperator<String> concat = String::concat;
|
||||
return genericData(stringsFunc,
|
||||
(BinaryOperator<String>[]) new BinaryOperator[]{
|
||||
concat });
|
||||
}
|
||||
|
||||
private static <T, OPS> Object[][] genericData(Function<Integer, T> generateFunc, OPS[] ops) {
|
||||
@ -161,5 +175,123 @@ public class ParallelPrefix {
|
||||
Arrays.parallelPrefix(parallelRangeResult, op);
|
||||
assertEquals(parallelRangeResult, Arrays.copyOfRange(sequentialResult, fromIndex, toIndex));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNPEs() {
|
||||
// null array
|
||||
assertThrows( () -> Arrays.parallelPrefix((int[]) null, Integer::max),
|
||||
NullPointerException.class, "should throw NPE");
|
||||
assertThrows( () -> Arrays.parallelPrefix((long []) null, Long::max),
|
||||
NullPointerException.class, "should throw NPE");
|
||||
assertThrows( () -> Arrays.parallelPrefix((double []) null, Double::max),
|
||||
NullPointerException.class, "should throw NPE");
|
||||
assertThrows( () -> Arrays.parallelPrefix((String []) null, String::concat),
|
||||
NullPointerException.class, "should throw NPE");
|
||||
|
||||
// null array w/ range
|
||||
assertThrows( () -> Arrays.parallelPrefix((int[]) null, 0, 0, Integer::max),
|
||||
NullPointerException.class, "should throw NPE");
|
||||
assertThrows( () -> Arrays.parallelPrefix((long []) null, 0, 0, Long::max),
|
||||
NullPointerException.class, "should throw NPE");
|
||||
assertThrows( () -> Arrays.parallelPrefix((double []) null, 0, 0, Double::max),
|
||||
NullPointerException.class, "should throw NPE");
|
||||
assertThrows( () -> Arrays.parallelPrefix((String []) null, 0, 0, String::concat),
|
||||
NullPointerException.class, "should throw NPE");
|
||||
|
||||
// null op
|
||||
assertThrows( () -> Arrays.parallelPrefix(new int[] {}, null),
|
||||
NullPointerException.class, "should throw NPE");
|
||||
assertThrows( () -> Arrays.parallelPrefix(new long[] {}, null),
|
||||
NullPointerException.class, "should throw NPE");
|
||||
assertThrows( () -> Arrays.parallelPrefix(new double[] {}, null),
|
||||
NullPointerException.class, "should throw NPE");
|
||||
assertThrows( () -> Arrays.parallelPrefix(new String[] {}, null),
|
||||
NullPointerException.class, "should throw NPE");
|
||||
|
||||
// null op w/ range
|
||||
assertThrows( () -> Arrays.parallelPrefix(new int[] {}, 0, 0, null),
|
||||
NullPointerException.class, "should throw NPE");
|
||||
assertThrows( () -> Arrays.parallelPrefix(new long[] {}, 0, 0, null),
|
||||
NullPointerException.class, "should throw NPE");
|
||||
assertThrows( () -> Arrays.parallelPrefix(new double[] {}, 0, 0, null),
|
||||
NullPointerException.class, "should throw NPE");
|
||||
assertThrows( () -> Arrays.parallelPrefix(new String[] {}, 0, 0, null),
|
||||
NullPointerException.class, "should throw NPE");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIAEs() {
|
||||
assertThrows( () -> Arrays.parallelPrefix(new int[] {}, 1, 0, Integer::max),
|
||||
IllegalArgumentException.class, "should throw IAE");
|
||||
assertThrows( () -> Arrays.parallelPrefix(new long[] {}, 1, 0, Long::max),
|
||||
IllegalArgumentException.class, "should throw IAE");
|
||||
assertThrows( () -> Arrays.parallelPrefix(new double[] {}, 1, 0, Double::max),
|
||||
IllegalArgumentException.class, "should throw IAE");
|
||||
assertThrows( () -> Arrays.parallelPrefix(new String[] {}, 1, 0, String::concat),
|
||||
IllegalArgumentException.class, "should throw IAE");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAIOBEs() {
|
||||
// bad "fromIndex"
|
||||
assertThrows( () -> Arrays.parallelPrefix(new int[] {}, -1, 0, Integer::max),
|
||||
ArrayIndexOutOfBoundsException.class, "should throw AIOBE");
|
||||
assertThrows( () -> Arrays.parallelPrefix(new long[] {}, -1, 0, Long::max),
|
||||
ArrayIndexOutOfBoundsException.class, "should throw AIOBE");
|
||||
assertThrows( () -> Arrays.parallelPrefix(new double[] {}, -1, 0, Double::max),
|
||||
ArrayIndexOutOfBoundsException.class, "should throw AIOBE");
|
||||
assertThrows( () -> Arrays.parallelPrefix(new String[] {}, -1, 0, String::concat),
|
||||
ArrayIndexOutOfBoundsException.class, "should throw AIOBE");
|
||||
|
||||
// bad "toIndex"
|
||||
assertThrows( () -> Arrays.parallelPrefix(new int[] {}, 0, 1, Integer::max),
|
||||
ArrayIndexOutOfBoundsException.class, "should throw AIOBE");
|
||||
assertThrows( () -> Arrays.parallelPrefix(new long[] {}, 0, 1, Long::max),
|
||||
ArrayIndexOutOfBoundsException.class, "should throw AIOBE");
|
||||
assertThrows( () -> Arrays.parallelPrefix(new double[] {}, 0, 1, Double::max),
|
||||
ArrayIndexOutOfBoundsException.class, "should throw AIOBE");
|
||||
assertThrows( () -> Arrays.parallelPrefix(new String[] {}, 0, 1, String::concat),
|
||||
ArrayIndexOutOfBoundsException.class, "should throw AIOBE");
|
||||
}
|
||||
|
||||
// "library" code
|
||||
|
||||
public interface Thrower<T extends Throwable> {
|
||||
|
||||
public void run() throws T;
|
||||
}
|
||||
|
||||
|
||||
public static <T extends Throwable> void assertThrows(Thrower<T> thrower, Class<T> throwable) {
|
||||
assertThrows(thrower, throwable, null);
|
||||
}
|
||||
|
||||
public static <T extends Throwable> void assertThrows(Thrower<T> thrower, Class<T> throwable, String message) {
|
||||
Throwable thrown;
|
||||
try {
|
||||
thrower.run();
|
||||
thrown = null;
|
||||
} catch (Throwable caught) {
|
||||
thrown = caught;
|
||||
}
|
||||
|
||||
assertInstance(thrown, throwable,
|
||||
((null != message) ? message : "") +
|
||||
" Failed to throw " + throwable.getCanonicalName());
|
||||
}
|
||||
|
||||
public static <T extends Throwable> void assertThrows(Class<T> throwable, String message, Thrower<T>... throwers) {
|
||||
for(Thrower<T> thrower : throwers) {
|
||||
assertThrows(thrower, throwable, message);
|
||||
}
|
||||
}
|
||||
|
||||
public static void assertInstance(Object actual, Class<?> expected) {
|
||||
assertInstance(expected.isInstance(actual), null);
|
||||
}
|
||||
|
||||
public static void assertInstance(Object actual, Class<?> expected, String message) {
|
||||
assertTrue(expected.isInstance(actual), message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user