< prev index next >

src/java.base/share/classes/java/util/stream/StreamSpliterators.java

Print this page
rev 47749 : 8190974: Parallel stream execution within a custom ForkJoinPool should obey the parallelism
Reviewed-by: martin, tvaleev
   1 /*
   2  * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 880             protected Spliterator.OfDouble makeSpliterator(Spliterator.OfDouble s,
 881                                                            long sliceOrigin, long sliceFence,
 882                                                            long origin, long fence) {
 883                 return new SliceSpliterator.OfDouble(s, sliceOrigin, sliceFence, origin, fence);
 884             }
 885 
 886             @Override
 887             protected DoubleConsumer emptyConsumer() {
 888                 return e -> {};
 889             }
 890         }
 891     }
 892 
 893     /**
 894      * A slice Spliterator that does not preserve order, if any, of a source
 895      * Spliterator.
 896      *
 897      * Note: The source spliterator may report {@code ORDERED} since that
 898      * spliterator be the result of a previous pipeline stage that was
 899      * collected to a {@code Node}. It is the order of the pipeline stage
 900      * that governs whether the this slice spliterator is to be used or not.
 901      */
 902     abstract static class UnorderedSliceSpliterator<T, T_SPLITR extends Spliterator<T>> {
 903         static final int CHUNK_SIZE = 1 << 7;
 904 
 905         // The spliterator to slice
 906         protected final T_SPLITR s;
 907         protected final boolean unlimited;
 908         protected final int chunkSize;
 909         private final long skipThreshold;
 910         private final AtomicLong permits;
 911 
 912         UnorderedSliceSpliterator(T_SPLITR s, long skip, long limit) {
 913             this.s = s;
 914             this.unlimited = limit < 0;
 915             this.skipThreshold = limit >= 0 ? limit : 0;
 916             this.chunkSize = limit >= 0 ? (int)Math.min(CHUNK_SIZE,
 917                 ((skip + limit) / AbstractTask.LEAF_TARGET) + 1) : CHUNK_SIZE;
 918             this.permits = new AtomicLong(limit >= 0 ? skip + limit : skip);
 919         }
 920 
 921         UnorderedSliceSpliterator(T_SPLITR s,
 922                                   UnorderedSliceSpliterator<T, T_SPLITR> parent) {
 923             this.s = s;
 924             this.unlimited = parent.unlimited;
 925             this.permits = parent.permits;
 926             this.skipThreshold = parent.skipThreshold;
 927             this.chunkSize = parent.chunkSize;
 928         }
 929 
 930         /**
 931          * Acquire permission to skip or process elements.  The caller must
 932          * first acquire the elements, then consult this method for guidance
 933          * as to what to do with the data.
 934          *
 935          * <p>We use an {@code AtomicLong} to atomically maintain a counter,
 936          * which is initialized as skip+limit if we are limiting, or skip only
 937          * if we are not limiting.  The user should consult the method


   1 /*
   2  * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 880             protected Spliterator.OfDouble makeSpliterator(Spliterator.OfDouble s,
 881                                                            long sliceOrigin, long sliceFence,
 882                                                            long origin, long fence) {
 883                 return new SliceSpliterator.OfDouble(s, sliceOrigin, sliceFence, origin, fence);
 884             }
 885 
 886             @Override
 887             protected DoubleConsumer emptyConsumer() {
 888                 return e -> {};
 889             }
 890         }
 891     }
 892 
 893     /**
 894      * A slice Spliterator that does not preserve order, if any, of a source
 895      * Spliterator.
 896      *
 897      * Note: The source spliterator may report {@code ORDERED} since that
 898      * spliterator be the result of a previous pipeline stage that was
 899      * collected to a {@code Node}. It is the order of the pipeline stage
 900      * that governs whether this slice spliterator is to be used or not.
 901      */
 902     abstract static class UnorderedSliceSpliterator<T, T_SPLITR extends Spliterator<T>> {
 903         static final int CHUNK_SIZE = 1 << 7;
 904 
 905         // The spliterator to slice
 906         protected final T_SPLITR s;
 907         protected final boolean unlimited;
 908         protected final int chunkSize;
 909         private final long skipThreshold;
 910         private final AtomicLong permits;
 911 
 912         UnorderedSliceSpliterator(T_SPLITR s, long skip, long limit) {
 913             this.s = s;
 914             this.unlimited = limit < 0;
 915             this.skipThreshold = limit >= 0 ? limit : 0;
 916             this.chunkSize = limit >= 0 ? (int)Math.min(CHUNK_SIZE,
 917                                                         ((skip + limit) / AbstractTask.getLeafTarget()) + 1) : CHUNK_SIZE;
 918             this.permits = new AtomicLong(limit >= 0 ? skip + limit : skip);
 919         }
 920 
 921         UnorderedSliceSpliterator(T_SPLITR s,
 922                                   UnorderedSliceSpliterator<T, T_SPLITR> parent) {
 923             this.s = s;
 924             this.unlimited = parent.unlimited;
 925             this.permits = parent.permits;
 926             this.skipThreshold = parent.skipThreshold;
 927             this.chunkSize = parent.chunkSize;
 928         }
 929 
 930         /**
 931          * Acquire permission to skip or process elements.  The caller must
 932          * first acquire the elements, then consult this method for guidance
 933          * as to what to do with the data.
 934          *
 935          * <p>We use an {@code AtomicLong} to atomically maintain a counter,
 936          * which is initialized as skip+limit if we are limiting, or skip only
 937          * if we are not limiting.  The user should consult the method


< prev index next >