--- a/jdk/src/java.base/share/classes/java/util/stream/FindOps.java Mon Feb 08 10:37:37 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/util/stream/FindOps.java Mon Feb 08 10:40:00 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -107,7 +107,7 @@
*/
private static final class FindOp<T, O> implements TerminalOp<T, O> {
private final StreamShape shape;
- final boolean mustFindFirst;
+ final int opFlags;
final O emptyValue;
final Predicate<O> presentPredicate;
final Supplier<TerminalSink<T, O>> sinkSupplier;
@@ -129,7 +129,7 @@
O emptyValue,
Predicate<O> presentPredicate,
Supplier<TerminalSink<T, O>> sinkSupplier) {
- this.mustFindFirst = mustFindFirst;
+ this.opFlags = StreamOpFlag.IS_SHORT_CIRCUIT | (mustFindFirst ? 0 : StreamOpFlag.NOT_ORDERED);
this.shape = shape;
this.emptyValue = emptyValue;
this.presentPredicate = presentPredicate;
@@ -138,7 +138,7 @@
@Override
public int getOpFlags() {
- return StreamOpFlag.IS_SHORT_CIRCUIT | (mustFindFirst ? 0 : StreamOpFlag.NOT_ORDERED);
+ return opFlags;
}
@Override
@@ -156,7 +156,10 @@
@Override
public <P_IN> O evaluateParallel(PipelineHelper<T> helper,
Spliterator<P_IN> spliterator) {
- return new FindTask<>(this, helper, spliterator).invoke();
+ // This takes into account the upstream ops flags and the terminal
+ // op flags and therefore takes into account findFirst or findAny
+ boolean mustFindFirst = StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags());
+ return new FindTask<>(this, mustFindFirst, helper, spliterator).invoke();
}
}
@@ -250,16 +253,20 @@
private static final class FindTask<P_IN, P_OUT, O>
extends AbstractShortCircuitTask<P_IN, P_OUT, O, FindTask<P_IN, P_OUT, O>> {
private final FindOp<P_OUT, O> op;
+ private final boolean mustFindFirst;
FindTask(FindOp<P_OUT, O> op,
+ boolean mustFindFirst,
PipelineHelper<P_OUT> helper,
Spliterator<P_IN> spliterator) {
super(helper, spliterator);
+ this.mustFindFirst = mustFindFirst;
this.op = op;
}
FindTask(FindTask<P_IN, P_OUT, O> parent, Spliterator<P_IN> spliterator) {
super(parent, spliterator);
+ this.mustFindFirst = parent.mustFindFirst;
this.op = parent.op;
}
@@ -283,7 +290,7 @@
@Override
protected O doLeaf() {
O result = helper.wrapAndCopyInto(op.sinkSupplier.get(), spliterator).get();
- if (!op.mustFindFirst) {
+ if (!mustFindFirst) {
if (result != null)
shortCircuit(result);
return null;
@@ -300,7 +307,7 @@
@Override
public void onCompletion(CountedCompleter<?> caller) {
- if (op.mustFindFirst) {
+ if (mustFindFirst) {
for (FindTask<P_IN, P_OUT, O> child = leftChild, p = null; child != p;
p = child, child = rightChild) {
O result = child.getLocalResult();
--- a/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/LambdaTestHelpers.java Mon Feb 08 10:37:37 2016 +0100
+++ b/jdk/test/java/util/stream/bootlib/java.base/java/util/stream/LambdaTestHelpers.java Mon Feb 08 10:40:00 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -47,6 +47,7 @@
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertFalse;
/**
* LambdaTestHelpers -- assertion methods and useful objects for lambda test cases
@@ -400,6 +401,16 @@
assertEquals(toBoxedMultiset(actual), toBoxedMultiset(expected));
}
+ public static<T> void assertContains(Optional<T> actual, Iterator<T> it) {
+ actual.ifPresentOrElse(r -> {
+ boolean contained = false;
+ while (!contained && it.hasNext()) {
+ contained = Objects.equals(r, it.next());
+ }
+ assertTrue(contained, "Not found: "+r);
+ }, () -> assertFalse(it.hasNext()));
+ }
+
public static void launderAssertion(Runnable r, Supplier<String> additionalInfo) {
try {
r.run();
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/FindAnyOpTest.java Mon Feb 08 10:37:37 2016 +0100
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/FindAnyOpTest.java Mon Feb 08 10:40:00 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -20,6 +20,12 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
+/**
+ * @test
+ * @bug 8148115
+ */
+
package org.openjdk.tests.java.util.stream;
import java.util.*;
@@ -61,18 +67,7 @@
void exerciseStream(TestData.OfRef<Integer> data, Function<Stream<Integer>, Stream<Integer>> fs) {
Optional<Integer> or = withData(data).terminal(fs, s -> s.findAny()).equalator(VALID_ANSWER).exercise();
- if (or.isPresent()) {
- Integer r = or.get();
- Iterator<Integer> it = fs.apply(data.stream()).iterator();
- boolean contained = false;
- while (!contained && it.hasNext()) {
- contained = Objects.equals(r, it.next());
- }
- assertTrue(contained);
- }
- else {
- assertFalse(fs.apply(data.stream()).iterator().hasNext());
- }
+ assertContains(or, fs.apply(data.stream()).iterator());
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/FindFirstOpTest.java Mon Feb 08 10:37:37 2016 +0100
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/FindFirstOpTest.java Mon Feb 08 10:40:00 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -20,6 +20,12 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
+/**
+ * @test
+ * @bug 8148115
+ */
+
package org.openjdk.tests.java.util.stream;
import java.util.*;
@@ -59,15 +65,19 @@
}
void exerciseStream(TestData.OfRef<Integer> data, Function<Stream<Integer>, Stream<Integer>> fs) {
- Optional<Integer> r = exerciseTerminalOps(data, fs, s -> s.findFirst());
- if (r.isPresent()) {
- Iterator<Integer> i = fs.apply(data.stream()).iterator();
- assertTrue(i.hasNext());
- assertEquals(i.next(), r.get());
- }
- else {
- assertFalse(fs.apply(data.stream()).iterator().hasNext());
- }
+ Iterator<Integer> i = fs.apply(data.stream()).iterator();
+ Optional<Integer> expected = i.hasNext() ? Optional.of(i.next()) : Optional.empty();
+ withData(data).terminal(fs, s -> s.findFirst())
+ .expectedResult(expected)
+ .resultAsserter((act, exp, ord, par) -> {
+ if (par & !ord) {
+ assertContains(act, fs.apply(data.stream()).iterator());
+ }
+ else {
+ assertEquals(act, exp);
+ }
+ })
+ .exercise();
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)