1ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin/* 2ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 3ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 5ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * This code is free software; you can redistribute it and/or modify it 6ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * under the terms of the GNU General Public License version 2 only, as 7ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * published by the Free Software Foundation. Oracle designates this 8ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * particular file as subject to the "Classpath" exception as provided 9ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * by Oracle in the LICENSE file that accompanied this code. 10ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 11ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * This code is distributed in the hope that it will be useful, but WITHOUT 12ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * version 2 for more details (a copy is included in the LICENSE file that 15ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * accompanied this code). 16ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 17ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * You should have received a copy of the GNU General Public License version 18ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 2 along with this work; if not, write to the Free Software Foundation, 19ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 21ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * or visit www.oracle.com if you need additional information or have any 23ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * questions. 24ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 25ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinpackage java.util.stream; 26ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 27ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.Comparator; 28ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.Objects; 29ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.Spliterator; 30ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.concurrent.ConcurrentHashMap; 31ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.concurrent.atomic.AtomicLong; 32ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.function.BooleanSupplier; 33ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.function.Consumer; 34ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.function.DoubleConsumer; 35ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.function.DoubleSupplier; 36ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.function.IntConsumer; 37ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.function.IntSupplier; 38ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.function.LongConsumer; 39ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.function.LongSupplier; 40ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.function.Supplier; 41ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 42ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin/** 43ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Spliterator implementations for wrapping and delegating spliterators, used 44ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * in the implementation of the {@link Stream#spliterator()} method. 45ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 46ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @since 1.8 47ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 48ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinclass StreamSpliterators { 49ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 50ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 51ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Abstract wrapping spliterator that binds to the spliterator of a 52ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * pipeline helper on first operation. 53ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 54ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * <p>This spliterator is not late-binding and will bind to the source 55ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * spliterator when first operated on. 56ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 57ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * <p>A wrapping spliterator produced from a sequential stream 58ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * cannot be split if there are stateful operations present. 59ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 60ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static abstract class AbstractWrappingSpliterator<P_IN, P_OUT, 61ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T_BUFFER extends AbstractSpinedBuffer> 62ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator<P_OUT> { 63ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 64ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // @@@ Detect if stateful operations are present or not 65ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // If not then can split otherwise cannot 66ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 67ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 68ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * True if this spliterator supports splitting 69ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 70ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin final boolean isParallel; 71ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 72ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin final PipelineHelper<P_OUT> ph; 73ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 74ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 75ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Supplier for the source spliterator. Client provides either a 76ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * spliterator or a supplier. 77ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 78ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private Supplier<Spliterator<P_IN>> spliteratorSupplier; 79ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 80ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 81ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Source spliterator. Either provided from client or obtained from 82ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * supplier. 83ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 84ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Spliterator<P_IN> spliterator; 85ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 86ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 87ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Sink chain for the downstream stages of the pipeline, ultimately 88ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * leading to the buffer. Used during partial traversal. 89ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 90ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Sink<P_IN> bufferSink; 91ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 92ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 93ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * A function that advances one element of the spliterator, pushing 94ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * it to bufferSink. Returns whether any elements were processed. 95ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Used during partial traversal. 96ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 97ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin BooleanSupplier pusher; 98ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 99ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** Next element to consume from the buffer, used during partial traversal */ 100ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long nextToConsume; 101ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 102ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** Buffer into which elements are pushed. Used during partial traversal. */ 103ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T_BUFFER buffer; 104ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 105ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 106ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * True if full traversal has occurred (with possible cancelation). 107ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * If doing a partial traversal, there may be still elements in buffer. 108ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 109ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin boolean finished; 110ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 111ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 112ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Construct an AbstractWrappingSpliterator from a 113ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * {@code Supplier<Spliterator>}. 114ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 115ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin AbstractWrappingSpliterator(PipelineHelper<P_OUT> ph, 116ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Supplier<Spliterator<P_IN>> spliteratorSupplier, 117ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin boolean parallel) { 118ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.ph = ph; 119ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.spliteratorSupplier = spliteratorSupplier; 120ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.spliterator = null; 121ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.isParallel = parallel; 122ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 123ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 124ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 125ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Construct an AbstractWrappingSpliterator from a 126ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * {@code Spliterator}. 127ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 128ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin AbstractWrappingSpliterator(PipelineHelper<P_OUT> ph, 129ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Spliterator<P_IN> spliterator, 130ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin boolean parallel) { 131ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.ph = ph; 132ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.spliteratorSupplier = null; 133ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.spliterator = spliterator; 134ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.isParallel = parallel; 135ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 136ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 137ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 138ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Called before advancing to set up spliterator, if needed. 139ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 140ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin final void init() { 141ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (spliterator == null) { 142ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin spliterator = spliteratorSupplier.get(); 143ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin spliteratorSupplier = null; 144ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 145ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 146ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 147ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 148ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Get an element from the source, pushing it into the sink chain, 149ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * setting up the buffer if needed 150ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return whether there are elements to consume from the buffer 151ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 152ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin final boolean doAdvance() { 153ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (buffer == null) { 154ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (finished) 155ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return false; 156ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 157ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin init(); 158ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin initPartialTraversalState(); 159ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin nextToConsume = 0; 160ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin bufferSink.begin(spliterator.getExactSizeIfKnown()); 161ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return fillBuffer(); 162ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 163ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else { 164ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin ++nextToConsume; 165ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin boolean hasNext = nextToConsume < buffer.count(); 166ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (!hasNext) { 167ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin nextToConsume = 0; 168ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin buffer.clear(); 169ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin hasNext = fillBuffer(); 170ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 171ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return hasNext; 172ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 173ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 174ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 175ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 176ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Invokes the shape-specific constructor with the provided arguments 177ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * and returns the result. 178ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 179ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin abstract AbstractWrappingSpliterator<P_IN, P_OUT, ?> wrap(Spliterator<P_IN> s); 180ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 181ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 182ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Initializes buffer, sink chain, and pusher for a shape-specific 183ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * implementation. 184ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 185ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin abstract void initPartialTraversalState(); 186ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 187ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 188ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator<P_OUT> trySplit() { 189ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (isParallel && !finished) { 190ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin init(); 191ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 192ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Spliterator<P_IN> split = spliterator.trySplit(); 193ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return (split == null) ? null : wrap(split); 194ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 195ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else 196ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return null; 197ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 198ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 199ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 200ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * If the buffer is empty, push elements into the sink chain until 201ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * the source is empty or cancellation is requested. 202ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return whether there are elements to consume from the buffer 203ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 204ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private boolean fillBuffer() { 205ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin while (buffer.count() == 0) { 206ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (bufferSink.cancellationRequested() || !pusher.getAsBoolean()) { 207ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (finished) 208ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return false; 209ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else { 210ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin bufferSink.end(); // might trigger more elements 211ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin finished = true; 212ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 213ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 214ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 215ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return true; 216ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 217ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 218ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 219ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public final long estimateSize() { 220ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin init(); 221ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Use the estimate of the wrapped spliterator 222ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Note this may not be accurate if there are filter/flatMap 223ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // operations filtering or adding elements to the stream 224ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return spliterator.estimateSize(); 225ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 226ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 227ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 228ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public final long getExactSizeIfKnown() { 229ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin init(); 230ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return StreamOpFlag.SIZED.isKnown(ph.getStreamAndOpFlags()) 231ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin ? spliterator.getExactSizeIfKnown() 232ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin : -1; 233ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 234ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 235ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 236ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public final int characteristics() { 237ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin init(); 238ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 239ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Get the characteristics from the pipeline 240ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin int c = StreamOpFlag.toCharacteristics(StreamOpFlag.toStreamFlags(ph.getStreamAndOpFlags())); 241ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 242ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Mask off the size and uniform characteristics and replace with 243ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // those of the spliterator 244ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Note that a non-uniform spliterator can change from something 245ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // with an exact size to an estimate for a sub-split, for example 246ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // with HashSet where the size is known at the top level spliterator 247ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // but for sub-splits only an estimate is known 248ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if ((c & Spliterator.SIZED) != 0) { 249ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin c &= ~(Spliterator.SIZED | Spliterator.SUBSIZED); 250ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin c |= (spliterator.characteristics() & (Spliterator.SIZED | Spliterator.SUBSIZED)); 251ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 252ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 253ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return c; 254ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 255ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 256ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 257ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Comparator<? super P_OUT> getComparator() { 258ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (!hasCharacteristics(SORTED)) 259ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalStateException(); 260ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return null; 261ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 262ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 263ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 264ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public final String toString() { 265ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return String.format("%s[%s]", getClass().getName(), spliterator); 266ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 267ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 268ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 269ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class WrappingSpliterator<P_IN, P_OUT> 270ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends AbstractWrappingSpliterator<P_IN, P_OUT, SpinedBuffer<P_OUT>> { 271ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 272ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin WrappingSpliterator(PipelineHelper<P_OUT> ph, 273ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Supplier<Spliterator<P_IN>> supplier, 274ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin boolean parallel) { 275ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(ph, supplier, parallel); 276ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 277ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 278ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin WrappingSpliterator(PipelineHelper<P_OUT> ph, 279ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Spliterator<P_IN> spliterator, 280ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin boolean parallel) { 281ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(ph, spliterator, parallel); 282ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 283ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 284ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 285ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin WrappingSpliterator<P_IN, P_OUT> wrap(Spliterator<P_IN> s) { 286ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new WrappingSpliterator<>(ph, s, isParallel); 287ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 288ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 289ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 290ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin void initPartialTraversalState() { 291ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin SpinedBuffer<P_OUT> b = new SpinedBuffer<>(); 292ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin buffer = b; 293ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin bufferSink = ph.wrapSink(b::accept); 294ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin pusher = () -> spliterator.tryAdvance(bufferSink); 295ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 296ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 297ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 298ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public boolean tryAdvance(Consumer<? super P_OUT> consumer) { 299ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Objects.requireNonNull(consumer); 300ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin boolean hasNext = doAdvance(); 301ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (hasNext) 302ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin consumer.accept(buffer.get(nextToConsume)); 303ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return hasNext; 304ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 305ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 306ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 307ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEachRemaining(Consumer<? super P_OUT> consumer) { 308ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (buffer == null && !finished) { 309ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Objects.requireNonNull(consumer); 310ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin init(); 311ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 312ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin ph.wrapAndCopyInto((Sink<P_OUT>) consumer::accept, spliterator); 313ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin finished = true; 314ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 315ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else { 316ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin do { } while (tryAdvance(consumer)); 317ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 318ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 319ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 320ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 321ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class IntWrappingSpliterator<P_IN> 322ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends AbstractWrappingSpliterator<P_IN, Integer, SpinedBuffer.OfInt> 323ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator.OfInt { 324ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 325ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin IntWrappingSpliterator(PipelineHelper<Integer> ph, 326ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Supplier<Spliterator<P_IN>> supplier, 327ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin boolean parallel) { 328ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(ph, supplier, parallel); 329ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 330ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 331ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin IntWrappingSpliterator(PipelineHelper<Integer> ph, 332ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Spliterator<P_IN> spliterator, 333ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin boolean parallel) { 334ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(ph, spliterator, parallel); 335ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 336ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 337ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 338ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin AbstractWrappingSpliterator<P_IN, Integer, ?> wrap(Spliterator<P_IN> s) { 339ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new IntWrappingSpliterator<>(ph, s, isParallel); 340ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 341ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 342ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 343ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin void initPartialTraversalState() { 344ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin SpinedBuffer.OfInt b = new SpinedBuffer.OfInt(); 345ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin buffer = b; 346ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin bufferSink = ph.wrapSink((Sink.OfInt) b::accept); 347ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin pusher = () -> spliterator.tryAdvance(bufferSink); 348ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 349ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 350ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 351ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator.OfInt trySplit() { 352ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return (Spliterator.OfInt) super.trySplit(); 353ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 354ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 355ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 356ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public boolean tryAdvance(IntConsumer consumer) { 357ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Objects.requireNonNull(consumer); 358ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin boolean hasNext = doAdvance(); 359ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (hasNext) 360ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin consumer.accept(buffer.get(nextToConsume)); 361ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return hasNext; 362ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 363ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 364ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 365ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEachRemaining(IntConsumer consumer) { 366ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (buffer == null && !finished) { 367ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Objects.requireNonNull(consumer); 368ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin init(); 369ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 370ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin ph.wrapAndCopyInto((Sink.OfInt) consumer::accept, spliterator); 371ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin finished = true; 372ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 373ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else { 374ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin do { } while (tryAdvance(consumer)); 375ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 376ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 377ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 378ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 379ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class LongWrappingSpliterator<P_IN> 380ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends AbstractWrappingSpliterator<P_IN, Long, SpinedBuffer.OfLong> 381ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator.OfLong { 382ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 383ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin LongWrappingSpliterator(PipelineHelper<Long> ph, 384ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Supplier<Spliterator<P_IN>> supplier, 385ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin boolean parallel) { 386ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(ph, supplier, parallel); 387ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 388ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 389ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin LongWrappingSpliterator(PipelineHelper<Long> ph, 390ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Spliterator<P_IN> spliterator, 391ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin boolean parallel) { 392ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(ph, spliterator, parallel); 393ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 394ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 395ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 396ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin AbstractWrappingSpliterator<P_IN, Long, ?> wrap(Spliterator<P_IN> s) { 397ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new LongWrappingSpliterator<>(ph, s, isParallel); 398ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 399ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 400ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 401ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin void initPartialTraversalState() { 402ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin SpinedBuffer.OfLong b = new SpinedBuffer.OfLong(); 403ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin buffer = b; 404ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin bufferSink = ph.wrapSink((Sink.OfLong) b::accept); 405ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin pusher = () -> spliterator.tryAdvance(bufferSink); 406ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 407ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 408ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 409ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator.OfLong trySplit() { 410ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return (Spliterator.OfLong) super.trySplit(); 411ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 412ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 413ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 414ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public boolean tryAdvance(LongConsumer consumer) { 415ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Objects.requireNonNull(consumer); 416ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin boolean hasNext = doAdvance(); 417ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (hasNext) 418ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin consumer.accept(buffer.get(nextToConsume)); 419ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return hasNext; 420ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 421ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 422ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 423ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEachRemaining(LongConsumer consumer) { 424ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (buffer == null && !finished) { 425ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Objects.requireNonNull(consumer); 426ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin init(); 427ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 428ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin ph.wrapAndCopyInto((Sink.OfLong) consumer::accept, spliterator); 429ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin finished = true; 430ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 431ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else { 432ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin do { } while (tryAdvance(consumer)); 433ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 434ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 435ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 436ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 437ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class DoubleWrappingSpliterator<P_IN> 438ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends AbstractWrappingSpliterator<P_IN, Double, SpinedBuffer.OfDouble> 439ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator.OfDouble { 440ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 441ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin DoubleWrappingSpliterator(PipelineHelper<Double> ph, 442ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Supplier<Spliterator<P_IN>> supplier, 443ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin boolean parallel) { 444ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(ph, supplier, parallel); 445ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 446ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 447ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin DoubleWrappingSpliterator(PipelineHelper<Double> ph, 448ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Spliterator<P_IN> spliterator, 449ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin boolean parallel) { 450ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(ph, spliterator, parallel); 451ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 452ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 453ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 454ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin AbstractWrappingSpliterator<P_IN, Double, ?> wrap(Spliterator<P_IN> s) { 455ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new DoubleWrappingSpliterator<>(ph, s, isParallel); 456ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 457ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 458ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 459ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin void initPartialTraversalState() { 460ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin SpinedBuffer.OfDouble b = new SpinedBuffer.OfDouble(); 461ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin buffer = b; 462ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin bufferSink = ph.wrapSink((Sink.OfDouble) b::accept); 463ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin pusher = () -> spliterator.tryAdvance(bufferSink); 464ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 465ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 466ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 467ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator.OfDouble trySplit() { 468ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return (Spliterator.OfDouble) super.trySplit(); 469ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 470ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 471ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 472ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public boolean tryAdvance(DoubleConsumer consumer) { 473ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Objects.requireNonNull(consumer); 474ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin boolean hasNext = doAdvance(); 475ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (hasNext) 476ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin consumer.accept(buffer.get(nextToConsume)); 477ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return hasNext; 478ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 479ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 480ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 481ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEachRemaining(DoubleConsumer consumer) { 482ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (buffer == null && !finished) { 483ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Objects.requireNonNull(consumer); 484ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin init(); 485ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 486ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin ph.wrapAndCopyInto((Sink.OfDouble) consumer::accept, spliterator); 487ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin finished = true; 488ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 489ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else { 490ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin do { } while (tryAdvance(consumer)); 491ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 492ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 493ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 494ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 495ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 496ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Spliterator implementation that delegates to an underlying spliterator, 497ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * acquiring the spliterator from a {@code Supplier<Spliterator>} on the 498ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * first call to any spliterator method. 499ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param <T> 500ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 501ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static class DelegatingSpliterator<T, T_SPLITR extends Spliterator<T>> 502ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator<T> { 503ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private final Supplier<? extends T_SPLITR> supplier; 504ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 505ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private T_SPLITR s; 506ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 507ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin DelegatingSpliterator(Supplier<? extends T_SPLITR> supplier) { 508ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.supplier = supplier; 509ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 510ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 511ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T_SPLITR get() { 512ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (s == null) { 513ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin s = supplier.get(); 514ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 515ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return s; 516ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 517ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 518ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 519ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("unchecked") 520ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public T_SPLITR trySplit() { 521ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return (T_SPLITR) get().trySplit(); 522ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 523ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 524ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 525ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public boolean tryAdvance(Consumer<? super T> consumer) { 526ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return get().tryAdvance(consumer); 527ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 528ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 529ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 530ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEachRemaining(Consumer<? super T> consumer) { 531ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin get().forEachRemaining(consumer); 532ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 533ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 534ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 535ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public long estimateSize() { 536ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return get().estimateSize(); 537ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 538ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 539ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 540ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public int characteristics() { 541ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return get().characteristics(); 542ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 543ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 544ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 545ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Comparator<? super T> getComparator() { 546ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return get().getComparator(); 547ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 548ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 549ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 550ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public long getExactSizeIfKnown() { 551ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return get().getExactSizeIfKnown(); 552ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 553ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 554ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 555ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public String toString() { 556ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return getClass().getName() + "[" + get() + "]"; 557ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 558ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 559ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static class OfPrimitive<T, T_CONS, T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>> 560ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends DelegatingSpliterator<T, T_SPLITR> 561ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator.OfPrimitive<T, T_CONS, T_SPLITR> { 562ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfPrimitive(Supplier<? extends T_SPLITR> supplier) { 563ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(supplier); 564ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 565ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 566ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 567ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public boolean tryAdvance(T_CONS consumer) { 568ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return get().tryAdvance(consumer); 569ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 570ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 571ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 572ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEachRemaining(T_CONS consumer) { 573ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin get().forEachRemaining(consumer); 574ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 575ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 576ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 577ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfInt 578ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends OfPrimitive<Integer, IntConsumer, Spliterator.OfInt> 579ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator.OfInt { 580ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 581ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfInt(Supplier<Spliterator.OfInt> supplier) { 582ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(supplier); 583ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 584ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 585ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 586ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfLong 587ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends OfPrimitive<Long, LongConsumer, Spliterator.OfLong> 588ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator.OfLong { 589ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 590ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfLong(Supplier<Spliterator.OfLong> supplier) { 591ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(supplier); 592ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 593ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 594ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 595ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfDouble 596ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends OfPrimitive<Double, DoubleConsumer, Spliterator.OfDouble> 597ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator.OfDouble { 598ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 599ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfDouble(Supplier<Spliterator.OfDouble> supplier) { 600ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(supplier); 601ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 602ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 603ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 604ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 605ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 606ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * A slice Spliterator from a source Spliterator that reports 607ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * {@code SUBSIZED}. 608ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 609ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 610ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static abstract class SliceSpliterator<T, T_SPLITR extends Spliterator<T>> { 611ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // The start index of the slice 612ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin final long sliceOrigin; 613ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // One past the last index of the slice 614ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin final long sliceFence; 615ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 616ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // The spliterator to slice 617ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T_SPLITR s; 618ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // current (absolute) index, modified on advance/split 619ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long index; 620ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // one past last (absolute) index or sliceFence, which ever is smaller 621ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long fence; 622ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 623ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin SliceSpliterator(T_SPLITR s, long sliceOrigin, long sliceFence, long origin, long fence) { 624ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert s.hasCharacteristics(Spliterator.SUBSIZED); 625ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.s = s; 626ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.sliceOrigin = sliceOrigin; 627ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.sliceFence = sliceFence; 628ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.index = origin; 629ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.fence = fence; 630ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 631ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 632ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected abstract T_SPLITR makeSpliterator(T_SPLITR s, long sliceOrigin, long sliceFence, long origin, long fence); 633ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 634ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public T_SPLITR trySplit() { 635ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (sliceOrigin >= fence) 636ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return null; 637ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 638ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (index >= fence) 639ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return null; 640ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 641ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Keep splitting until the left and right splits intersect with the slice 642ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // thereby ensuring the size estimate decreases. 643ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // This also avoids creating empty spliterators which can result in 644ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // existing and additionally created F/J tasks that perform 645ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // redundant work on no elements. 646ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin while (true) { 647ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("unchecked") 648ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T_SPLITR leftSplit = (T_SPLITR) s.trySplit(); 649ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (leftSplit == null) 650ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return null; 651ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 652ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long leftSplitFenceUnbounded = index + leftSplit.estimateSize(); 653ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long leftSplitFence = Math.min(leftSplitFenceUnbounded, sliceFence); 654ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (sliceOrigin >= leftSplitFence) { 655ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // The left split does not intersect with, and is to the left of, the slice 656ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // The right split does intersect 657ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Discard the left split and split further with the right split 658ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin index = leftSplitFence; 659ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 660ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else if (leftSplitFence >= sliceFence) { 661ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // The right split does not intersect with, and is to the right of, the slice 662ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // The left split does intersect 663ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Discard the right split and split further with the left split 664ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin s = leftSplit; 665ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin fence = leftSplitFence; 666ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 667ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else if (index >= sliceOrigin && leftSplitFenceUnbounded <= sliceFence) { 668ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // The left split is contained within the slice, return the underlying left split 669ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Right split is contained within or intersects with the slice 670ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin index = leftSplitFence; 671ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return leftSplit; 672ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } else { 673ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // The left split intersects with the slice 674ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Right split is contained within or intersects with the slice 675ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return makeSpliterator(leftSplit, sliceOrigin, sliceFence, index, index = leftSplitFence); 676ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 677ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 678ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 679ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 680ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public long estimateSize() { 681ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return (sliceOrigin < fence) 682ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin ? fence - Math.max(sliceOrigin, index) : 0; 683ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 684ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 685ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public int characteristics() { 686ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return s.characteristics(); 687ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 688ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 689ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfRef<T> 690ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends SliceSpliterator<T, Spliterator<T>> 691ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator<T> { 692ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 693ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfRef(Spliterator<T> s, long sliceOrigin, long sliceFence) { 694ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this(s, sliceOrigin, sliceFence, 0, Math.min(s.estimateSize(), sliceFence)); 695ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 696ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 697ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private OfRef(Spliterator<T> s, 698ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long sliceOrigin, long sliceFence, long origin, long fence) { 699ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(s, sliceOrigin, sliceFence, origin, fence); 700ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 701ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 702ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 703ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected Spliterator<T> makeSpliterator(Spliterator<T> s, 704ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long sliceOrigin, long sliceFence, 705ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long origin, long fence) { 706ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new OfRef<>(s, sliceOrigin, sliceFence, origin, fence); 707ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 708ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 709ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 710ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public boolean tryAdvance(Consumer<? super T> action) { 711ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Objects.requireNonNull(action); 712ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 713ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (sliceOrigin >= fence) 714ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return false; 715ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 716ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin while (sliceOrigin > index) { 717ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin s.tryAdvance(e -> {}); 718ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin index++; 719ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 720ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 721ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (index >= fence) 722ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return false; 723ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 724ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin index++; 725ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return s.tryAdvance(action); 726ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 727ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 728ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 729ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEachRemaining(Consumer<? super T> action) { 730ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Objects.requireNonNull(action); 731ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 732ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (sliceOrigin >= fence) 733ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return; 734ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 735ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (index >= fence) 736ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return; 737ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 738ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (index >= sliceOrigin && (index + s.estimateSize()) <= sliceFence) { 739ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // The spliterator is contained within the slice 740ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin s.forEachRemaining(action); 741ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin index = fence; 742ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } else { 743ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // The spliterator intersects with the slice 744ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin while (sliceOrigin > index) { 745ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin s.tryAdvance(e -> {}); 746ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin index++; 747ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 748ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Traverse elements up to the fence 749ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin for (;index < fence; index++) { 750ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin s.tryAdvance(action); 751ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 752ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 753ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 754ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 755ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 756ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static abstract class OfPrimitive<T, 757ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>, 758ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T_CONS> 759ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends SliceSpliterator<T, T_SPLITR> 760ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator.OfPrimitive<T, T_CONS, T_SPLITR> { 761ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 762ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfPrimitive(T_SPLITR s, long sliceOrigin, long sliceFence) { 763ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this(s, sliceOrigin, sliceFence, 0, Math.min(s.estimateSize(), sliceFence)); 764ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 765ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 766ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private OfPrimitive(T_SPLITR s, 767ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long sliceOrigin, long sliceFence, long origin, long fence) { 768ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(s, sliceOrigin, sliceFence, origin, fence); 769ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 770ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 771ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 772ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public boolean tryAdvance(T_CONS action) { 773ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Objects.requireNonNull(action); 774ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 775ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (sliceOrigin >= fence) 776ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return false; 777ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 778ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin while (sliceOrigin > index) { 779ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin s.tryAdvance(emptyConsumer()); 780ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin index++; 781ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 782ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 783ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (index >= fence) 784ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return false; 785ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 786ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin index++; 787ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return s.tryAdvance(action); 788ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 789ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 790ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 791ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEachRemaining(T_CONS action) { 792ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Objects.requireNonNull(action); 793ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 794ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (sliceOrigin >= fence) 795ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return; 796ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 797ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (index >= fence) 798ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return; 799ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 800ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (index >= sliceOrigin && (index + s.estimateSize()) <= sliceFence) { 801ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // The spliterator is contained within the slice 802ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin s.forEachRemaining(action); 803ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin index = fence; 804ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } else { 805ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // The spliterator intersects with the slice 806ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin while (sliceOrigin > index) { 807ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin s.tryAdvance(emptyConsumer()); 808ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin index++; 809ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 810ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Traverse elements up to the fence 811ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin for (;index < fence; index++) { 812ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin s.tryAdvance(action); 813ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 814ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 815ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 816ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 817ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected abstract T_CONS emptyConsumer(); 818ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 819ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 820ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfInt extends OfPrimitive<Integer, Spliterator.OfInt, IntConsumer> 821ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator.OfInt { 822ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfInt(Spliterator.OfInt s, long sliceOrigin, long sliceFence) { 823ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(s, sliceOrigin, sliceFence); 824ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 825ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 826ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfInt(Spliterator.OfInt s, 827ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long sliceOrigin, long sliceFence, long origin, long fence) { 828ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(s, sliceOrigin, sliceFence, origin, fence); 829ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 830ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 831ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 832ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected Spliterator.OfInt makeSpliterator(Spliterator.OfInt s, 833ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long sliceOrigin, long sliceFence, 834ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long origin, long fence) { 835ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new SliceSpliterator.OfInt(s, sliceOrigin, sliceFence, origin, fence); 836ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 837ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 838ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 839ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected IntConsumer emptyConsumer() { 840ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return e -> {}; 841ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 842ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 843ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 844ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfLong extends OfPrimitive<Long, Spliterator.OfLong, LongConsumer> 845ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator.OfLong { 846ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfLong(Spliterator.OfLong s, long sliceOrigin, long sliceFence) { 847ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(s, sliceOrigin, sliceFence); 848ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 849ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 850ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfLong(Spliterator.OfLong s, 851ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long sliceOrigin, long sliceFence, long origin, long fence) { 852ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(s, sliceOrigin, sliceFence, origin, fence); 853ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 854ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 855ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 856ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected Spliterator.OfLong makeSpliterator(Spliterator.OfLong s, 857ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long sliceOrigin, long sliceFence, 858ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long origin, long fence) { 859ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new SliceSpliterator.OfLong(s, sliceOrigin, sliceFence, origin, fence); 860ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 861ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 862ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 863ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected LongConsumer emptyConsumer() { 864ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return e -> {}; 865ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 866ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 867ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 868ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfDouble extends OfPrimitive<Double, Spliterator.OfDouble, DoubleConsumer> 869ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator.OfDouble { 870ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfDouble(Spliterator.OfDouble s, long sliceOrigin, long sliceFence) { 871ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(s, sliceOrigin, sliceFence); 872ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 873ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 874ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfDouble(Spliterator.OfDouble s, 875ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long sliceOrigin, long sliceFence, long origin, long fence) { 876ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(s, sliceOrigin, sliceFence, origin, fence); 877ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 878ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 879ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 880ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected Spliterator.OfDouble makeSpliterator(Spliterator.OfDouble s, 881ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long sliceOrigin, long sliceFence, 882ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long origin, long fence) { 883ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new SliceSpliterator.OfDouble(s, sliceOrigin, sliceFence, origin, fence); 884ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 885ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 886ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 887ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected DoubleConsumer emptyConsumer() { 888ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return e -> {}; 889ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 890ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 891ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 892ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 893ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 894ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * A slice Spliterator that does not preserve order, if any, of a source 895ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Spliterator. 896ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 897ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Note: The source spliterator may report {@code ORDERED} since that 898ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * spliterator be the result of a previous pipeline stage that was 899ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * collected to a {@code Node}. It is the order of the pipeline stage 900ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * that governs whether the this slice spliterator is to be used or not. 901ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 902ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static abstract class UnorderedSliceSpliterator<T, T_SPLITR extends Spliterator<T>> { 903ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final int CHUNK_SIZE = 1 << 7; 904ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 905ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // The spliterator to slice 906ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected final T_SPLITR s; 907ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected final boolean unlimited; 908ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private final long skipThreshold; 909ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private final AtomicLong permits; 910ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 911ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin UnorderedSliceSpliterator(T_SPLITR s, long skip, long limit) { 912ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.s = s; 913ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.unlimited = limit < 0; 914ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.skipThreshold = limit >= 0 ? limit : 0; 915ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.permits = new AtomicLong(limit >= 0 ? skip + limit : skip); 916ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 917ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 918ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin UnorderedSliceSpliterator(T_SPLITR s, 919ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin UnorderedSliceSpliterator<T, T_SPLITR> parent) { 920ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.s = s; 921ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.unlimited = parent.unlimited; 922ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.permits = parent.permits; 923ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.skipThreshold = parent.skipThreshold; 924ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 925ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 926ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 927ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Acquire permission to skip or process elements. The caller must 928ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * first acquire the elements, then consult this method for guidance 929ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * as to what to do with the data. 930ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 931ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * <p>We use an {@code AtomicLong} to atomically maintain a counter, 932ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * which is initialized as skip+limit if we are limiting, or skip only 933ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * if we are not limiting. The user should consult the method 934ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * {@code checkPermits()} before acquiring data elements. 935ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 936ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param numElements the number of elements the caller has in hand 937ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return the number of elements that should be processed; any 938ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * remaining elements should be discarded. 939ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 940ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected final long acquirePermits(long numElements) { 941ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long remainingPermits; 942ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long grabbing; 943ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // permits never increase, and don't decrease below zero 944ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert numElements > 0; 945ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin do { 946ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin remainingPermits = permits.get(); 947ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (remainingPermits == 0) 948ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return unlimited ? numElements : 0; 949ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin grabbing = Math.min(remainingPermits, numElements); 950ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } while (grabbing > 0 && 951ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin !permits.compareAndSet(remainingPermits, remainingPermits - grabbing)); 952ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 953ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (unlimited) 954ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return Math.max(numElements - grabbing, 0); 955ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else if (remainingPermits > skipThreshold) 956ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return Math.max(grabbing - (remainingPermits - skipThreshold), 0); 957ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else 958ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return grabbing; 959ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 960ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 961ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin enum PermitStatus { NO_MORE, MAYBE_MORE, UNLIMITED } 962ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 963ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** Call to check if permits might be available before acquiring data */ 964ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected final PermitStatus permitStatus() { 965ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (permits.get() > 0) 966ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return PermitStatus.MAYBE_MORE; 967ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else 968ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return unlimited ? PermitStatus.UNLIMITED : PermitStatus.NO_MORE; 969ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 970ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 971ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public final T_SPLITR trySplit() { 972ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Stop splitting when there are no more limit permits 973ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (permits.get() == 0) 974ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return null; 975ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("unchecked") 976ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T_SPLITR split = (T_SPLITR) s.trySplit(); 977ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return split == null ? null : makeSpliterator(split); 978ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 979ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 980ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected abstract T_SPLITR makeSpliterator(T_SPLITR s); 981ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 982ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public final long estimateSize() { 983ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return s.estimateSize(); 984ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 985ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 986ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public final int characteristics() { 987ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return s.characteristics() & 988ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin ~(Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED); 989ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 990ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 991ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfRef<T> extends UnorderedSliceSpliterator<T, Spliterator<T>> 992ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator<T>, Consumer<T> { 993ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T tmpSlot; 994ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 995ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfRef(Spliterator<T> s, long skip, long limit) { 996ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(s, skip, limit); 997ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 998ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 999ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfRef(Spliterator<T> s, OfRef<T> parent) { 1000ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(s, parent); 1001ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1002ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1003ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1004ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public final void accept(T t) { 1005ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin tmpSlot = t; 1006ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1007ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1008ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1009ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public boolean tryAdvance(Consumer<? super T> action) { 1010ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Objects.requireNonNull(action); 1011ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1012ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin while (permitStatus() != PermitStatus.NO_MORE) { 1013ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (!s.tryAdvance(this)) 1014ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return false; 1015ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else if (acquirePermits(1) == 1) { 1016ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin action.accept(tmpSlot); 1017ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin tmpSlot = null; 1018ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return true; 1019ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1020ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1021ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return false; 1022ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1023ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1024ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1025ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEachRemaining(Consumer<? super T> action) { 1026ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Objects.requireNonNull(action); 1027ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1028ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin ArrayBuffer.OfRef<T> sb = null; 1029ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin PermitStatus permitStatus; 1030ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin while ((permitStatus = permitStatus()) != PermitStatus.NO_MORE) { 1031ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (permitStatus == PermitStatus.MAYBE_MORE) { 1032ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Optimistically traverse elements up to a threshold of CHUNK_SIZE 1033ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (sb == null) 1034ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin sb = new ArrayBuffer.OfRef<>(CHUNK_SIZE); 1035ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else 1036ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin sb.reset(); 1037ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long permitsRequested = 0; 1038ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin do { } while (s.tryAdvance(sb) && ++permitsRequested < CHUNK_SIZE); 1039ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (permitsRequested == 0) 1040ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return; 1041ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin sb.forEach(action, acquirePermits(permitsRequested)); 1042ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1043ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else { 1044ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Must be UNLIMITED; let 'er rip 1045ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin s.forEachRemaining(action); 1046ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return; 1047ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1048ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1049ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1050ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1051ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1052ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected Spliterator<T> makeSpliterator(Spliterator<T> s) { 1053ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new UnorderedSliceSpliterator.OfRef<>(s, this); 1054ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1055ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1056ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1057ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 1058ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Concrete sub-types must also be an instance of type {@code T_CONS}. 1059ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 1060ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @paramthe type of the spined buffer. Must also be a type of 1061ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * {@code T_CONS}. 1062ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 1063ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static abstract class OfPrimitive< 1064ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T, 1065ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T_CONS, 1066ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T_BUFF extends ArrayBuffer.OfPrimitive<T_CONS>, 1067ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>> 1068ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends UnorderedSliceSpliterator<T, T_SPLITR> 1069ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator.OfPrimitive<T, T_CONS, T_SPLITR> { 1070ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfPrimitive(T_SPLITR s, long skip, long limit) { 1071ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(s, skip, limit); 1072ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1073ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1074ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfPrimitive(T_SPLITR s, UnorderedSliceSpliterator.OfPrimitive<T, T_CONS, T_BUFF, T_SPLITR> parent) { 1075ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(s, parent); 1076ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1077ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1078ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1079ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public boolean tryAdvance(T_CONS action) { 1080ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Objects.requireNonNull(action); 1081ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("unchecked") 1082ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T_CONS consumer = (T_CONS) this; 1083ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1084ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin while (permitStatus() != PermitStatus.NO_MORE) { 1085ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (!s.tryAdvance(consumer)) 1086ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return false; 1087ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else if (acquirePermits(1) == 1) { 1088ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin acceptConsumed(action); 1089ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return true; 1090ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1091ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1092ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return false; 1093ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1094ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1095ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected abstract void acceptConsumed(T_CONS action); 1096ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1097ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1098ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEachRemaining(T_CONS action) { 1099ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Objects.requireNonNull(action); 1100ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1101ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T_BUFF sb = null; 1102ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin PermitStatus permitStatus; 1103ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin while ((permitStatus = permitStatus()) != PermitStatus.NO_MORE) { 1104ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (permitStatus == PermitStatus.MAYBE_MORE) { 1105ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Optimistically traverse elements up to a threshold of CHUNK_SIZE 1106ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (sb == null) 1107ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin sb = bufferCreate(CHUNK_SIZE); 1108ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else 1109ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin sb.reset(); 1110ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("unchecked") 1111ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T_CONS sbc = (T_CONS) sb; 1112ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long permitsRequested = 0; 1113ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin do { } while (s.tryAdvance(sbc) && ++permitsRequested < CHUNK_SIZE); 1114ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (permitsRequested == 0) 1115ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return; 1116ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin sb.forEach(action, acquirePermits(permitsRequested)); 1117ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1118ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else { 1119ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Must be UNLIMITED; let 'er rip 1120ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin s.forEachRemaining(action); 1121ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return; 1122ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1123ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1124ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1125ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1126ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected abstract T_BUFF bufferCreate(int initialCapacity); 1127ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1128ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1129ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfInt 1130ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends OfPrimitive<Integer, IntConsumer, ArrayBuffer.OfInt, Spliterator.OfInt> 1131ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator.OfInt, IntConsumer { 1132ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1133ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin int tmpValue; 1134ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1135ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfInt(Spliterator.OfInt s, long skip, long limit) { 1136ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(s, skip, limit); 1137ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1138ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1139ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfInt(Spliterator.OfInt s, UnorderedSliceSpliterator.OfInt parent) { 1140ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(s, parent); 1141ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1142ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1143ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1144ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void accept(int value) { 1145ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin tmpValue = value; 1146ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1147ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1148ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1149ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected void acceptConsumed(IntConsumer action) { 1150ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin action.accept(tmpValue); 1151ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1152ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1153ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1154ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected ArrayBuffer.OfInt bufferCreate(int initialCapacity) { 1155ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new ArrayBuffer.OfInt(initialCapacity); 1156ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1157ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1158ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1159ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected Spliterator.OfInt makeSpliterator(Spliterator.OfInt s) { 1160ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new UnorderedSliceSpliterator.OfInt(s, this); 1161ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1162ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1163ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1164ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfLong 1165ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends OfPrimitive<Long, LongConsumer, ArrayBuffer.OfLong, Spliterator.OfLong> 1166ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator.OfLong, LongConsumer { 1167ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1168ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long tmpValue; 1169ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1170ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfLong(Spliterator.OfLong s, long skip, long limit) { 1171ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(s, skip, limit); 1172ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1173ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1174ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfLong(Spliterator.OfLong s, UnorderedSliceSpliterator.OfLong parent) { 1175ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(s, parent); 1176ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1177ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1178ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1179ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void accept(long value) { 1180ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin tmpValue = value; 1181ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1182ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1183ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1184ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected void acceptConsumed(LongConsumer action) { 1185ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin action.accept(tmpValue); 1186ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1187ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1188ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1189ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected ArrayBuffer.OfLong bufferCreate(int initialCapacity) { 1190ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new ArrayBuffer.OfLong(initialCapacity); 1191ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1192ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1193ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1194ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected Spliterator.OfLong makeSpliterator(Spliterator.OfLong s) { 1195ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new UnorderedSliceSpliterator.OfLong(s, this); 1196ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1197ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1198ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1199ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfDouble 1200ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends OfPrimitive<Double, DoubleConsumer, ArrayBuffer.OfDouble, Spliterator.OfDouble> 1201ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator.OfDouble, DoubleConsumer { 1202ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1203ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin double tmpValue; 1204ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1205ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfDouble(Spliterator.OfDouble s, long skip, long limit) { 1206ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(s, skip, limit); 1207ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1208ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1209ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfDouble(Spliterator.OfDouble s, UnorderedSliceSpliterator.OfDouble parent) { 1210ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(s, parent); 1211ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1212ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1213ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1214ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void accept(double value) { 1215ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin tmpValue = value; 1216ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1217ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1218ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1219ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected void acceptConsumed(DoubleConsumer action) { 1220ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin action.accept(tmpValue); 1221ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1222ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1223ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1224ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected ArrayBuffer.OfDouble bufferCreate(int initialCapacity) { 1225ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new ArrayBuffer.OfDouble(initialCapacity); 1226ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1227ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1228ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1229ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected Spliterator.OfDouble makeSpliterator(Spliterator.OfDouble s) { 1230ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new UnorderedSliceSpliterator.OfDouble(s, this); 1231ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1232ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1233ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1234ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1235ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 1236ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * A wrapping spliterator that only reports distinct elements of the 1237ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * underlying spliterator. Does not preserve size and encounter order. 1238ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 1239ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class DistinctSpliterator<T> implements Spliterator<T>, Consumer<T> { 1240ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1241ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // The value to represent null in the ConcurrentHashMap 1242ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final Object NULL_VALUE = new Object(); 1243ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1244ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // The underlying spliterator 1245ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private final Spliterator<T> s; 1246ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1247ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // ConcurrentHashMap holding distinct elements as keys 1248ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private final ConcurrentHashMap<T, Boolean> seen; 1249ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1250ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Temporary element, only used with tryAdvance 1251ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private T tmpSlot; 1252ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1253ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin DistinctSpliterator(Spliterator<T> s) { 1254ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this(s, new ConcurrentHashMap<>()); 1255ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1256ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1257ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private DistinctSpliterator(Spliterator<T> s, ConcurrentHashMap<T, Boolean> seen) { 1258ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.s = s; 1259ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.seen = seen; 1260ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1261ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1262ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1263ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void accept(T t) { 1264ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.tmpSlot = t; 1265ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1266ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1267ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("unchecked") 1268ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private T mapNull(T t) { 1269ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return t != null ? t : (T) NULL_VALUE; 1270ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1271ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1272ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1273ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public boolean tryAdvance(Consumer<? super T> action) { 1274ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin while (s.tryAdvance(this)) { 1275ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (seen.putIfAbsent(mapNull(tmpSlot), Boolean.TRUE) == null) { 1276ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin action.accept(tmpSlot); 1277ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin tmpSlot = null; 1278ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return true; 1279ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1280ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1281ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return false; 1282ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1283ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1284ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1285ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEachRemaining(Consumer<? super T> action) { 1286ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin s.forEachRemaining(t -> { 1287ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (seen.putIfAbsent(mapNull(t), Boolean.TRUE) == null) { 1288ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin action.accept(t); 1289ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1290ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin }); 1291ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1292ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1293ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1294ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator<T> trySplit() { 1295ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Spliterator<T> split = s.trySplit(); 1296ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return (split != null) ? new DistinctSpliterator<>(split, seen) : null; 1297ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1298ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1299ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1300ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public long estimateSize() { 1301ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return s.estimateSize(); 1302ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1303ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1304ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1305ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public int characteristics() { 1306ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return (s.characteristics() & ~(Spliterator.SIZED | Spliterator.SUBSIZED | 1307ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Spliterator.SORTED | Spliterator.ORDERED)) 1308ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin | Spliterator.DISTINCT; 1309ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1310ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1311ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1312ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Comparator<? super T> getComparator() { 1313ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return s.getComparator(); 1314ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1315ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1316ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1317ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 1318ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * A Spliterator that infinitely supplies elements in no particular order. 1319ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 1320ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * <p>Splitting divides the estimated size in two and stops when the 1321ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * estimate size is 0. 1322ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 1323ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * <p>The {@code forEachRemaining} method if invoked will never terminate. 1324ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * The {@code tryAdvance} method always returns true. 1325ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 1326ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 1327ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static abstract class InfiniteSupplyingSpliterator<T> implements Spliterator<T> { 1328ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long estimate; 1329ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1330ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected InfiniteSupplyingSpliterator(long estimate) { 1331ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.estimate = estimate; 1332ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1333ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1334ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1335ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public long estimateSize() { 1336ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return estimate; 1337ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1338ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1339ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1340ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public int characteristics() { 1341ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return IMMUTABLE; 1342ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1343ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1344ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfRef<T> extends InfiniteSupplyingSpliterator<T> { 1345ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin final Supplier<T> s; 1346ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1347ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfRef(long size, Supplier<T> s) { 1348ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(size); 1349ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.s = s; 1350ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1351ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1352ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1353ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public boolean tryAdvance(Consumer<? super T> action) { 1354ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Objects.requireNonNull(action); 1355ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1356ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin action.accept(s.get()); 1357ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return true; 1358ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1359ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1360ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1361ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator<T> trySplit() { 1362ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (estimate == 0) 1363ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return null; 1364ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new InfiniteSupplyingSpliterator.OfRef<>(estimate >>>= 1, s); 1365ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1366ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1367ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1368ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfInt extends InfiniteSupplyingSpliterator<Integer> 1369ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator.OfInt { 1370ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin final IntSupplier s; 1371ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1372ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfInt(long size, IntSupplier s) { 1373ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(size); 1374ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.s = s; 1375ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1376ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1377ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1378ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public boolean tryAdvance(IntConsumer action) { 1379ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Objects.requireNonNull(action); 1380ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1381ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin action.accept(s.getAsInt()); 1382ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return true; 1383ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1384ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1385ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1386ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator.OfInt trySplit() { 1387ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (estimate == 0) 1388ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return null; 1389ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new InfiniteSupplyingSpliterator.OfInt(estimate = estimate >>> 1, s); 1390ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1391ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1392ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1393ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfLong extends InfiniteSupplyingSpliterator<Long> 1394ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator.OfLong { 1395ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin final LongSupplier s; 1396ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1397ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfLong(long size, LongSupplier s) { 1398ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(size); 1399ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.s = s; 1400ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1401ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1402ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1403ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public boolean tryAdvance(LongConsumer action) { 1404ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Objects.requireNonNull(action); 1405ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1406ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin action.accept(s.getAsLong()); 1407ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return true; 1408ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1409ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1410ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1411ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator.OfLong trySplit() { 1412ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (estimate == 0) 1413ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return null; 1414ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new InfiniteSupplyingSpliterator.OfLong(estimate = estimate >>> 1, s); 1415ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1416ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1417ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1418ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfDouble extends InfiniteSupplyingSpliterator<Double> 1419ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator.OfDouble { 1420ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin final DoubleSupplier s; 1421ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1422ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfDouble(long size, DoubleSupplier s) { 1423ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(size); 1424ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.s = s; 1425ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1426ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1427ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1428ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public boolean tryAdvance(DoubleConsumer action) { 1429ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Objects.requireNonNull(action); 1430ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1431ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin action.accept(s.getAsDouble()); 1432ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return true; 1433ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1434ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1435ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1436ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator.OfDouble trySplit() { 1437ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (estimate == 0) 1438ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return null; 1439ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new InfiniteSupplyingSpliterator.OfDouble(estimate = estimate >>> 1, s); 1440ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1441ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1442ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1443ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1444ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // @@@ Consolidate with Node.Builder 1445ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static abstract class ArrayBuffer { 1446ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin int index; 1447ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1448ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin void reset() { 1449ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin index = 0; 1450ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1451ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1452ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfRef<T> extends ArrayBuffer implements Consumer<T> { 1453ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin final Object[] array; 1454ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1455ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfRef(int size) { 1456ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.array = new Object[size]; 1457ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1458ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1459ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1460ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void accept(T t) { 1461ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array[index++] = t; 1462ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1463ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1464ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEach(Consumer<? super T> action, long fence) { 1465ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin for (int i = 0; i < fence; i++) { 1466ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("unchecked") 1467ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T t = (T) array[i]; 1468ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin action.accept(t); 1469ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1470ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1471ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1472ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1473ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static abstract class OfPrimitive<T_CONS> extends ArrayBuffer { 1474ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin int index; 1475ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1476ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1477ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin void reset() { 1478ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin index = 0; 1479ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1480ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1481ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin abstract void forEach(T_CONS action, long fence); 1482ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1483ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1484ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfInt extends OfPrimitive<IntConsumer> 1485ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements IntConsumer { 1486ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin final int[] array; 1487ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1488ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfInt(int size) { 1489ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.array = new int[size]; 1490ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1491ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1492ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1493ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void accept(int t) { 1494ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array[index++] = t; 1495ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1496ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1497ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1498ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEach(IntConsumer action, long fence) { 1499ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin for (int i = 0; i < fence; i++) { 1500ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin action.accept(array[i]); 1501ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1502ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1503ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1504ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1505ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfLong extends OfPrimitive<LongConsumer> 1506ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements LongConsumer { 1507ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin final long[] array; 1508ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1509ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfLong(int size) { 1510ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.array = new long[size]; 1511ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1512ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1513ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1514ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void accept(long t) { 1515ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array[index++] = t; 1516ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1517ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1518ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1519ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEach(LongConsumer action, long fence) { 1520ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin for (int i = 0; i < fence; i++) { 1521ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin action.accept(array[i]); 1522ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1523ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1524ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1525ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1526ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfDouble extends OfPrimitive<DoubleConsumer> 1527ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements DoubleConsumer { 1528ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin final double[] array; 1529ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1530ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfDouble(int size) { 1531ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.array = new double[size]; 1532ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1533ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1534ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1535ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void accept(double t) { 1536ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array[index++] = t; 1537ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1538ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1539ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1540ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin void forEach(DoubleConsumer action, long fence) { 1541ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin for (int i = 0; i < fence; i++) { 1542ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin action.accept(array[i]); 1543ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1544ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1545ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1546ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1547ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin} 1548ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1549