OpenJDK / lambda / lambda / jdk
changeset 5887:ba24de9416e3 it2-bootstrap
Merge
author | briangoetz |
---|---|
date | Fri, 31 Aug 2012 23:08:47 -0400 |
parents | 4dd29128bc9b f94f4135cf68 |
children | dc8c914e7cac |
files | test-ng/tests/org/openjdk/tests/java/util/LambdaTestHelpers.java test-ng/tests/org/openjdk/tests/java/util/streams/ops/StreamOpTestCase.java |
diffstat | 14 files changed, 450 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/java/util/streams/LinearPipeline.java Fri Aug 31 22:42:01 2012 -0400 +++ b/src/share/classes/java/util/streams/LinearPipeline.java Fri Aug 31 23:08:47 2012 -0400 @@ -90,8 +90,13 @@ } @Override - public void forEach(Block<? super U> sink) { - pipeline(ForEachOp.make(sink)); + public void forEach(Block<? super U> block) { + pipeline(ForEachOp.make(block)); + } + + @Override + public Stream<U> tee(Block<? super U> block) { + return chainLinear(new TeeOp<>(block)); } @Override
--- a/src/share/classes/java/util/streams/MapPipeline.java Fri Aug 31 22:42:01 2012 -0400 +++ b/src/share/classes/java/util/streams/MapPipeline.java Fri Aug 31 23:08:47 2012 -0400 @@ -68,10 +68,15 @@ } @Override - public void forEach(BiBlock<K, V> sink) { + public void forEach(BiBlock<? super K, ? super V> sink) { pipeline(ForEachOp.make(sink)); } + @Override + public MapStream<K, V> tee(BiBlock<? super K, ? super V> block) { + return chainMap(new BiTeeOp<>(block)); + } + public<U> U pipeline(TerminalOp<Mapping<K,V>, U> op) { return evaluate(op); }
--- a/src/share/classes/java/util/streams/MapStream.java Fri Aug 31 22:42:01 2012 -0400 +++ b/src/share/classes/java/util/streams/MapStream.java Fri Aug 31 23:08:47 2012 -0400 @@ -38,7 +38,7 @@ public interface MapStream<K, V> { MapIterator<K, V> iterator(); - + /** * Return the mapping which is semantically "first" in the stream. If the * stream is not ordered then repeated invocations may return a different @@ -119,7 +119,14 @@ * * @param sink the Sink via which all elements will be processed. */ - void forEach(BiBlock<K, V> sink); + void forEach(BiBlock<? super K, ? super V> sink); + + /** + * Each element of this stream is processed by the provided sink. + * + * @param block the Sink via which all elements will be processed. + */ + MapStream<K, V> tee(BiBlock<? super K, ? super V> block); // @@@ Map, or MapFillable? <A extends Map<K, V>> A into(A target);
--- a/src/share/classes/java/util/streams/Sink.java Fri Aug 31 22:42:01 2012 -0400 +++ b/src/share/classes/java/util/streams/Sink.java Fri Aug 31 23:08:47 2012 -0400 @@ -25,6 +25,7 @@ package java.util.streams; import java.util.Mapping; +import java.util.Objects; import java.util.functions.Block; /** @@ -42,6 +43,7 @@ * Sink is being reused by multiple calculations. * @param size The approximate size of the data to be pushed downstream, if * known or -1 if size is unknown. + * @@@ or something like that... */ void begin(int size); @@ -71,7 +73,7 @@ protected final Sink downstream; public ChainedLinear(Sink downstream) { - this.downstream = downstream; + this.downstream = Objects.requireNonNull(downstream); } @Override @@ -101,7 +103,7 @@ protected final Sink downstream; public ChainedMap(Sink downstream) { - this.downstream = downstream; + this.downstream = Objects.requireNonNull(downstream); } @Override
--- a/src/share/classes/java/util/streams/Stream.java Fri Aug 31 22:42:01 2012 -0400 +++ b/src/share/classes/java/util/streams/Stream.java Fri Aug 31 23:08:47 2012 -0400 @@ -101,6 +101,8 @@ void forEach(Block<? super T> sink); + Stream<T> tee(Block<? super T> sink); + <A extends Fillable<? super T>> A into(A target); Object[] toArray();
--- a/src/share/classes/java/util/streams/ops/BiMapOp.java Fri Aug 31 22:42:01 2012 -0400 +++ b/src/share/classes/java/util/streams/ops/BiMapOp.java Fri Aug 31 23:08:47 2012 -0400 @@ -61,7 +61,6 @@ } public MapIterator<K, U> iterator(final MapIterator<K,V> source) { - Objects.requireNonNull(source); return iterator(source, mapper); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/java/util/streams/ops/BiTeeOp.java Fri Aug 31 23:08:47 2012 -0400 @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2012, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package java.util.streams.ops; + +import java.util.Iterator; +import java.util.MapIterator; +import java.util.Mapping; +import java.util.Objects; +import java.util.functions.BiBlock; +import java.util.streams.Sink; +import java.util.streams.Stream; + +/** + * Passes elements to provided block as encountered and passes objects + * downstream. + * + * @param <K> Type of element keys. + * @param <V> Type of element values. + */ +public class BiTeeOp<K, V> implements StatelessOp<Mapping<K,V>, Mapping<K,V>> { + + /** + * Tee block for this operation. + */ + public final BiBlock<? super K, ? super V> tee; + + public BiTeeOp(BiBlock<? super K, ? super V> tee) { + this.tee = Objects.requireNonNull(tee); + } + + @Override + public int getStreamFlags(int upstreamState) { + return upstreamState & ~(Stream.STATE_UNKNOWN_MASK_V1); + } + + @Override + public Iterator<Mapping<K, V>> iterator(final Iterator<Mapping<K,V>> source) { + return iterator(source, tee); + } + + public MapIterator<K, V> iterator(final MapIterator<K,V> source) { + return iterator(source, tee); + } + + @Override + public Sink<Mapping<K, V>, K, V> sink(Sink sink) { + return new Sink.ChainedMap<K,V>(sink) { + @Override + public void accept(K k, V v) { + tee.apply(k,v); + downstream.accept(k, v); + } + }; + } + + public static <K, V> MapIterator<K, V> iterator(final Iterator<Mapping<K, V>> source, + final BiBlock<? super K, ? super V> tee) { + Objects.requireNonNull(source); + Objects.requireNonNull(tee); + return new MapIterator<K, V>() { + Mapping<K, V> current; + + @Override + public boolean hasNext() { + return source.hasNext(); + } + + @Override + public Mapping<K, V> next() { + current = source.next(); + + tee.apply(current.getKey(), current.getValue()); + + return current; + } + + @Override + public K nextKey() { + return next().getKey(); + } + + @Override + public V nextValue() { + return next().getValue(); + } + + @Override + public K curKey() { + return current.getKey(); + } + + @Override + public V curValue() { + return current.getValue(); + } + }; + } +}
--- a/src/share/classes/java/util/streams/ops/ForEachOp.java Fri Aug 31 22:42:01 2012 -0400 +++ b/src/share/classes/java/util/streams/ops/ForEachOp.java Fri Aug 31 23:08:47 2012 -0400 @@ -25,6 +25,7 @@ package java.util.streams.ops; import java.util.Mapping; +import java.util.Objects; import java.util.Spliterator; import java.util.concurrent.RecursiveAction; import java.util.functions.BiBlock; @@ -41,7 +42,7 @@ private final StatefulSink<T,Void> sink; protected ForEachOp(StatefulSink<T, Void> sink) { - this.sink = sink; + this.sink = Objects.requireNonNull(sink); } public static<T> ForEachOp<T> make(final Block<? super T> block) { @@ -59,6 +60,7 @@ } public static<K,V> ForEachOp<Mapping<K,V>> make(final BiBlock<? super K, ? super V> block) { + Objects.requireNonNull(block); return new ForEachOp<>(new StatefulSink<Mapping<K,V>, Void>() { @Override public void accept(Object k, Object v) {
--- a/src/share/classes/java/util/streams/ops/MapOp.java Fri Aug 31 22:42:01 2012 -0400 +++ b/src/share/classes/java/util/streams/ops/MapOp.java Fri Aug 31 23:08:47 2012 -0400 @@ -49,7 +49,6 @@ @Override public Iterator<R> iterator(final Iterator<T> source) { - Objects.requireNonNull(source); return iterator(source, mapper); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/java/util/streams/ops/TeeOp.java Fri Aug 31 23:08:47 2012 -0400 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2012, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package java.util.streams.ops; + +import java.util.Iterator; +import java.util.Objects; +import java.util.functions.Block; +import java.util.streams.Sink; +import java.util.streams.Stream; + +/** + * TeeOp + */ +public class TeeOp<T> implements StatelessOp<T, T> { + public final Block<? super T> tee; + + public TeeOp(Block<? super T> tee) { + this.tee = Objects.requireNonNull(tee); + } + + @Override + public int getStreamFlags(int upstreamState) { + return upstreamState & ~Stream.STATE_UNKNOWN_MASK_V1; + } + + @Override + public Iterator<T> iterator(final Iterator<T> source) { + return iterator(source, tee); + } + + @Override + public Sink<T, ?, ?> sink(Sink sink) { + return new Sink.ChainedLinear<T>(sink) { + @Override + public void accept(T t) { + tee.apply(t); + downstream.accept(t); + } + }; + } + + public static<T> Iterator<T> iterator(final Iterator<T> source, final Block<? super T> tee) { + Objects.requireNonNull(source); + Objects.requireNonNull(tee); + return new Iterator<T>() { + @Override + public boolean hasNext() { + return source.hasNext(); + } + + @Override + public T next() { + T next = source.next(); + tee.apply(next); + return next; + } + }; + } +}
--- a/test-ng/tests/org/openjdk/tests/java/util/LambdaTestHelpers.java Fri Aug 31 22:42:01 2012 -0400 +++ b/test-ng/tests/org/openjdk/tests/java/util/LambdaTestHelpers.java Fri Aug 31 23:08:47 2012 -0400 @@ -185,23 +185,35 @@ } } - public static<T> void assertContents(Iterable<T> pi, Iterable<T> list) { - assertContents(pi.iterator(), list.iterator()); + public static<T> void assertContents(Iterable<T> actual, Iterable<T> expected) { + assertContents(actual.iterator(), expected.iterator()); } - public static<T> void assertContents(Iterator<T> pI, Iterator<T> lI) { - while (lI.hasNext()) { - assertTrue(pI.hasNext()); - T pT = pI.next(); - T lT = lI.next(); + public static<T> void assertContents(Iterator<T> actual, Iterator<T> expected) { + while (expected.hasNext()) { + assertTrue(actual.hasNext()); + T pT = actual.next(); + T lT = expected.next(); assertEquals(pT, lT); } - assertTrue(!pI.hasNext()); + assertTrue(!actual.hasNext()); } @SafeVarargs - public static<T> void assertContents(Iterator<T> pi, T... values) { - assertContents(pi, Arrays.asList(values).iterator()); + public static<T> void assertContents(Iterator<T> actual, T... expected) { + assertContents(actual, Arrays.asList(expected).iterator()); + } + + public static<T extends Comparable<? super T>> void assertContentsUnordered(Iterable<T> actual, Iterable<T> expected) { + ArrayList<T> one = new ArrayList<>(); + for (T t : actual) + one.add(t); + ArrayList<T> two = new ArrayList<>(); + for (T t : expected) + two.add(t); + Collections.sort(one); + Collections.sort(two); + assertContents(one, two); } static <T> void assertSplitContents(Iterable<Iterable<T>> splits, Iterable<T> list) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-ng/tests/org/openjdk/tests/java/util/streams/MapStreamTestDataProvider.java Fri Aug 31 23:08:47 2012 -0400 @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2012, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.tests.java.util.streams; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import org.testng.annotations.DataProvider; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentSkipListMap; + +/** + * MapStreamTestDataProvider + * <p/> + */ +public class MapStreamTestDataProvider { + + private static Map<Integer, Integer> makeIntegerIntegerMap(Class<? extends Map> type, int size) { + try { + Map<Integer, Integer> map = type.newInstance(); + for (int i = 1; i <= size; i++) { + map.put(i, i); + } + return map; + } catch (InstantiationException | IllegalAccessException badNews) { + throw new Error(badNews); + } + } + + private static Map<Integer, String> makeIntegerStringMap(Class<? extends Map> type, int size) { + try { + Map<Integer, String> map = type.newInstance(); + for (int i = 1; i <= size; i++) { + map.put(i, Integer.toString(i)); + } + return map; + } catch (InstantiationException | IllegalAccessException badNews) { + throw new Error(badNews); + } + } + private static final Class[] TYPES = { + HashMap.class, + Hashtable.class, + LinkedHashMap.class, + TreeMap.class, + ConcurrentHashMap.class, + ConcurrentSkipListMap.class + }; + private static final int[] SIZES = {0, 1, 10, 100, 1000}; + private static final Object[][] TEST_DATA; + + static { + List<Object[]> list = new ArrayList<>(); + for (Class type : TYPES) { + String name = type.getName(); + for (int size : SIZES) { + String range = 0 == size ? "[empty]" : String.format("[1..%d]", size); + + list.add(new Object[]{ + String.format("%s%s%s", name, "<Integer,Integer>", range), + makeIntegerIntegerMap(type, size) + }); + list.add(new Object[]{ + String.format("%s%s%s", name, "<Integer,String>", range), + makeIntegerStringMap(type, size)}); + } + } + TEST_DATA = list.toArray(new Object[0][]); + } + + // Return an array of ( String name, TestData<Integer> ) + @DataProvider(name = "opMaps") + public static Object[][] makeMapTestData() { + return TEST_DATA; + } +}
--- a/test-ng/tests/org/openjdk/tests/java/util/streams/ops/StreamOpTestCase.java Fri Aug 31 22:42:01 2012 -0400 +++ b/test-ng/tests/org/openjdk/tests/java/util/streams/ops/StreamOpTestCase.java Fri Aug 31 23:08:47 2012 -0400 @@ -325,7 +325,7 @@ return sink; } - public static interface TestData<T> { + public static interface TestData<T> extends Iterable<T>, Traversable<T>, Sized { AbstractPipeline<?, T> seq(); AbstractPipeline<?, T> par(); Iterator<T> iterator();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-ng/tests/org/openjdk/tests/java/util/streams/ops/TeeOpTest.java Fri Aug 31 23:08:47 2012 -0400 @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2012, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.tests.java.util.streams.ops; + +import java.util.Arrays; +import java.util.Optional; +import java.util.streams.StatefulSink; +import org.testng.annotations.Test; + +import java.util.streams.ops.TeeOp; +import java.util.streams.ops.ToArrayOp; +import java.util.streams.ops.SeedlessFoldOp; +import java.util.streams.ops.MapOp; + +import org.openjdk.tests.java.util.streams.StreamTestDataProvider; + + +import static org.openjdk.tests.java.util.LambdaTestHelpers.*; + +/** + * TeeOpTest + * + */ +public class TeeOpTest extends StreamOpTestCase { + public void testRawIterator() { + StatefulSink<Integer,Object[]> copy = ToArrayOp.<Integer>singleton().sink(); + copy.begin(-1); + assertCountSum(TeeOp.iterator(countTo(0).iterator(), copy), 0, 0); + copy.end(); + assertCountSum(Arrays.asList(copy.getAndClearState()).iterator(), 0, 0); + + copy.begin(-1); + assertCountSum(TeeOp.iterator(countTo(10).iterator(), copy), 10, 55); + copy.end(); + assertCountSum(Arrays.asList(copy.getAndClearState()).iterator(), 10, 55); + + copy.begin(-1); + assertCountSum(TeeOp.iterator(MapOp.iterator(countTo(10).iterator(), mDoubler), copy), 10, 110); + copy.end(); + assertCountSum(Arrays.asList(copy.getAndClearState()).iterator(), 10, 110); + } + + public void testTee() { + StatefulSink<Integer,Object[]> copy = ToArrayOp.<Integer>singleton().sink(); + copy.begin(-1); + assertCountSum(countTo(0).stream().tee(copy), 0, 0); + copy.end(); + assertCountSum(Arrays.asList(copy.getAndClearState()).iterator(), 0, 0); + + copy.begin(-1); + assertCountSum(countTo(10).stream().tee(copy), 10, 55); + copy.end(); + assertCountSum(Arrays.asList(copy.getAndClearState()).iterator(), 10, 55); + + copy.begin(-1); + assertCountSum(countTo(10).stream().map(mDoubler).tee(copy), 10, 110); + copy.end(); + assertCountSum(Arrays.asList(copy.getAndClearState()).iterator(), 10, 110); + } + + @Test(dataProvider = "opArrays", dataProviderClass = StreamTestDataProvider.class) + public void testOps(String name, TestData<Integer> data) { + StatefulSink<Integer,Optional<Integer>> fold = new SeedlessFoldOp<>(rPlus).sink(); + fold.begin(-1); + StreamResult<Integer> result = exerciseOps(data, new TeeOp<>(fold)); + assertContentsUnordered(result, data); + + fold.end(); + } +}