OpenJDK / lambda / lambda / jdk
changeset 5896:beb45a05989e it2-bootstrap
Improved version of array-stream forEach; move Fillable to be nested interface of Stream; create Map-equivalent of Fillable
author | briangoetz |
---|---|
date | Tue, 04 Sep 2012 11:33:42 -0400 |
parents | 610aa6b7e1bb |
children | e98be7e3f31f eaa2a29f3b92 |
files | make/java/java/FILES_java.gmk src/share/classes/java/lang/AbstractStringBuilder.java src/share/classes/java/util/Arrays.java src/share/classes/java/util/Collection.java src/share/classes/java/util/Fillable.java src/share/classes/java/util/Map.java src/share/classes/java/util/ParallelIterable.java src/share/classes/java/util/ParallelIterables.java src/share/classes/java/util/StringJoiner.java src/share/classes/java/util/streams/LinearPipeline.java src/share/classes/java/util/streams/MapPipeline.java src/share/classes/java/util/streams/MapStream.java src/share/classes/java/util/streams/Stream.java |
diffstat | 13 files changed, 49 insertions(+), 888 deletions(-) [+] |
line wrap: on
line diff
--- a/make/java/java/FILES_java.gmk Tue Sep 04 10:52:18 2012 -0400 +++ b/make/java/java/FILES_java.gmk Tue Sep 04 11:33:42 2012 -0400 @@ -236,7 +236,6 @@ java/util/Iterators.java \ java/util/Iterables.java \ java/util/ListIterator.java \ - java/util/Fillable.java \ java/util/Collection.java \ java/util/Set.java \ java/util/SortedSet.java \ @@ -282,8 +281,6 @@ java/util/TimerTask.java \ java/util/Objects.java \ java/util/UUID.java \ - java/util/ParallelIterable.java \ - java/util/ParallelIterables.java \ java/util/Splittable.java \ java/util/concurrent/AbstractExecutorService.java \ java/util/concurrent/ArrayBlockingQueue.java \
--- a/src/share/classes/java/lang/AbstractStringBuilder.java Tue Sep 04 10:52:18 2012 -0400 +++ b/src/share/classes/java/lang/AbstractStringBuilder.java Tue Sep 04 11:33:42 2012 -0400 @@ -43,7 +43,7 @@ * @since 1.5 */ abstract class AbstractStringBuilder - implements Appendable, CharSequence, java.util.Fillable<CharSequence> + implements Appendable, CharSequence, Stream.Destination<CharSequence> { /** * The value is used for character storage.
--- a/src/share/classes/java/util/Arrays.java Tue Sep 04 10:52:18 2012 -0400 +++ b/src/share/classes/java/util/Arrays.java Tue Sep 04 11:33:42 2012 -0400 @@ -3738,8 +3738,12 @@ @Override public void forEach(Block<? super T> block) { - while (offset < endOffset) { - block.apply(array[offset++]); + // Strange-looking way to iterate; reduce heap write traffic + if (offset < endOffset) { + int wasOffset = offset; + offset = endOffset; + for (int i=wasOffset; i<endOffset; i++) + block.apply(array[i]); } } @@ -3760,8 +3764,13 @@ @Override public void forEach(Block<? super T> block) { - while (offset < endOffset) - block.apply(array[offset++]); + // Strange-looking way to iterate; reduce heap write traffic + if (offset < endOffset) { + int wasOffset = offset; + offset = endOffset; + for (int i=wasOffset; i<endOffset; i++) + block.apply(array[i]); + } } @Override
--- a/src/share/classes/java/util/Collection.java Tue Sep 04 10:52:18 2012 -0400 +++ b/src/share/classes/java/util/Collection.java Tue Sep 04 11:33:42 2012 -0400 @@ -130,7 +130,7 @@ * @since 1.2 */ -public interface Collection<E> extends Sized, Streamable<E>, Traversable<E>, Iterable<E>, Fillable<E> { +public interface Collection<E> extends Sized, Streamable<E>, Traversable<E>, Iterable<E>, Stream.Destination<E> { // Query Operations /**
--- a/src/share/classes/java/util/Fillable.java Tue Sep 04 10:52:18 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright (c) 1997, 2010, 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; - -import java.util.streams.Stream; - -/** - * An aggregate that supports an {@code add(T)} operation. - * - * @param <T> Type of aggregate elements. - */ -public interface Fillable<T> { - public void addAll(Stream<? extends T> stream); -}
--- a/src/share/classes/java/util/Map.java Tue Sep 04 10:52:18 2012 -0400 +++ b/src/share/classes/java/util/Map.java Tue Sep 04 11:33:42 2012 -0400 @@ -122,7 +122,7 @@ * @see Set * @since 1.2 */ -public interface Map<K,V> extends Sized, Streamable<Mapping<K,V>>, MapTraversable<K,V> { +public interface Map<K,V> extends Sized, Streamable<Mapping<K,V>>, MapTraversable<K,V>, MapStream.Destination<K,V> { // Query Operations @@ -496,10 +496,10 @@ return Streams.stream(this, size()); } - <M extends Mapping<? extends K, ? extends V>> void putAll(Stream<M> stream) default { + @Override + void addAll(MapStream<? extends K, ? extends V> stream) default { if (stream.isParallel()) stream = stream.sequential(); - // @@@ Would use this::add but compiler doens't support that yet. - stream.forEach((M m) -> { put(m.getKey(),m.getValue()); }); + stream.forEach((BiBlock<K,V>) this::put); } }
--- a/src/share/classes/java/util/ParallelIterable.java Tue Sep 04 10:52:18 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,163 +0,0 @@ -package java.util; - -import java.util.functions.*; - -/** - * ParallelIterable - * @param <T> - */ -public interface ParallelIterable<T> extends Splittable<T> { -// long estimateCount(); -// -// /** -// * Return {@code true} if this Iterable contains no elements. -// * -// * @since 1.8 -// * -// * @return {@code true} if this Iterable contains no elements. -// */ -// boolean isEmpty() default { -// return ParallelIterables.isEmpty(this); -// } -// -// T getFirst() default { -// return ParallelIterables.getFirst(this); -// } -// -// T getAny() default { -// return ParallelIterables.getAny(this); -// } -// -// T getOnly() default { -// return ParallelIterables.getOnly(this); -// } -// -// /** -// * Filter elements according to the provided {@code predicate} and return a -// * an Iterable view of the filtered elements. The filtered view will reflect -// * changes in this Iterable. -// * -// * @since 1.8 -// * -// * @param predicate Decides which elements should be included in the -// * resulting Iterable view. Each element with a {@code true} result will be -// * included in the resulting view. -// * @return An Iterable view of the filtered elements. -// */ -// ParallelIterable<T> filter(Predicate<? super T> predicate) default { -// return ParallelIterables.filter(this, predicate); -// } -// -// /** -// * Performs the operation specified by {@code block} upon each element. -// * -// * @since 1.8 -// * -// * @param block The operation to be performed upon each each element. -// */ -// void forEach(Block<? super T> block) default { -// ParallelIterables.forEach(this, block); -// } -// -// /** -// * Map elements using the provided {@code mapper} and return an Iterable -// * view of the mapped elements. The mappeds view will reflect changes in -// * this Iterable. -// * -// * @since 1.8 -// * -// * @param <U> Type of the returned elements. -// * @param mapper Performs the mapping between elements of type {@code T} -// * and elements of type {@code U}. -// * @return An Iterable view consisting of the mapped elements. -// */ -// <U> ParallelIterable<U> map(Mapper<? super T, ? extends U> mapper) default { -// return ParallelIterables.map(this, mapper); -// } -// -// <U> ParallelIterable<U> flatMap(Mapper<? super T, ? extends Iterable<U>> mapper) default { -// return ParallelIterables.flatMap(this, mapper); -// } -// -// /** -// * Reduce elements to a single value. -// * -// * @since 1.8 -// * -// * @param reducer Reduces elements to a result of type {@code U}. -// * @param base Initial value for reducer. -// * @return The reduced value of the elements. -// */ -// T reduce(T base, BinaryOperator<T> reducer) default { -// return ParallelIterables.reduce(this, base, reducer); -// } -// -// <U> U mapReduce(Mapper<? super T, ? extends U> mapper, U base, BinaryOperator<U> reducer) default { -// return ParallelIterables.mapReduce(this, mapper, base, reducer); -// } -// int mapReduce(IntMapper<? super T> mapper, int base, IntBinaryOperator reducer) default { -// return ParallelIterables.mapReduce(this, mapper, base, reducer); -// } -// long mapReduce(LongMapper<? super T> mapper, long base, LongBinaryOperator reducer) default { -// return ParallelIterables.mapReduce(this, mapper, base, reducer); -// } -// double mapReduce(DoubleMapper<? super T> mapper, double base, DoubleBinaryOperator reducer) default { -// return ParallelIterables.mapReduce(this, mapper, base, reducer); -// } -// -// /** -// * All elements are added to the specified collection. -// * -// * @since 1.8 -// * -// * @param target The collection to which the elements are added. -// * @return The provided collection. -// */ -// <A extends Fillable<? super T>> A into(A target) default { -// return ParallelIterables.into(this, target); -//} -// -// /** -// * Returns {@code true} if any of the elements match the provided predicate. -// * -// * @param filter a predicate against which returns {@code true} for -// * matching elements. -// * @return {@code true} if any elements returned {@code true} for the provided predicate. -// */ -// public boolean anyMatch(Predicate<? super T> filter) default { -// return ParallelIterables.anyMatch(this, filter); -// } -// -// /** -// * Returns {@code true} if none of the elements match the provided predicate. -// * -// * @param filter a predicate against which returns {@code true} for -// * matching elements. -// * @return {@code true} if all elements of this collection returned -// * {@code true} for the provided predicate. -// */ -// public boolean noneMatch(Predicate<? super T> filter) default { -// return ParallelIterables.noneMatch(this, filter); -// } -// -// /** -// * Returns {@code true} if all of the elements match the provided predicate. -// * -// * @param filter a predicate against which returns {@code true} for -// * matching elements. -// * @return {@code true} if all elements returned {@code true} for the provided predicate. -// */ -// public boolean allMatch(Predicate<? super T> filter) default { -// return ParallelIterables.allMatch(this, filter); -// } -// -// // public ParallelIterable<T> sorted() default Iterables.sorted; -// -// public ParallelIterable<T> sorted(Comparator<? super T> comparator) default { -// return ParallelIterables.sorted(this, comparator); -// } -// -// public ParallelIterable<T> uniqueElements() default { -// return ParallelIterables.uniqueElements(this); -// } -}
--- a/src/share/classes/java/util/ParallelIterables.java Tue Sep 04 10:52:18 2012 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,664 +0,0 @@ -package java.util; - -import java.util.concurrent.ForkJoinUtils; -import java.util.concurrent.RecursiveAction; -import java.util.concurrent.RecursiveTask; -import java.util.functions.*; -import java.util.streams.ops.FilterOp; - -/** - * ParallelIterables - */ -public final class ParallelIterables { -// private ParallelIterables() { -// throw new Error("No instances for you!"); -// } -// -// /** -// * Return {@code true} if the iterable contains no elements. -// * -// * @param <T> Type of elements -// * @param iterable The source of elements. -// * @return {@code true} if the Iterable contains no elements. -// */ -// public static <T> boolean isEmpty(ParallelIterable<T> iterable) { -// Objects.requireNonNull(iterable); -// return anyMatch(iterable, Predicates.alwaysTrue()); -// } -// -// private static<T> int calculateDepth(long s) { -// long initialSize = s; -// long leafSize = 1 + ((s + 7) >>> 3) / ForkJoinUtils.defaultFJPool().getParallelism(); -// int d = 0; -// while (s > leafSize) { -// s /= 2; -// ++d; -// } -// // System.out.printf("Size=%d, depth=%d%n", initialSize, d); -// return d; -// } -// -// public static<T> T getFirst(ParallelIterable<T> iterable) { -// Objects.requireNonNull(iterable); -// // @@@ don't forget cancellation of remaining tasks after getting the first one -// return iterable.sequential().getFirst(); -// } -// -// public static<T> T getAny(ParallelIterable<T> iterable) { -// Objects.requireNonNull(iterable); -// throw new UnsupportedOperationException(); -// } -// -// public static<T> T getOnly(ParallelIterable<T> iterable) { -// Objects.requireNonNull(iterable); -// return iterable.sequential().getOnly(); -// } -// -// private static abstract class BaseTask<T, S extends BaseTask<T, S>> extends RecursiveAction { -// public final int depth; -// public final ParallelIterable<T> coll; -// -// protected BaseTask(int depth, ParallelIterable<T> coll) { -// this.depth = depth; -// this.coll = coll; -// } -// -// public abstract void seq(); -// -// public void combine(S left, S right) { } -// -// public abstract S makeTask(int depth, ParallelIterable<T> coll); -// -// @Override -// protected void compute() { -// if (depth == 0) -// seq(); -// else { -// S left = makeTask(depth-1, coll.left()); -// S right = makeTask(depth-1, coll.right()); -// right.fork(); -// left.compute(); -// right.join(); -// combine(left, right); -// } -// } -// } -// -// private static class CountTask<T> extends BaseTask<T, CountTask<T>> { -// public long count; -// -// CountTask(int depth, ParallelIterable<T> coll) { -// super(depth, coll); -// } -// -// @Override -// public void seq() { -// count = Iterators.count(coll.iterator()); -// } -// -// @Override -// public void combine(CountTask<T> left, CountTask<T> right) { -// count = left.count + right.count; -// } -// -// @Override -// public CountTask<T> makeTask(int depth, ParallelIterable<T> coll) { -// return new CountTask<>(depth, coll); -// } -// } -// -// public static<T> long count(ParallelIterable<T> pi) { -// Objects.requireNonNull(pi); -// if (pi instanceof Collection) -// return ((Collection) pi).size(); -// else { -// CountTask<T> task = new CountTask<>(calculateDepth(pi.estimateCount()), pi); -// ForkJoinUtils.defaultFJPool().invoke(task); -// return task.count; -// } -// } -// -// private static abstract class BaseLazy<T, U> implements ParallelIterable<U> { -// protected final ParallelIterable<T> underlying; -// -// private BaseLazy(ParallelIterable<T> underlying) { -// this.underlying = underlying; -// } -// -// @Override -// public long estimateCount() { -// return underlying.estimateCount(); -// } -// -// @Override -// public ParallelIterable<U> left() { -// return makeNode(underlying.left()); -// } -// -// @Override -// public ParallelIterable<U> right() { -// return makeNode(underlying.right()); -// } -// -// @Override -// public Iterator<U> iterator() { -// return leafAction(underlying.iterator()); -// } -// -// @Override -// public Iterable<U> sequential() { -// return () -> { -// Sequential t = new Sequential(calculateDepth(underlying.estimateCount()), underlying); -// ForkJoinUtils.defaultFJPool().execute(t); -// return t.iterator(); -// }; -// } -// -// protected abstract BaseLazy<T, U> makeNode(ParallelIterable<T> pi); -// -// protected abstract Iterator<U> leafAction(Iterator<T> it); -// -// private class Sequential extends RecursiveTask<Iterable<U>> { -// public final int depth; -// public final ParallelIterable<T> coll; -// public final Sequential left, right; -// -// public Sequential(int depth, ParallelIterable<T> coll) { -// this.depth = depth; -// this.coll = coll; -// if (depth > 0) { -// left = new Sequential(depth - 1, coll.left()); -// right = new Sequential(depth - 1, coll.right()); -// } -// else { -// left = right = null; -// } -// } -// -// public Iterator<U> iterator() { -// final List<Sequential> nodes = new ArrayList<>(1 << depth); -// populate(nodes, this); -// return nodes.flatMap(task -> task.join()).iterator(); -// } -// -// private<T, U> void populate(List<Sequential> nodes, Sequential task) { -// if (task.left != null) { -// populate(nodes, task.left); -// populate(nodes, task.right); -// } -// else -// nodes.add(task); -// } -// -// @Override -// protected Iterable<U> compute() { -// if (depth == 0) { -// return Iterators.drain(leafAction(coll.iterator())); -// } -// else { -// right.fork(); -// left.fork(); -// return null; -// } -// } -// } -// } -// -// private static class Filtered<T> extends BaseLazy<T, T> { -// private final Predicate<? super T> predicate; -// -// private Filtered(ParallelIterable<T> underlying, Predicate<? super T> predicate) { -// super(underlying); -// this.predicate = predicate; -// } -// -// @Override -// protected BaseLazy<T, T> makeNode(ParallelIterable<T> pi) { -// return new Filtered<>(pi, predicate); -// } -// -// @Override -// protected Iterator<T> leafAction(Iterator<T> it) { -// return FilterOp.iterator(it, predicate); -// } -// } -// -// /** -// * Filter elements according to the provided {@code predicate} and return a -// * an Iterable view of the filtered elements. The filtered view will reflect -// * changes in the provided {@code iterable}. -// * -// * @param <T> Type of elements -// * @param pi The source of elements. -// * @param predicate Decides which elements should be included in the -// * resulting Iterable view. Each element with a {@code true} result will be -// * included in the resulting view. -// * @return An Iterable view of the filtered elements. -// */ -// public static <T> ParallelIterable<T> filter(final ParallelIterable<T> pi, final Predicate<? super T> predicate) { -// Objects.requireNonNull(pi); -// Objects.requireNonNull(predicate); -// return new Filtered<>(pi, predicate); -// } -// -// private static class ForEachTask<T> extends BaseTask<T, ForEachTask<T>> { -// private static final long serialVersionUID = 1L; -// private final Block<? super T> block; -// -// ForEachTask(int depth, ParallelIterable<T> coll, Block<? super T> block) { -// super(depth, coll); -// this.block = block; -// } -// -// @Override -// public void seq() { -// Iterators.forEach(coll.iterator(), block); -// } -// -// @Override -// public ForEachTask<T> makeTask(int depth, ParallelIterable<T> coll) { -// return new ForEachTask<>(depth, coll, block); -// } -// } -// -// /** -// * Performs the operation specified by {@code block} upon each element. -// * -// * <p/>This implementation is eager and performs the operation upon elements -// * before returning. As such, it should be used only with finite iterables. -// * -// * @param <T> Type of elements -// * @param pi The source of elements. -// * @param block The operation to be performed upon each each element. -// */ -// public static <T> void forEach(final ParallelIterable<T> pi, final Block<? super T> block) { -// Objects.requireNonNull(pi); -// Objects.requireNonNull(block); -// ForkJoinUtils.defaultFJPool().invoke(new ForEachTask<>(calculateDepth(pi.estimateCount()), pi, block)); -// } -// -// private static class Mapped<T, U> extends BaseLazy<T, U> { -// private final Mapper<? super T, ? extends U> mapper; -// -// private Mapped(ParallelIterable<T> underlying, Mapper<? super T, ? extends U> mapper) { -// super(underlying); -// this.mapper = mapper; -// } -// -// @Override -// protected BaseLazy<T, U> makeNode(ParallelIterable<T> pi) { -// return new Mapped<>(pi, mapper); -// } -// -// @Override -// protected Iterator<U> leafAction(Iterator<T> it) { -// return Iterators.map(it, mapper); -// } -// } -// -// /** -// * Map the elements of an Iterable and return an Iterable view containing -// * the mapped elements. -// * -// * @param <T> Type of elements -// * @param <U> Type of the returned elements. -// * @param pi The source of elements. -// * @param mapper Performs the mapping between elements of type {@code T} -// * and type {@code U}. -// * @return An Iterable view consisting of the mapped elements. -// */ -// public static <T, U> ParallelIterable<U> map(final ParallelIterable<T> pi, final Mapper<? super T, ? extends U> mapper) { -// Objects.requireNonNull(pi); -// Objects.requireNonNull(mapper); -// return new Mapped<>(pi, mapper); -// } -// -// private static class FlatMapped<T, U> extends BaseLazy<T,U> { -// private final Mapper<? super T, ? extends Iterable<U>> mapper; -// -// private FlatMapped(ParallelIterable<T> underlying, Mapper<? super T, ? extends Iterable<U>> mapper) { -// super(underlying); -// this.mapper = mapper; -// } -// -// @Override -// protected BaseLazy<T, U> makeNode(ParallelIterable<T> pi) { -// return new FlatMapped<>(pi, mapper); -// } -// -// @Override -// protected Iterator<U> leafAction(Iterator<T> it) { -// return Iterators.flatMap(it, mapper); -// } -// } -// -// public static <T, U> ParallelIterable<U> flatMap(final ParallelIterable<T> pi, final Mapper<? super T, ? extends Iterable<U>> mapper) { -// Objects.requireNonNull(pi); -// Objects.requireNonNull(mapper); -// return new FlatMapped<>(pi, mapper); -// } -// -// private static class ReduceTask<T> extends BaseTask<T, ReduceTask<T>> { -// private static final long serialVersionUID = 1L; -// public final BinaryOperator<T> operator; -// public final T base; -// public T value; -// -// ReduceTask(int depth, ParallelIterable<T> coll, T base, BinaryOperator<T> operator) { -// super(depth, coll); -// this.operator = operator; -// this.base = base; -// } -// -// @Override -// public void seq() { -// value = Iterators.reduce(coll.iterator(), base, operator); -// } -// -// @Override -// public void combine(ReduceTask<T> left, ReduceTask<T> right) { -// value = operator.operate(left.value, right.value); -// } -// -// @Override -// public ReduceTask<T> makeTask(int depth, ParallelIterable<T> coll) { -// return new ReduceTask<>(depth, coll, base, operator); -// } -// } -// -// private static class MapReduceTask<T, U> extends BaseTask<T, MapReduceTask<T, U>> { -// private static final long serialVersionUID = 1L; -// public final BinaryOperator<U> operator; -// public final Mapper<? super T, ? extends U> mapper; -// public final U base; -// public U value; -// -// MapReduceTask(int depth, ParallelIterable<T> coll, Mapper<? super T, ? extends U> mapper, U base, BinaryOperator<U> operator) { -// super(depth, coll); -// this.operator = operator; -// this.base = base; -// this.mapper = mapper; -// } -// -// @Override -// public void seq() { -// value = Iterators.mapReduce(coll.iterator(), mapper, base, operator); -// } -// -// @Override -// public void combine(MapReduceTask<T,U> left, MapReduceTask<T,U> right) { -// value = operator.operate(left.value, right.value); -// } -// -// @Override -// public MapReduceTask<T,U> makeTask(int depth, ParallelIterable<T> coll) { -// return new MapReduceTask<>(depth, coll, mapper, base, operator); -// } -// } -// -// private static class IntMapReduceTask<T> extends BaseTask<T, IntMapReduceTask<T>> { -// private static final long serialVersionUID = 1L; -// public final IntBinaryOperator operator; -// public final IntMapper<? super T> mapper; -// public final int base; -// public int value; -// -// IntMapReduceTask(int depth, ParallelIterable<T> coll, IntMapper<? super T> mapper, int base, IntBinaryOperator operator) { -// super(depth, coll); -// this.operator = operator; -// this.base = base; -// this.mapper = mapper; -// } -// -// @Override -// public void seq() { -// value = Iterators.mapReduce(coll.iterator(), mapper, base, operator); -// } -// -// @Override -// public void combine(IntMapReduceTask<T> left, IntMapReduceTask<T> right) { -// value = operator.eval(left.value, right.value); -// } -// -// @Override -// public IntMapReduceTask<T> makeTask(int depth, ParallelIterable<T> coll) { -// return new IntMapReduceTask<>(depth, coll, mapper, base, operator); -// } -// } -// -// private static class LongMapReduceTask<T> extends BaseTask<T, LongMapReduceTask<T>> { -// private static final long serialVersionUID = 1L; -// public final LongBinaryOperator operator; -// public final LongMapper<? super T> mapper; -// public final long base; -// public long value; -// -// LongMapReduceTask(int depth, ParallelIterable<T> coll, LongMapper<? super T> mapper, long base, LongBinaryOperator operator) { -// super(depth, coll); -// this.operator = operator; -// this.base = base; -// this.mapper = mapper; -// } -// -// @Override -// public void seq() { -// value = Iterators.mapReduce(coll.iterator(), mapper, base, operator); -// } -// -// @Override -// public void combine(LongMapReduceTask<T> left, LongMapReduceTask<T> right) { -// value = operator.eval(left.value, right.value); -// } -// -// @Override -// public LongMapReduceTask<T> makeTask(int depth, ParallelIterable<T> coll) { -// return new LongMapReduceTask<>(depth, coll, mapper, base, operator); -// } -// } -// -// private static class DoubleMapReduceTask<T> extends BaseTask<T, DoubleMapReduceTask<T>> { -// private static final long serialVersionUID = 1L; -// public final DoubleBinaryOperator operator; -// public final DoubleMapper<? super T> mapper; -// public final double base; -// public double value; -// -// DoubleMapReduceTask(int depth, ParallelIterable<T> coll, DoubleMapper<? super T> mapper, double base, DoubleBinaryOperator operator) { -// super(depth, coll); -// this.operator = operator; -// this.base = base; -// this.mapper = mapper; -// } -// -// @Override -// public void seq() { -// value = Iterators.mapReduce(coll.iterator(), mapper, base, operator); -// } -// -// @Override -// public void combine(DoubleMapReduceTask<T> left, DoubleMapReduceTask<T> right) { -// value = operator.eval(left.value, right.value); -// } -// -// @Override -// public DoubleMapReduceTask<T> makeTask(int depth, ParallelIterable<T> coll) { -// return new DoubleMapReduceTask<>(depth, coll, mapper, base, operator); -// } -// } -// -// /** -// * Reduce elements to a single value. -// * -// * @param <T> Type of elements -// * @param pi The source of elements. -// * @param operator Reduces elements to a result of type {@code U}. -// * @param base Initial value for reducer. -// * @return The reduced value of the elements. -// */ -// public static <T> T reduce(ParallelIterable<T> pi, T base, BinaryOperator<T> operator) { -// Objects.requireNonNull(pi); -// Objects.requireNonNull(operator); -// ReduceTask<T> task = new ReduceTask<>(calculateDepth(pi.estimateCount()), pi, base, operator); -// ForkJoinUtils.defaultFJPool().invoke(task); -// return task.value; -// } -// -// public static <T, U> U mapReduce(ParallelIterable<T> pi, Mapper<? super T, ? extends U> mapper, U base, BinaryOperator<U> operator) { -// Objects.requireNonNull(pi); -// Objects.requireNonNull(mapper); -// Objects.requireNonNull(operator); -// MapReduceTask<T, U> task = new MapReduceTask<>(calculateDepth(pi.estimateCount()), pi, mapper, base, operator); -// ForkJoinUtils.defaultFJPool().invoke(task); -// return task.value; -// } -// -// public static<T> int mapReduce(ParallelIterable<T> pi, IntMapper<? super T> mapper, int base, IntBinaryOperator operator) { -// Objects.requireNonNull(pi); -// Objects.requireNonNull(mapper); -// Objects.requireNonNull(operator); -// IntMapReduceTask<T> task = new IntMapReduceTask<>(calculateDepth(pi.estimateCount()), pi, mapper, base, operator); -// ForkJoinUtils.defaultFJPool().invoke(task); -// return task.value; -// } -// -// public static<T> long mapReduce(ParallelIterable<T> pi, LongMapper<? super T> mapper, long base, LongBinaryOperator operator) { -// Objects.requireNonNull(pi); -// Objects.requireNonNull(mapper); -// Objects.requireNonNull(operator); -// LongMapReduceTask<T> task = new LongMapReduceTask<>(calculateDepth(pi.estimateCount()), pi, mapper, base, operator); -// ForkJoinUtils.defaultFJPool().invoke(task); -// return task.value; -// } -// -// public static<T> double mapReduce(ParallelIterable<T> pi, DoubleMapper<? super T> mapper, double base, DoubleBinaryOperator operator) { -// Objects.requireNonNull(pi); -// Objects.requireNonNull(mapper); -// Objects.requireNonNull(operator); -// DoubleMapReduceTask<T> task = new DoubleMapReduceTask<>(calculateDepth(pi.estimateCount()), pi, mapper, base, operator); -// ForkJoinUtils.defaultFJPool().invoke(task); -// return task.value; -// } -// -// /** -// * All elements of the Iterable are added to the specified container. This version of into() takes -// * an ordinary Fillable, which is not known to support concurrent addition. So this version takes -// * a lock on the container while inserting. The into(ParallelFillable) version (not yet written) -// * does not have this limitation. -// * -// * @param <T> Type of elements -// * @param <A> -// * @param pi The source of elements. -// * @param target The collection other container into which the elements are added. -// * @return The provided container. -// */ -// public static <T, A extends Fillable<? super T>> A into(ParallelIterable<T> pi, final A target) { -// Objects.requireNonNull(pi); -// Objects.requireNonNull(target); -// -// ForkJoinUtils.defaultFJPool().invoke(new IntoTask<>(calculateDepth(pi.estimateCount()), pi, target)); -// return target; -// } -// -// private static class IntoTask<T> extends BaseTask<T, IntoTask<T>> { -// private final Fillable<? super T> target; -// -// IntoTask(int depth, ParallelIterable<T> coll, Fillable<? super T> target) { -// super(depth, coll); -// this.target = target; -// } -// -// @Override -// public void seq() { -// // Do the computation before we take the lock by draining into a -// // temporary collection, allowing computation to happen in parallel -// Iterable<T> drained = Iterators.drain(coll.iterator()); -// synchronized (target) { -// target.addAll(drained); -// } -// } -// -// @Override -// public IntoTask<T> makeTask(int depth, ParallelIterable<T> coll) { -// return new IntoTask<>(depth, coll, target); -// } -// } -// -// // TODO: better short-circuiting -// private static class MatchTask<T> extends BaseTask<T, MatchTask<T>> { -// private static final long serialVersionUID = 1L; -// enum Kind { ANY, ALL, NONE }; -// public final Predicate<? super T> predicate; -// public final Kind kind; -// public boolean value; -// -// MatchTask(int depth, ParallelIterable<T> coll, Predicate<? super T> predicate, Kind kind) { -// super(depth, coll); -// this.predicate = predicate; -// this.kind = kind; -// } -// -// @Override -// public void seq() { -// switch (kind) { -// case ANY: value = Iterators.anyMatch(coll.iterator(), predicate); break; -// case ALL: value = Iterators.allMatch(coll.iterator(), predicate); break; -// case NONE: value = Iterators.noneMatch(coll.iterator(), predicate); break; -// } -// } -// -// @Override -// public void combine(MatchTask<T> left, MatchTask<T> right) { -// switch (kind) { -// case ANY: value = left.value || right.value; break; -// case ALL: value = left.value && right.value; break; -// case NONE: value = left.value && right.value; break; -// } -// } -// -// @Override -// public MatchTask<T> makeTask(int depth, ParallelIterable<T> coll) { -// return new MatchTask<>(depth, coll, predicate, kind); -// } -// } -// -// public static <T> boolean anyMatch(ParallelIterable<T> pi, Predicate<? super T> predicate) { -// Objects.requireNonNull(pi); -// Objects.requireNonNull(predicate); -// MatchTask<T> task = new MatchTask<>(calculateDepth(pi.estimateCount()), pi, predicate, MatchTask.Kind.ANY); -// ForkJoinUtils.defaultFJPool().invoke(task); -// return task.value; -// } -// -// public static <T> boolean noneMatch(ParallelIterable<T> pi, Predicate<? super T> predicate) { -// Objects.requireNonNull(pi); -// Objects.requireNonNull(predicate); -// MatchTask<T> task = new MatchTask<>(calculateDepth(pi.estimateCount()), pi, predicate, MatchTask.Kind.NONE); -// ForkJoinUtils.defaultFJPool().invoke(task); -// return task.value; -// } -// -// public static <T> boolean allMatch(ParallelIterable<T> pi, Predicate<? super T> predicate) { -// Objects.requireNonNull(pi); -// Objects.requireNonNull(predicate); -// MatchTask<T> task = new MatchTask<>(calculateDepth(pi.estimateCount()), pi, predicate, MatchTask.Kind.ALL); -// ForkJoinUtils.defaultFJPool().invoke(task); -// return task.value; -// } -// -// public static<T extends Comparable<? super T>> ParallelIterable<T> sorted(ParallelIterable<T> pi) { -// Objects.requireNonNull(pi); -// -// throw new UnsupportedOperationException("nyi"); -// } -// -// public static<T> ParallelIterable<T> sorted(ParallelIterable<T> pi, final Comparator<? super T> comparator) { -// Objects.requireNonNull(pi); -// Objects.requireNonNull(comparator); -// throw new UnsupportedOperationException("nyi"); -// } -// -// public static<T> ParallelIterable<T> uniqueElements(ParallelIterable<T> pi) { -// Objects.requireNonNull(pi); -// throw new UnsupportedOperationException("nyi"); -// } -}
--- a/src/share/classes/java/util/StringJoiner.java Tue Sep 04 10:52:18 2012 -0400 +++ b/src/share/classes/java/util/StringJoiner.java Tue Sep 04 11:33:42 2012 -0400 @@ -64,7 +64,7 @@ * @author Jim Gish * @since 1.8 */ -public class StringJoiner implements Fillable<CharSequence>, CharSequence { +public class StringJoiner implements Stream.Destination<CharSequence>, CharSequence { private static final String PREFIX_IS_NULL_MSG = "The prefix must not be null"; private static final String INFIX_IS_NULL_MSG = "The infix delimiter must not be null";
--- a/src/share/classes/java/util/streams/LinearPipeline.java Tue Sep 04 10:52:18 2012 -0400 +++ b/src/share/classes/java/util/streams/LinearPipeline.java Tue Sep 04 11:33:42 2012 -0400 @@ -25,7 +25,6 @@ package java.util.streams; import java.util.Comparator; -import java.util.Fillable; import java.util.Map; import java.util.Optional; import java.util.functions.*; @@ -100,7 +99,7 @@ } @Override - public <A extends Fillable<? super U>> A into(A target) { + public <A extends Destination<? super U>> A into(A target) { target.addAll(this); return target; }
--- a/src/share/classes/java/util/streams/MapPipeline.java Tue Sep 04 10:52:18 2012 -0400 +++ b/src/share/classes/java/util/streams/MapPipeline.java Tue Sep 04 11:33:42 2012 -0400 @@ -73,6 +73,12 @@ } @Override + public <A extends Destination<K, V>> A into(A target) { + target.addAll(this); + return target; + } + + @Override public MapStream<K, V> tee(BiBlock<? super K, ? super V> block) { return chainMap(new BiTeeOp<>(block)); } @@ -82,12 +88,6 @@ } @Override - public <A extends Map<K, V>> A into(A target) { - forEach(target::put); - return target; - } - - @Override public Stream<K> keys() { return chainLinear(new MapExtractKeysOp<K,V>()); }
--- a/src/share/classes/java/util/streams/MapStream.java Tue Sep 04 10:52:18 2012 -0400 +++ b/src/share/classes/java/util/streams/MapStream.java Tue Sep 04 11:33:42 2012 -0400 @@ -131,8 +131,7 @@ */ MapStream<K, V> tee(BiBlock<? super K, ? super V> block); - // @@@ Map, or MapFillable? - <A extends Map<K, V>> A into(A target); + <A extends MapStream.Destination<K, V>> A into(A target); /** * Any of the elements of this map stream return {@code true} for the @@ -196,4 +195,14 @@ MapStream<V, K> swap(); MapStream<K, V> sequential(); + + /** + * An aggregate that supports an {@code add(T)} operation. + * + * @param <K> Type of aggregate elements. + * @param <V> Type of aggregate elements. + */ + interface Destination<K,V> { + public void addAll(MapStream<? extends K, ? extends V> stream); + } }
--- a/src/share/classes/java/util/streams/Stream.java Tue Sep 04 10:52:18 2012 -0400 +++ b/src/share/classes/java/util/streams/Stream.java Tue Sep 04 11:33:42 2012 -0400 @@ -103,7 +103,7 @@ Stream<T> tee(Block<? super T> sink); - <A extends Fillable<? super T>> A into(A target); + <A extends Destination<? super T>> A into(A target); Object[] toArray(); @@ -128,4 +128,14 @@ Stream<T> sequential(); <U> MapStream<T, U> mapped(Mapper<? super T, ? extends U> mapper); + + + /** + * An aggregate that supports an {@code add(T)} operation. + * + * @param <T> Type of aggregate elements. + */ + interface Destination<T> { + public void addAll(Stream<? extends T> stream); + } }