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);
+    }
 }