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.ArrayDeque; 28ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.Arrays; 29ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.Collection; 30ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.Deque; 31ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.List; 32ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.Objects; 33ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.Spliterator; 34ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.Spliterators; 35ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.concurrent.CountedCompleter; 36ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.function.BinaryOperator; 37ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.function.Consumer; 38ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.function.DoubleConsumer; 39ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.function.IntConsumer; 40ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.function.IntFunction; 41ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.function.LongConsumer; 42ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.function.LongFunction; 43ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 44ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin/** 45ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Factory methods for constructing implementations of {@link Node} and 46ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * {@link Node.Builder} and their primitive specializations. Fork/Join tasks 47ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * for collecting output from a {@link PipelineHelper} to a {@link Node} and 48ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * flattening {@link Node}s. 49ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 50ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @since 1.8 51ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 52ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinfinal class Nodes { 53ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 54ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private Nodes() { 55ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new Error("no instances"); 56ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 57ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 58ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 59ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * The maximum size of an array that can be allocated. 60ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 61ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final long MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; 62ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 63ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // IllegalArgumentException messages 64ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final String BAD_SIZE = "Stream size exceeds max array size"; 65ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 66ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("rawtypes") 67ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final Node EMPTY_NODE = new EmptyNode.OfRef(); 68ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final Node.OfInt EMPTY_INT_NODE = new EmptyNode.OfInt(); 69ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final Node.OfLong EMPTY_LONG_NODE = new EmptyNode.OfLong(); 70ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final Node.OfDouble EMPTY_DOUBLE_NODE = new EmptyNode.OfDouble(); 71ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 72ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // General shape-based node creation methods 73ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 74ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 75ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Produces an empty node whose count is zero, has no children and no content. 76ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 77ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param <T> the type of elements of the created node 78ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param shape the shape of the node to be created 79ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return an empty node. 80ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 81ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("unchecked") 82ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static <T> Node<T> emptyNode(StreamShape shape) { 83ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin switch (shape) { 84ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin case REFERENCE: return (Node<T>) EMPTY_NODE; 85ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin case INT_VALUE: return (Node<T>) EMPTY_INT_NODE; 86ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin case LONG_VALUE: return (Node<T>) EMPTY_LONG_NODE; 87ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin case DOUBLE_VALUE: return (Node<T>) EMPTY_DOUBLE_NODE; 88ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin default: 89ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalStateException("Unknown shape " + shape); 90ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 91ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 92ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 93ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 94ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Produces a concatenated {@link Node} that has two or more children. 95ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * <p>The count of the concatenated node is equal to the sum of the count 96ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * of each child. Traversal of the concatenated node traverses the content 97ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * of each child in encounter order of the list of children. Splitting a 98ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * spliterator obtained from the concatenated node preserves the encounter 99ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * order of the list of children. 100ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 101ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * <p>The result may be a concatenated node, the input sole node if the size 102ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * of the list is 1, or an empty node. 103ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 104ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param <T> the type of elements of the concatenated node 105ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param shape the shape of the concatenated node to be created 106ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param left the left input node 107ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param right the right input node 108ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return a {@code Node} covering the elements of the input nodes 109ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @throws IllegalStateException if all {@link Node} elements of the list 110ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * are an not instance of type supported by this factory. 111ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 112ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("unchecked") 113ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static <T> Node<T> conc(StreamShape shape, Node<T> left, Node<T> right) { 114ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin switch (shape) { 115ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin case REFERENCE: 116ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new ConcNode<>(left, right); 117ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin case INT_VALUE: 118ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return (Node<T>) new ConcNode.OfInt((Node.OfInt) left, (Node.OfInt) right); 119ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin case LONG_VALUE: 120ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return (Node<T>) new ConcNode.OfLong((Node.OfLong) left, (Node.OfLong) right); 121ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin case DOUBLE_VALUE: 122ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return (Node<T>) new ConcNode.OfDouble((Node.OfDouble) left, (Node.OfDouble) right); 123ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin default: 124ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalStateException("Unknown shape " + shape); 125ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 126ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 127ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 128ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Reference-based node methods 129ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 130ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 131ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Produces a {@link Node} describing an array. 132ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 133ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * <p>The node will hold a reference to the array and will not make a copy. 134ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 135ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param <T> the type of elements held by the node 136ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param array the array 137ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return a node holding an array 138ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 139ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static <T> Node<T> node(T[] array) { 140ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new ArrayNode<>(array); 141ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 142ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 143ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 144ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Produces a {@link Node} describing a {@link Collection}. 145ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * <p> 146ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * The node will hold a reference to the collection and will not make a copy. 147ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 148ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param <T> the type of elements held by the node 149ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param c the collection 150ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return a node holding a collection 151ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 152ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static <T> Node<T> node(Collection<T> c) { 153ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new CollectionNode<>(c); 154ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 155ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 156ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 157ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Produces a {@link Node.Builder}. 158ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 159ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param exactSizeIfKnown -1 if a variable size builder is requested, 160ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * otherwise the exact capacity desired. A fixed capacity builder will 161ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * fail if the wrong number of elements are added to the builder. 162ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param generator the array factory 163ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param <T> the type of elements of the node builder 164ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return a {@code Node.Builder} 165ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 166ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static <T> Node.Builder<T> builder(long exactSizeIfKnown, IntFunction<T[]> generator) { 167ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return (exactSizeIfKnown >= 0 && exactSizeIfKnown < MAX_ARRAY_SIZE) 168ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin ? new FixedNodeBuilder<>(exactSizeIfKnown, generator) 169ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin : builder(); 170ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 171ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 172ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 173ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Produces a variable size @{link Node.Builder}. 174ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 175ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param <T> the type of elements of the node builder 176ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return a {@code Node.Builder} 177ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 178ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static <T> Node.Builder<T> builder() { 179ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new SpinedNodeBuilder<>(); 180ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 181ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 182ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Int nodes 183ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 184ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 185ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Produces a {@link Node.OfInt} describing an int[] array. 186ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 187ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * <p>The node will hold a reference to the array and will not make a copy. 188ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 189ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param array the array 190ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return a node holding an array 191ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 192ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static Node.OfInt node(int[] array) { 193ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new IntArrayNode(array); 194ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 195ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 196ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 197ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Produces a {@link Node.Builder.OfInt}. 198ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 199ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param exactSizeIfKnown -1 if a variable size builder is requested, 200ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * otherwise the exact capacity desired. A fixed capacity builder will 201ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * fail if the wrong number of elements are added to the builder. 202ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return a {@code Node.Builder.OfInt} 203ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 204ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static Node.Builder.OfInt intBuilder(long exactSizeIfKnown) { 205ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return (exactSizeIfKnown >= 0 && exactSizeIfKnown < MAX_ARRAY_SIZE) 206ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin ? new IntFixedNodeBuilder(exactSizeIfKnown) 207ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin : intBuilder(); 208ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 209ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 210ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 211ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Produces a variable size @{link Node.Builder.OfInt}. 212ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 213ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return a {@code Node.Builder.OfInt} 214ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 215ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static Node.Builder.OfInt intBuilder() { 216ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new IntSpinedNodeBuilder(); 217ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 218ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 219ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Long nodes 220ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 221ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 222ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Produces a {@link Node.OfLong} describing a long[] array. 223ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * <p> 224ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * The node will hold a reference to the array and will not make a copy. 225ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 226ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param array the array 227ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return a node holding an array 228ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 229ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static Node.OfLong node(final long[] array) { 230ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new LongArrayNode(array); 231ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 232ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 233ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 234ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Produces a {@link Node.Builder.OfLong}. 235ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 236ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param exactSizeIfKnown -1 if a variable size builder is requested, 237ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * otherwise the exact capacity desired. A fixed capacity builder will 238ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * fail if the wrong number of elements are added to the builder. 239ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return a {@code Node.Builder.OfLong} 240ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 241ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static Node.Builder.OfLong longBuilder(long exactSizeIfKnown) { 242ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return (exactSizeIfKnown >= 0 && exactSizeIfKnown < MAX_ARRAY_SIZE) 243ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin ? new LongFixedNodeBuilder(exactSizeIfKnown) 244ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin : longBuilder(); 245ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 246ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 247ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 248ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Produces a variable size @{link Node.Builder.OfLong}. 249ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 250ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return a {@code Node.Builder.OfLong} 251ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 252ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static Node.Builder.OfLong longBuilder() { 253ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new LongSpinedNodeBuilder(); 254ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 255ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 256ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Double nodes 257ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 258ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 259ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Produces a {@link Node.OfDouble} describing a double[] array. 260ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 261ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * <p>The node will hold a reference to the array and will not make a copy. 262ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 263ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param array the array 264ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return a node holding an array 265ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 266ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static Node.OfDouble node(final double[] array) { 267ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new DoubleArrayNode(array); 268ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 269ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 270ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 271ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Produces a {@link Node.Builder.OfDouble}. 272ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 273ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param exactSizeIfKnown -1 if a variable size builder is requested, 274ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * otherwise the exact capacity desired. A fixed capacity builder will 275ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * fail if the wrong number of elements are added to the builder. 276ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return a {@code Node.Builder.OfDouble} 277ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 278ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static Node.Builder.OfDouble doubleBuilder(long exactSizeIfKnown) { 279ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return (exactSizeIfKnown >= 0 && exactSizeIfKnown < MAX_ARRAY_SIZE) 280ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin ? new DoubleFixedNodeBuilder(exactSizeIfKnown) 281ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin : doubleBuilder(); 282ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 283ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 284ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 285ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Produces a variable size @{link Node.Builder.OfDouble}. 286ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 287ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return a {@code Node.Builder.OfDouble} 288ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 289ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static Node.Builder.OfDouble doubleBuilder() { 290ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new DoubleSpinedNodeBuilder(); 291ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 292ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 293ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Parallel evaluation of pipelines to nodes 294ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 295ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 296ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Collect, in parallel, elements output from a pipeline and describe those 297ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * elements with a {@link Node}. 298ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 299ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @implSpec 300ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * If the exact size of the output from the pipeline is known and the source 301ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * {@link Spliterator} has the {@link Spliterator#SUBSIZED} characteristic, 302ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * then a flat {@link Node} will be returned whose content is an array, 303ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * since the size is known the array can be constructed in advance and 304ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * output elements can be placed into the array concurrently by leaf 305ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * tasks at the correct offsets. If the exact size is not known, output 306ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * elements are collected into a conc-node whose shape mirrors that 307ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * of the computation. This conc-node can then be flattened in 308ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * parallel to produce a flat {@code Node} if desired. 309ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 310ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param helper the pipeline helper describing the pipeline 311ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param flattenTree whether a conc node should be flattened into a node 312ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * describing an array before returning 313ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param generator the array generator 314ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return a {@link Node} describing the output elements 315ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 316ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public static <P_IN, P_OUT> Node<P_OUT> collect(PipelineHelper<P_OUT> helper, 317ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Spliterator<P_IN> spliterator, 318ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin boolean flattenTree, 319ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin IntFunction<P_OUT[]> generator) { 320ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long size = helper.exactOutputSizeIfKnown(spliterator); 321ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (size >= 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) { 322ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (size >= MAX_ARRAY_SIZE) 323ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalArgumentException(BAD_SIZE); 324ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin P_OUT[] array = generator.apply((int) size); 325ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin new SizedCollectorTask.OfRef<>(spliterator, helper, array).invoke(); 326ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return node(array); 327ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } else { 328ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Node<P_OUT> node = new CollectorTask.OfRef<>(helper, generator, spliterator).invoke(); 329ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return flattenTree ? flatten(node, generator) : node; 330ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 331ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 332ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 333ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 334ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Collect, in parallel, elements output from an int-valued pipeline and 335ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * describe those elements with a {@link Node.OfInt}. 336ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 337ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @implSpec 338ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * If the exact size of the output from the pipeline is known and the source 339ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * {@link Spliterator} has the {@link Spliterator#SUBSIZED} characteristic, 340ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * then a flat {@link Node} will be returned whose content is an array, 341ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * since the size is known the array can be constructed in advance and 342ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * output elements can be placed into the array concurrently by leaf 343ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * tasks at the correct offsets. If the exact size is not known, output 344ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * elements are collected into a conc-node whose shape mirrors that 345ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * of the computation. This conc-node can then be flattened in 346ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * parallel to produce a flat {@code Node.OfInt} if desired. 347ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 348ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @paramthe type of elements from the source Spliterator 349ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param helper the pipeline helper describing the pipeline 350ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param flattenTree whether a conc node should be flattened into a node 351ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * describing an array before returning 352ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return a {@link Node.OfInt} describing the output elements 353ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 354ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public static <P_IN> Node.OfInt collectInt(PipelineHelper<Integer> helper, 355ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Spliterator<P_IN> spliterator, 356ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin boolean flattenTree) { 357ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long size = helper.exactOutputSizeIfKnown(spliterator); 358ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (size >= 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) { 359ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (size >= MAX_ARRAY_SIZE) 360ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalArgumentException(BAD_SIZE); 361ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin int[] array = new int[(int) size]; 362ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin new SizedCollectorTask.OfInt<>(spliterator, helper, array).invoke(); 363ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return node(array); 364ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 365ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else { 366ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Node.OfInt node = new CollectorTask.OfInt<>(helper, spliterator).invoke(); 367ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return flattenTree ? flattenInt(node) : node; 368ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 369ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 370ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 371ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 372ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Collect, in parallel, elements output from a long-valued pipeline and 373ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * describe those elements with a {@link Node.OfLong}. 374ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 375ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @implSpec 376ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * If the exact size of the output from the pipeline is known and the source 377ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * {@link Spliterator} has the {@link Spliterator#SUBSIZED} characteristic, 378ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * then a flat {@link Node} will be returned whose content is an array, 379ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * since the size is known the array can be constructed in advance and 380ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * output elements can be placed into the array concurrently by leaf 381ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * tasks at the correct offsets. If the exact size is not known, output 382ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * elements are collected into a conc-node whose shape mirrors that 383ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * of the computation. This conc-node can then be flattened in 384ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * parallel to produce a flat {@code Node.OfLong} if desired. 385ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 386ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param the type of elements from the source Spliterator 387ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param helper the pipeline helper describing the pipeline 388ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param flattenTree whether a conc node should be flattened into a node 389ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * describing an array before returning 390ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return a {@link Node.OfLong} describing the output elements 391ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 392ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public static <P_IN> Node.OfLong collectLong(PipelineHelper<Long> helper, 393ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Spliterator<P_IN> spliterator, 394ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin boolean flattenTree) { 395ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long size = helper.exactOutputSizeIfKnown(spliterator); 396ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (size >= 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) { 397ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (size >= MAX_ARRAY_SIZE) 398ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalArgumentException(BAD_SIZE); 399ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long[] array = new long[(int) size]; 400ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin new SizedCollectorTask.OfLong<>(spliterator, helper, array).invoke(); 401ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return node(array); 402ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 403ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else { 404ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Node.OfLong node = new CollectorTask.OfLong<>(helper, spliterator).invoke(); 405ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return flattenTree ? flattenLong(node) : node; 406ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 407ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 408ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 409ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 410ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Collect, in parallel, elements output from n double-valued pipeline and 411ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * describe those elements with a {@link Node.OfDouble}. 412ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 413ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @implSpec 414ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * If the exact size of the output from the pipeline is known and the source 415ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * {@link Spliterator} has the {@link Spliterator#SUBSIZED} characteristic, 416ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * then a flat {@link Node} will be returned whose content is an array, 417ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * since the size is known the array can be constructed in advance and 418ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * output elements can be placed into the array concurrently by leaf 419ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * tasks at the correct offsets. If the exact size is not known, output 420ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * elements are collected into a conc-node whose shape mirrors that 421ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * of the computation. This conc-node can then be flattened in 422ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * parallel to produce a flat {@code Node.OfDouble} if desired. 423ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 424ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param the type of elements from the source Spliterator 425ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param helper the pipeline helper describing the pipeline 426ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param flattenTree whether a conc node should be flattened into a node 427ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * describing an array before returning 428ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return a {@link Node.OfDouble} describing the output elements 429ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 430ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public static <P_IN> Node.OfDouble collectDouble(PipelineHelper<Double> helper, 431ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Spliterator<P_IN> spliterator, 432ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin boolean flattenTree) { 433ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long size = helper.exactOutputSizeIfKnown(spliterator); 434ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (size >= 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) { 435ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (size >= MAX_ARRAY_SIZE) 436ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalArgumentException(BAD_SIZE); 437ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin double[] array = new double[(int) size]; 438ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin new SizedCollectorTask.OfDouble<>(spliterator, helper, array).invoke(); 439ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return node(array); 440ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 441ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else { 442ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Node.OfDouble node = new CollectorTask.OfDouble<>(helper, spliterator).invoke(); 443ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return flattenTree ? flattenDouble(node) : node; 444ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 445ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 446ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 447ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Parallel flattening of nodes 448ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 449ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 450ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Flatten, in parallel, a {@link Node}. A flattened node is one that has 451ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * no children. If the node is already flat, it is simply returned. 452ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 453ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @implSpec 454ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * If a new node is to be created, the generator is used to create an array 455ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * whose length is {@link Node#count()}. Then the node tree is traversed 456ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * and leaf node elements are placed in the array concurrently by leaf tasks 457ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * at the correct offsets. 458ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 459ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param <T> type of elements contained by the node 460ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param node the node to flatten 461ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param generator the array factory used to create array instances 462ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return a flat {@code Node} 463ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 464ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public static <T> Node<T> flatten(Node<T> node, IntFunction<T[]> generator) { 465ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (node.getChildCount() > 0) { 466ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long size = node.count(); 467ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (size >= MAX_ARRAY_SIZE) 468ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalArgumentException(BAD_SIZE); 469ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T[] array = generator.apply((int) size); 470ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin new ToArrayTask.OfRef<>(node, array, 0).invoke(); 471ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return node(array); 472ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } else { 473ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return node; 474ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 475ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 476ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 477ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 478ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Flatten, in parallel, a {@link Node.OfInt}. A flattened node is one that 479ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * has no children. If the node is already flat, it is simply returned. 480ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 481ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @implSpec 482ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * If a new node is to be created, a new int[] array is created whose length 483ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * is {@link Node#count()}. Then the node tree is traversed and leaf node 484ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * elements are placed in the array concurrently by leaf tasks at the 485ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * correct offsets. 486ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 487ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param node the node to flatten 488ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return a flat {@code Node.OfInt} 489ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 490ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public static Node.OfInt flattenInt(Node.OfInt node) { 491ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (node.getChildCount() > 0) { 492ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long size = node.count(); 493ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (size >= MAX_ARRAY_SIZE) 494ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalArgumentException(BAD_SIZE); 495ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin int[] array = new int[(int) size]; 496ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin new ToArrayTask.OfInt(node, array, 0).invoke(); 497ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return node(array); 498ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } else { 499ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return node; 500ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 501ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 502ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 503ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 504ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Flatten, in parallel, a {@link Node.OfLong}. A flattened node is one that 505ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * has no children. If the node is already flat, it is simply returned. 506ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 507ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @implSpec 508ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * If a new node is to be created, a new long[] array is created whose length 509ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * is {@link Node#count()}. Then the node tree is traversed and leaf node 510ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * elements are placed in the array concurrently by leaf tasks at the 511ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * correct offsets. 512ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 513ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param node the node to flatten 514ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return a flat {@code Node.OfLong} 515ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 516ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public static Node.OfLong flattenLong(Node.OfLong node) { 517ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (node.getChildCount() > 0) { 518ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long size = node.count(); 519ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (size >= MAX_ARRAY_SIZE) 520ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalArgumentException(BAD_SIZE); 521ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long[] array = new long[(int) size]; 522ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin new ToArrayTask.OfLong(node, array, 0).invoke(); 523ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return node(array); 524ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } else { 525ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return node; 526ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 527ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 528ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 529ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 530ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Flatten, in parallel, a {@link Node.OfDouble}. A flattened node is one that 531ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * has no children. If the node is already flat, it is simply returned. 532ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 533ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @implSpec 534ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * If a new node is to be created, a new double[] array is created whose length 535ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * is {@link Node#count()}. Then the node tree is traversed and leaf node 536ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * elements are placed in the array concurrently by leaf tasks at the 537ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * correct offsets. 538ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 539ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param node the node to flatten 540ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @return a flat {@code Node.OfDouble} 541ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 542ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public static Node.OfDouble flattenDouble(Node.OfDouble node) { 543ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (node.getChildCount() > 0) { 544ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long size = node.count(); 545ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (size >= MAX_ARRAY_SIZE) 546ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalArgumentException(BAD_SIZE); 547ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin double[] array = new double[(int) size]; 548ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin new ToArrayTask.OfDouble(node, array, 0).invoke(); 549ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return node(array); 550ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } else { 551ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return node; 552ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 553ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 554ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 555ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Implementations 556ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 557ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static abstract class EmptyNode<T, T_ARR, T_CONS> implements Node<T> { 558ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin EmptyNode() { } 559ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 560ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 561ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public T[] asArray(IntFunction<T[]> generator) { 562ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return generator.apply(0); 563ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 564ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 565ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void copyInto(T_ARR array, int offset) { } 566ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 567ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 568ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public long count() { 569ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return 0; 570ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 571ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 572ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEach(T_CONS consumer) { } 573ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 574ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static class OfRef<T> extends EmptyNode<T, T[], Consumer<? super T>> { 575ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private OfRef() { 576ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(); 577ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 578ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 579ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 580ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator<T> spliterator() { 581ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return Spliterators.emptySpliterator(); 582ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 583ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 584ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 585ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final class OfInt 586ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends EmptyNode<Integer, int[], IntConsumer> 587ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Node.OfInt { 588ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 589ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfInt() { } // Avoid creation of special accessor 590ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 591ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 592ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator.OfInt spliterator() { 593ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return Spliterators.emptyIntSpliterator(); 594ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 595ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 596ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 597ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public int[] asPrimitiveArray() { 598ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return EMPTY_INT_ARRAY; 599ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 600ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 601ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 602ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final class OfLong 603ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends EmptyNode<Long, long[], LongConsumer> 604ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Node.OfLong { 605ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 606ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfLong() { } // Avoid creation of special accessor 607ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 608ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 609ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator.OfLong spliterator() { 610ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return Spliterators.emptyLongSpliterator(); 611ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 612ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 613ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 614ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public long[] asPrimitiveArray() { 615ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return EMPTY_LONG_ARRAY; 616ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 617ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 618ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 619ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final class OfDouble 620ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends EmptyNode<Double, double[], DoubleConsumer> 621ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Node.OfDouble { 622ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 623ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfDouble() { } // Avoid creation of special accessor 624ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 625ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 626ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator.OfDouble spliterator() { 627ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return Spliterators.emptyDoubleSpliterator(); 628ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 629ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 630ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 631ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public double[] asPrimitiveArray() { 632ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return EMPTY_DOUBLE_ARRAY; 633ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 634ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 635ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 636ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 637ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** Node class for a reference array */ 638ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static class ArrayNode<T> implements Node<T> { 639ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin final T[] array; 640ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin int curSize; 641ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 642ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("unchecked") 643ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin ArrayNode(long size, IntFunction<T[]> generator) { 644ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (size >= MAX_ARRAY_SIZE) 645ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalArgumentException(BAD_SIZE); 646ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.array = generator.apply((int) size); 647ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.curSize = 0; 648ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 649ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 650ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin ArrayNode(T[] array) { 651ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.array = array; 652ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.curSize = array.length; 653ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 654ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 655ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Node 656ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 657ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 658ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator<T> spliterator() { 659ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return Arrays.spliterator(array, 0, curSize); 660ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 661ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 662ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 663ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void copyInto(T[] dest, int destOffset) { 664ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin System.arraycopy(array, 0, dest, destOffset, curSize); 665ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 666ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 667ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 668ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public T[] asArray(IntFunction<T[]> generator) { 669ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (array.length == curSize) { 670ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return array; 671ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } else { 672ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalStateException(); 673ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 674ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 675ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 676ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 677ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public long count() { 678ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return curSize; 679ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 680ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 681ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 682ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEach(Consumer<? super T> consumer) { 683ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin for (int i = 0; i < curSize; i++) { 684ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin consumer.accept(array[i]); 685ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 686ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 687ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 688ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // 689ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 690ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 691ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public String toString() { 692ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return String.format("ArrayNode[%d][%s]", 693ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array.length - curSize, Arrays.toString(array)); 694ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 695ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 696ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 697ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** Node class for a Collection */ 698ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final class CollectionNode<T> implements Node<T> { 699ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private final Collection<T> c; 700ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 701ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin CollectionNode(Collection<T> c) { 702ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.c = c; 703ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 704ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 705ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Node 706ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 707ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 708ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator<T> spliterator() { 709ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return c.stream().spliterator(); 710ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 711ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 712ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 713ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void copyInto(T[] array, int offset) { 714ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin for (T t : c) 715ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array[offset++] = t; 716ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 717ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 718ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 719ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("unchecked") 720ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public T[] asArray(IntFunction<T[]> generator) { 721ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return c.toArray(generator.apply(c.size())); 722ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 723ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 724ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 725ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public long count() { 726ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return c.size(); 727ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 728ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 729ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 730ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEach(Consumer<? super T> consumer) { 731ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin c.forEach(consumer); 732ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 733ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 734ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // 735ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 736ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 737ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public String toString() { 738ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return String.format("CollectionNode[%d][%s]", c.size(), c); 739ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 740ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 741ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 742ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 743ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Node class for an internal node with two or more children 744ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 745ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static abstract class AbstractConcNode<T, T_NODE extends Node<T>> implements Node<T> { 746ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected final T_NODE left; 747ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected final T_NODE right; 748ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private final long size; 749ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 750ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin AbstractConcNode(T_NODE left, T_NODE right) { 751ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.left = left; 752ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.right = right; 753ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // The Node count will be required when the Node spliterator is 754ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // obtained and it is cheaper to aggressively calculate bottom up 755ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // as the tree is built rather than later on from the top down 756ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // traversing the tree 757ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.size = left.count() + right.count(); 758ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 759ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 760ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 761ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public int getChildCount() { 762ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return 2; 763ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 764ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 765ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 766ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public T_NODE getChild(int i) { 767ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (i == 0) return left; 768ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (i == 1) return right; 769ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IndexOutOfBoundsException(); 770ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 771ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 772ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 773ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public long count() { 774ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return size; 775ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 776ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 777ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 778ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class ConcNode<T> 779ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends AbstractConcNode<T, Node<T>> 780ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Node<T> { 781ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 782ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin ConcNode(Node<T> left, Node<T> right) { 783ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(left, right); 784ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 785ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 786ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 787ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator<T> spliterator() { 788ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new Nodes.InternalNodeSpliterator.OfRef<>(this); 789ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 790ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 791ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 792ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void copyInto(T[] array, int offset) { 793ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Objects.requireNonNull(array); 794ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin left.copyInto(array, offset); 795ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Cast to int is safe since it is the callers responsibility to 796ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // ensure that there is sufficient room in the array 797ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin right.copyInto(array, offset + (int) left.count()); 798ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 799ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 800ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 801ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public T[] asArray(IntFunction<T[]> generator) { 802ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long size = count(); 803ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (size >= MAX_ARRAY_SIZE) 804ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalArgumentException(BAD_SIZE); 805ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T[] array = generator.apply((int) size); 806ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin copyInto(array, 0); 807ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return array; 808ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 809ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 810ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 811ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEach(Consumer<? super T> consumer) { 812ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin left.forEach(consumer); 813ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin right.forEach(consumer); 814ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 815ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 816ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 817ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Node<T> truncate(long from, long to, IntFunction<T[]> generator) { 818ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (from == 0 && to == count()) 819ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return this; 820ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long leftCount = left.count(); 821ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (from >= leftCount) 822ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return right.truncate(from - leftCount, to - leftCount, generator); 823ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else if (to <= leftCount) 824ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return left.truncate(from, to, generator); 825ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else { 826ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return Nodes.conc(getShape(), left.truncate(from, leftCount, generator), 827ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin right.truncate(0, to - leftCount, generator)); 828ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 829ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 830ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 831ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 832ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public String toString() { 833ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (count() < 32) { 834ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return String.format("ConcNode[%s.%s]", left, right); 835ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } else { 836ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return String.format("ConcNode[size=%d]", count()); 837ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 838ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 839ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 840ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private abstract static class OfPrimitive<E, T_CONS, T_ARR, 841ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T_SPLITR extends Spliterator.OfPrimitive<E, T_CONS, T_SPLITR>, 842ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T_NODE extends Node.OfPrimitive<E, T_CONS, T_ARR, T_SPLITR, T_NODE>> 843ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends AbstractConcNode<E, T_NODE> 844ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Node.OfPrimitive<E, T_CONS, T_ARR, T_SPLITR, T_NODE> { 845ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 846ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfPrimitive(T_NODE left, T_NODE right) { 847ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(left, right); 848ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 849ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 850ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 851ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEach(T_CONS consumer) { 852ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin left.forEach(consumer); 853ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin right.forEach(consumer); 854ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 855ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 856ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 857ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void copyInto(T_ARR array, int offset) { 858ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin left.copyInto(array, offset); 859ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Cast to int is safe since it is the callers responsibility to 860ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // ensure that there is sufficient room in the array 861ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin right.copyInto(array, offset + (int) left.count()); 862ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 863ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 864ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 865ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public T_ARR asPrimitiveArray() { 866ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long size = count(); 867ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (size >= MAX_ARRAY_SIZE) 868ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalArgumentException(BAD_SIZE); 869ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T_ARR array = newArray((int) size); 870ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin copyInto(array, 0); 871ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return array; 872ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 873ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 874ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 875ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public String toString() { 876ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (count() < 32) 877ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return String.format("%s[%s.%s]", this.getClass().getName(), left, right); 878ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else 879ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return String.format("%s[size=%d]", this.getClass().getName(), count()); 880ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 881ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 882ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 883ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfInt 884ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends ConcNode.OfPrimitive<Integer, IntConsumer, int[], Spliterator.OfInt, Node.OfInt> 885ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Node.OfInt { 886ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 887ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfInt(Node.OfInt left, Node.OfInt right) { 888ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(left, right); 889ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 890ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 891ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 892ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator.OfInt spliterator() { 893ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new InternalNodeSpliterator.OfInt(this); 894ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 895ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 896ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 897ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfLong 898ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends ConcNode.OfPrimitive<Long, LongConsumer, long[], Spliterator.OfLong, Node.OfLong> 899ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Node.OfLong { 900ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 901ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfLong(Node.OfLong left, Node.OfLong right) { 902ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(left, right); 903ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 904ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 905ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 906ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator.OfLong spliterator() { 907ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new InternalNodeSpliterator.OfLong(this); 908ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 909ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 910ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 911ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfDouble 912ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends ConcNode.OfPrimitive<Double, DoubleConsumer, double[], Spliterator.OfDouble, Node.OfDouble> 913ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Node.OfDouble { 914ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 915ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfDouble(Node.OfDouble left, Node.OfDouble right) { 916ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(left, right); 917ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 918ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 919ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 920ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator.OfDouble spliterator() { 921ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new InternalNodeSpliterator.OfDouble(this); 922ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 923ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 924ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 925ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 926ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** Abstract class for spliterator for all internal node classes */ 927ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static abstract class InternalNodeSpliterator<T, 928ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin S extends Spliterator<T>, 929ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin N extends Node<T>> 930ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator<T> { 931ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Node we are pointing to 932ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // null if full traversal has occurred 933ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin N curNode; 934ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 935ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // next child of curNode to consume 936ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin int curChildIndex; 937ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 938ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // The spliterator of the curNode if that node is last and has no children. 939ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // This spliterator will be delegated to for splitting and traversing. 940ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // null if curNode has children 941ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin S lastNodeSpliterator; 942ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 943ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // spliterator used while traversing with tryAdvance 944ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // null if no partial traversal has occurred 945ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin S tryAdvanceSpliterator; 946ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 947ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // node stack used when traversing to search and find leaf nodes 948ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // null if no partial traversal has occurred 949ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Deque<N> tryAdvanceStack; 950ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 951ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin InternalNodeSpliterator(N curNode) { 952ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.curNode = curNode; 953ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 954ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 955ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 956ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Initiate a stack containing, in left-to-right order, the child nodes 957ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * covered by this spliterator 958ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 959ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("unchecked") 960ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected final Deque<N> initStack() { 961ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Bias size to the case where leaf nodes are close to this node 962ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // 8 is the minimum initial capacity for the ArrayDeque implementation 963ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Deque<N> stack = new ArrayDeque<>(8); 964ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin for (int i = curNode.getChildCount() - 1; i >= curChildIndex; i--) 965ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin stack.addFirst((N) curNode.getChild(i)); 966ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return stack; 967ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 968ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 969ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 970ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Depth first search, in left-to-right order, of the node tree, using 971ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * an explicit stack, to find the next non-empty leaf node. 972ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 973ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("unchecked") 974ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected final N findNextLeafNode(Deque<N> stack) { 975ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin N n = null; 976ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin while ((n = stack.pollFirst()) != null) { 977ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (n.getChildCount() == 0) { 978ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (n.count() > 0) 979ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return n; 980ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } else { 981ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin for (int i = n.getChildCount() - 1; i >= 0; i--) 982ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin stack.addFirst((N) n.getChild(i)); 983ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 984ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 985ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 986ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return null; 987ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 988ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 989ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("unchecked") 990ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected final boolean initTryAdvance() { 991ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (curNode == null) 992ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return false; 993ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 994ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (tryAdvanceSpliterator == null) { 995ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (lastNodeSpliterator == null) { 996ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Initiate the node stack 997ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin tryAdvanceStack = initStack(); 998ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin N leaf = findNextLeafNode(tryAdvanceStack); 999ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (leaf != null) 1000ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin tryAdvanceSpliterator = (S) leaf.spliterator(); 1001ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else { 1002ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // A non-empty leaf node was not found 1003ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // No elements to traverse 1004ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin curNode = null; 1005ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return false; 1006ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1007ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1008ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else 1009ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin tryAdvanceSpliterator = lastNodeSpliterator; 1010ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1011ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return true; 1012ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1013ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1014ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1015ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("unchecked") 1016ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public final S trySplit() { 1017ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (curNode == null || tryAdvanceSpliterator != null) 1018ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return null; // Cannot split if fully or partially traversed 1019ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else if (lastNodeSpliterator != null) 1020ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return (S) lastNodeSpliterator.trySplit(); 1021ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else if (curChildIndex < curNode.getChildCount() - 1) 1022ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return (S) curNode.getChild(curChildIndex++).spliterator(); 1023ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else { 1024ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin curNode = (N) curNode.getChild(curChildIndex); 1025ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (curNode.getChildCount() == 0) { 1026ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin lastNodeSpliterator = (S) curNode.spliterator(); 1027ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return (S) lastNodeSpliterator.trySplit(); 1028ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1029ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else { 1030ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin curChildIndex = 0; 1031ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return (S) curNode.getChild(curChildIndex++).spliterator(); 1032ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1033ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1034ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1035ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1036ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1037ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public final long estimateSize() { 1038ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (curNode == null) 1039ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return 0; 1040ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1041ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Will not reflect the effects of partial traversal. 1042ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // This is compliant with the specification 1043ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (lastNodeSpliterator != null) 1044ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return lastNodeSpliterator.estimateSize(); 1045ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else { 1046ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long size = 0; 1047ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin for (int i = curChildIndex; i < curNode.getChildCount(); i++) 1048ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin size += curNode.getChild(i).count(); 1049ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return size; 1050ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1051ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1052ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1053ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1054ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public final int characteristics() { 1055ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return Spliterator.SIZED; 1056ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1057ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1058ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final class OfRef<T> 1059ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends InternalNodeSpliterator<T, Spliterator<T>, Node<T>> { 1060ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1061ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfRef(Node<T> curNode) { 1062ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(curNode); 1063ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1064ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1065ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1066ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public boolean tryAdvance(Consumer<? super T> consumer) { 1067ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (!initTryAdvance()) 1068ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return false; 1069ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1070ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin boolean hasNext = tryAdvanceSpliterator.tryAdvance(consumer); 1071ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (!hasNext) { 1072ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (lastNodeSpliterator == null) { 1073ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Advance to the spliterator of the next non-empty leaf node 1074ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Node<T> leaf = findNextLeafNode(tryAdvanceStack); 1075ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (leaf != null) { 1076ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin tryAdvanceSpliterator = leaf.spliterator(); 1077ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Since the node is not-empty the spliterator can be advanced 1078ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return tryAdvanceSpliterator.tryAdvance(consumer); 1079ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1080ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1081ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // No more elements to traverse 1082ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin curNode = null; 1083ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1084ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return hasNext; 1085ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1086ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1087ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1088ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEachRemaining(Consumer<? super T> consumer) { 1089ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (curNode == null) 1090ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return; 1091ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1092ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (tryAdvanceSpliterator == null) { 1093ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (lastNodeSpliterator == null) { 1094ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Deque<Node<T>> stack = initStack(); 1095ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Node<T> leaf; 1096ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin while ((leaf = findNextLeafNode(stack)) != null) { 1097ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin leaf.forEach(consumer); 1098ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1099ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin curNode = null; 1100ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1101ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else 1102ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin lastNodeSpliterator.forEachRemaining(consumer); 1103ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1104ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else 1105ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin while(tryAdvance(consumer)) { } 1106ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1107ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1108ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1109ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static abstract class OfPrimitive<T, T_CONS, T_ARR, 1110ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>, 1111ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin N extends Node.OfPrimitive<T, T_CONS, T_ARR, T_SPLITR, N>> 1112ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends InternalNodeSpliterator<T, T_SPLITR, N> 1113ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator.OfPrimitive<T, T_CONS, T_SPLITR> { 1114ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1115ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfPrimitive(N cur) { 1116ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(cur); 1117ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1118ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1119ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1120ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public boolean tryAdvance(T_CONS consumer) { 1121ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (!initTryAdvance()) 1122ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return false; 1123ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1124ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin boolean hasNext = tryAdvanceSpliterator.tryAdvance(consumer); 1125ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (!hasNext) { 1126ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (lastNodeSpliterator == null) { 1127ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Advance to the spliterator of the next non-empty leaf node 1128ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin N leaf = findNextLeafNode(tryAdvanceStack); 1129ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (leaf != null) { 1130ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin tryAdvanceSpliterator = leaf.spliterator(); 1131ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Since the node is not-empty the spliterator can be advanced 1132ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return tryAdvanceSpliterator.tryAdvance(consumer); 1133ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1134ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1135ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // No more elements to traverse 1136ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin curNode = null; 1137ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1138ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return hasNext; 1139ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1140ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1141ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1142ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEachRemaining(T_CONS consumer) { 1143ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (curNode == null) 1144ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return; 1145ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1146ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (tryAdvanceSpliterator == null) { 1147ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (lastNodeSpliterator == null) { 1148ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Deque<N> stack = initStack(); 1149ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin N leaf; 1150ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin while ((leaf = findNextLeafNode(stack)) != null) { 1151ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin leaf.forEach(consumer); 1152ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1153ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin curNode = null; 1154ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1155ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else 1156ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin lastNodeSpliterator.forEachRemaining(consumer); 1157ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1158ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else 1159ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin while(tryAdvance(consumer)) { } 1160ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1161ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1162ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1163ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final class OfInt 1164ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends OfPrimitive<Integer, IntConsumer, int[], Spliterator.OfInt, Node.OfInt> 1165ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator.OfInt { 1166ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1167ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfInt(Node.OfInt cur) { 1168ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(cur); 1169ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1170ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1171ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1172ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final class OfLong 1173ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends OfPrimitive<Long, LongConsumer, long[], Spliterator.OfLong, Node.OfLong> 1174ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator.OfLong { 1175ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1176ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfLong(Node.OfLong cur) { 1177ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(cur); 1178ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1179ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1180ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1181ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final class OfDouble 1182ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends OfPrimitive<Double, DoubleConsumer, double[], Spliterator.OfDouble, Node.OfDouble> 1183ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Spliterator.OfDouble { 1184ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1185ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfDouble(Node.OfDouble cur) { 1186ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(cur); 1187ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1188ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1189ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1190ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1191ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 1192ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Fixed-sized builder class for reference nodes 1193ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 1194ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final class FixedNodeBuilder<T> 1195ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends ArrayNode<T> 1196ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Node.Builder<T> { 1197ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1198ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin FixedNodeBuilder(long size, IntFunction<T[]> generator) { 1199ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(size, generator); 1200ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert size < MAX_ARRAY_SIZE; 1201ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1202ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1203ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1204ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Node<T> build() { 1205ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (curSize < array.length) 1206ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalStateException(String.format("Current size %d is less than fixed size %d", 1207ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin curSize, array.length)); 1208ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return this; 1209ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1210ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1211ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1212ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void begin(long size) { 1213ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (size != array.length) 1214ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalStateException(String.format("Begin size %d is not equal to fixed size %d", 1215ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin size, array.length)); 1216ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin curSize = 0; 1217ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1218ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1219ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1220ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void accept(T t) { 1221ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (curSize < array.length) { 1222ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array[curSize++] = t; 1223ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } else { 1224ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalStateException(String.format("Accept exceeded fixed size of %d", 1225ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array.length)); 1226ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1227ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1228ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1229ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1230ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void end() { 1231ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (curSize < array.length) 1232ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalStateException(String.format("End size %d is less than fixed size %d", 1233ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin curSize, array.length)); 1234ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1235ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1236ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1237ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public String toString() { 1238ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return String.format("FixedNodeBuilder[%d][%s]", 1239ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array.length - curSize, Arrays.toString(array)); 1240ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1241ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1242ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1243ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /** 1244ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Variable-sized builder class for reference nodes 1245ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 1246ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final class SpinedNodeBuilder<T> 1247ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends SpinedBuffer<T> 1248ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Node<T>, Node.Builder<T> { 1249ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private boolean building = false; 1250ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1251ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin SpinedNodeBuilder() {} // Avoid creation of special accessor 1252ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1253ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1254ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator<T> spliterator() { 1255ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert !building : "during building"; 1256ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return super.spliterator(); 1257ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1258ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1259ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1260ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEach(Consumer<? super T> consumer) { 1261ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert !building : "during building"; 1262ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super.forEach(consumer); 1263ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1264ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1265ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // 1266ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1267ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void begin(long size) { 1268ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert !building : "was already building"; 1269ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin building = true; 1270ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin clear(); 1271ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin ensureCapacity(size); 1272ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1273ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1274ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1275ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void accept(T t) { 1276ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert building : "not building"; 1277ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super.accept(t); 1278ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1279ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1280ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1281ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void end() { 1282ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert building : "was not building"; 1283ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin building = false; 1284ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // @@@ check begin(size) and size 1285ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1286ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1287ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1288ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void copyInto(T[] array, int offset) { 1289ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert !building : "during building"; 1290ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super.copyInto(array, offset); 1291ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1292ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1293ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1294ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public T[] asArray(IntFunction<T[]> arrayFactory) { 1295ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert !building : "during building"; 1296ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return super.asArray(arrayFactory); 1297ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1298ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1299ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1300ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Node<T> build() { 1301ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert !building : "during building"; 1302ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return this; 1303ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1304ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1305ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1306ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // 1307ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1308ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final int[] EMPTY_INT_ARRAY = new int[0]; 1309ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final long[] EMPTY_LONG_ARRAY = new long[0]; 1310ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final double[] EMPTY_DOUBLE_ARRAY = new double[0]; 1311ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1312ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static class IntArrayNode implements Node.OfInt { 1313ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin final int[] array; 1314ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin int curSize; 1315ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1316ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin IntArrayNode(long size) { 1317ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (size >= MAX_ARRAY_SIZE) 1318ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalArgumentException(BAD_SIZE); 1319ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.array = new int[(int) size]; 1320ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.curSize = 0; 1321ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1322ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1323ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin IntArrayNode(int[] array) { 1324ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.array = array; 1325ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.curSize = array.length; 1326ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1327ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1328ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Node 1329ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1330ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1331ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator.OfInt spliterator() { 1332ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return Arrays.spliterator(array, 0, curSize); 1333ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1334ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1335ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1336ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public int[] asPrimitiveArray() { 1337ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (array.length == curSize) { 1338ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return array; 1339ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } else { 1340ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return Arrays.copyOf(array, curSize); 1341ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1342ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1343ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1344ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1345ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void copyInto(int[] dest, int destOffset) { 1346ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin System.arraycopy(array, 0, dest, destOffset, curSize); 1347ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1348ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1349ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1350ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public long count() { 1351ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return curSize; 1352ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1353ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1354ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1355ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEach(IntConsumer consumer) { 1356ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin for (int i = 0; i < curSize; i++) { 1357ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin consumer.accept(array[i]); 1358ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1359ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1360ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1361ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1362ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public String toString() { 1363ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return String.format("IntArrayNode[%d][%s]", 1364ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array.length - curSize, Arrays.toString(array)); 1365ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1366ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1367ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1368ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static class LongArrayNode implements Node.OfLong { 1369ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin final long[] array; 1370ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin int curSize; 1371ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1372ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin LongArrayNode(long size) { 1373ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (size >= MAX_ARRAY_SIZE) 1374ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalArgumentException(BAD_SIZE); 1375ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.array = new long[(int) size]; 1376ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.curSize = 0; 1377ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1378ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1379ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin LongArrayNode(long[] array) { 1380ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.array = array; 1381ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.curSize = array.length; 1382ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1383ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1384ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1385ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator.OfLong spliterator() { 1386ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return Arrays.spliterator(array, 0, curSize); 1387ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1388ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1389ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1390ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public long[] asPrimitiveArray() { 1391ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (array.length == curSize) { 1392ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return array; 1393ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } else { 1394ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return Arrays.copyOf(array, curSize); 1395ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1396ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1397ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1398ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1399ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void copyInto(long[] dest, int destOffset) { 1400ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin System.arraycopy(array, 0, dest, destOffset, curSize); 1401ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1402ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1403ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1404ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public long count() { 1405ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return curSize; 1406ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1407ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1408ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1409ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEach(LongConsumer consumer) { 1410ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin for (int i = 0; i < curSize; i++) { 1411ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin consumer.accept(array[i]); 1412ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1413ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1414ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1415ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1416ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public String toString() { 1417ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return String.format("LongArrayNode[%d][%s]", 1418ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array.length - curSize, Arrays.toString(array)); 1419ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1420ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1421ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1422ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static class DoubleArrayNode implements Node.OfDouble { 1423ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin final double[] array; 1424ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin int curSize; 1425ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1426ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin DoubleArrayNode(long size) { 1427ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (size >= MAX_ARRAY_SIZE) 1428ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalArgumentException(BAD_SIZE); 1429ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.array = new double[(int) size]; 1430ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.curSize = 0; 1431ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1432ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1433ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin DoubleArrayNode(double[] array) { 1434ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.array = array; 1435ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.curSize = array.length; 1436ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1437ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1438ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1439ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator.OfDouble spliterator() { 1440ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return Arrays.spliterator(array, 0, curSize); 1441ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1442ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1443ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1444ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public double[] asPrimitiveArray() { 1445ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (array.length == curSize) { 1446ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return array; 1447ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } else { 1448ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return Arrays.copyOf(array, curSize); 1449ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1450ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1451ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1452ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1453ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void copyInto(double[] dest, int destOffset) { 1454ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin System.arraycopy(array, 0, dest, destOffset, curSize); 1455ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1456ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1457ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1458ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public long count() { 1459ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return curSize; 1460ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1461ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1462ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1463ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEach(DoubleConsumer consumer) { 1464ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin for (int i = 0; i < curSize; i++) { 1465ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin consumer.accept(array[i]); 1466ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1467ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1468ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1469ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1470ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public String toString() { 1471ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return String.format("DoubleArrayNode[%d][%s]", 1472ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array.length - curSize, Arrays.toString(array)); 1473ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1474ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1475ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1476ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final class IntFixedNodeBuilder 1477ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends IntArrayNode 1478ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Node.Builder.OfInt { 1479ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1480ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin IntFixedNodeBuilder(long size) { 1481ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(size); 1482ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert size < MAX_ARRAY_SIZE; 1483ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1484ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1485ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1486ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Node.OfInt build() { 1487ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (curSize < array.length) { 1488ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalStateException(String.format("Current size %d is less than fixed size %d", 1489ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin curSize, array.length)); 1490ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1491ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1492ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return this; 1493ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1494ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1495ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1496ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void begin(long size) { 1497ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (size != array.length) { 1498ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalStateException(String.format("Begin size %d is not equal to fixed size %d", 1499ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin size, array.length)); 1500ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1501ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1502ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin curSize = 0; 1503ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1504ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1505ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1506ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void accept(int i) { 1507ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (curSize < array.length) { 1508ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array[curSize++] = i; 1509ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } else { 1510ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalStateException(String.format("Accept exceeded fixed size of %d", 1511ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array.length)); 1512ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1513ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1514ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1515ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1516ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void end() { 1517ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (curSize < array.length) { 1518ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalStateException(String.format("End size %d is less than fixed size %d", 1519ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin curSize, array.length)); 1520ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1521ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1522ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1523ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1524ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public String toString() { 1525ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return String.format("IntFixedNodeBuilder[%d][%s]", 1526ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array.length - curSize, Arrays.toString(array)); 1527ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1528ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1529ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1530ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final class LongFixedNodeBuilder 1531ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends LongArrayNode 1532ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Node.Builder.OfLong { 1533ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1534ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin LongFixedNodeBuilder(long size) { 1535ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(size); 1536ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert size < MAX_ARRAY_SIZE; 1537ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1538ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1539ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1540ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Node.OfLong build() { 1541ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (curSize < array.length) { 1542ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalStateException(String.format("Current size %d is less than fixed size %d", 1543ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin curSize, array.length)); 1544ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1545ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1546ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return this; 1547ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1548ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1549ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1550ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void begin(long size) { 1551ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (size != array.length) { 1552ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalStateException(String.format("Begin size %d is not equal to fixed size %d", 1553ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin size, array.length)); 1554ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1555ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1556ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin curSize = 0; 1557ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1558ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1559ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1560ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void accept(long i) { 1561ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (curSize < array.length) { 1562ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array[curSize++] = i; 1563ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } else { 1564ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalStateException(String.format("Accept exceeded fixed size of %d", 1565ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array.length)); 1566ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1567ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1568ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1569ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1570ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void end() { 1571ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (curSize < array.length) { 1572ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalStateException(String.format("End size %d is less than fixed size %d", 1573ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin curSize, array.length)); 1574ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1575ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1576ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1577ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1578ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public String toString() { 1579ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return String.format("LongFixedNodeBuilder[%d][%s]", 1580ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array.length - curSize, Arrays.toString(array)); 1581ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1582ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1583ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1584ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final class DoubleFixedNodeBuilder 1585ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends DoubleArrayNode 1586ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Node.Builder.OfDouble { 1587ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1588ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin DoubleFixedNodeBuilder(long size) { 1589ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(size); 1590ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert size < MAX_ARRAY_SIZE; 1591ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1592ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1593ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1594ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Node.OfDouble build() { 1595ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (curSize < array.length) { 1596ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalStateException(String.format("Current size %d is less than fixed size %d", 1597ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin curSize, array.length)); 1598ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1599ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1600ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return this; 1601ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1602ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1603ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1604ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void begin(long size) { 1605ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (size != array.length) { 1606ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalStateException(String.format("Begin size %d is not equal to fixed size %d", 1607ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin size, array.length)); 1608ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1609ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1610ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin curSize = 0; 1611ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1612ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1613ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1614ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void accept(double i) { 1615ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (curSize < array.length) { 1616ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array[curSize++] = i; 1617ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } else { 1618ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalStateException(String.format("Accept exceeded fixed size of %d", 1619ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array.length)); 1620ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1621ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1622ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1623ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1624ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void end() { 1625ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (curSize < array.length) { 1626ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalStateException(String.format("End size %d is less than fixed size %d", 1627ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin curSize, array.length)); 1628ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1629ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1630ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1631ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1632ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public String toString() { 1633ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return String.format("DoubleFixedNodeBuilder[%d][%s]", 1634ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array.length - curSize, Arrays.toString(array)); 1635ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1636ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1637ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1638ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final class IntSpinedNodeBuilder 1639ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends SpinedBuffer.OfInt 1640ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Node.OfInt, Node.Builder.OfInt { 1641ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private boolean building = false; 1642ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1643ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin IntSpinedNodeBuilder() {} // Avoid creation of special accessor 1644ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1645ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1646ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator.OfInt spliterator() { 1647ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert !building : "during building"; 1648ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return super.spliterator(); 1649ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1650ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1651ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1652ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEach(IntConsumer consumer) { 1653ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert !building : "during building"; 1654ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super.forEach(consumer); 1655ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1656ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1657ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // 1658ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1659ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void begin(long size) { 1660ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert !building : "was already building"; 1661ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin building = true; 1662ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin clear(); 1663ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin ensureCapacity(size); 1664ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1665ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1666ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1667ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void accept(int i) { 1668ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert building : "not building"; 1669ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super.accept(i); 1670ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1671ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1672ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1673ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void end() { 1674ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert building : "was not building"; 1675ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin building = false; 1676ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // @@@ check begin(size) and size 1677ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1678ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1679ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1680ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void copyInto(int[] array, int offset) throws IndexOutOfBoundsException { 1681ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert !building : "during building"; 1682ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super.copyInto(array, offset); 1683ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1684ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1685ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1686ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public int[] asPrimitiveArray() { 1687ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert !building : "during building"; 1688ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return super.asPrimitiveArray(); 1689ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1690ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1691ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1692ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Node.OfInt build() { 1693ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert !building : "during building"; 1694ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return this; 1695ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1696ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1697ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1698ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final class LongSpinedNodeBuilder 1699ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends SpinedBuffer.OfLong 1700ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Node.OfLong, Node.Builder.OfLong { 1701ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private boolean building = false; 1702ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1703ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin LongSpinedNodeBuilder() {} // Avoid creation of special accessor 1704ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1705ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1706ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator.OfLong spliterator() { 1707ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert !building : "during building"; 1708ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return super.spliterator(); 1709ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1710ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1711ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1712ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEach(LongConsumer consumer) { 1713ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert !building : "during building"; 1714ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super.forEach(consumer); 1715ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1716ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1717ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // 1718ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1719ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void begin(long size) { 1720ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert !building : "was already building"; 1721ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin building = true; 1722ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin clear(); 1723ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin ensureCapacity(size); 1724ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1725ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1726ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1727ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void accept(long i) { 1728ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert building : "not building"; 1729ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super.accept(i); 1730ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1731ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1732ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1733ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void end() { 1734ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert building : "was not building"; 1735ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin building = false; 1736ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // @@@ check begin(size) and size 1737ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1738ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1739ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1740ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void copyInto(long[] array, int offset) { 1741ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert !building : "during building"; 1742ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super.copyInto(array, offset); 1743ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1744ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1745ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1746ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public long[] asPrimitiveArray() { 1747ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert !building : "during building"; 1748ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return super.asPrimitiveArray(); 1749ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1750ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1751ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1752ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Node.OfLong build() { 1753ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert !building : "during building"; 1754ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return this; 1755ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1756ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1757ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1758ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final class DoubleSpinedNodeBuilder 1759ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends SpinedBuffer.OfDouble 1760ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Node.OfDouble, Node.Builder.OfDouble { 1761ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private boolean building = false; 1762ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1763ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin DoubleSpinedNodeBuilder() {} // Avoid creation of special accessor 1764ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1765ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1766ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Spliterator.OfDouble spliterator() { 1767ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert !building : "during building"; 1768ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return super.spliterator(); 1769ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1770ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1771ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1772ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void forEach(DoubleConsumer consumer) { 1773ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert !building : "during building"; 1774ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super.forEach(consumer); 1775ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1776ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1777ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // 1778ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1779ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void begin(long size) { 1780ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert !building : "was already building"; 1781ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin building = true; 1782ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin clear(); 1783ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin ensureCapacity(size); 1784ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1785ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1786ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1787ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void accept(double i) { 1788ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert building : "not building"; 1789ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super.accept(i); 1790ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1791ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1792ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1793ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void end() { 1794ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert building : "was not building"; 1795ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin building = false; 1796ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // @@@ check begin(size) and size 1797ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1798ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1799ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1800ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void copyInto(double[] array, int offset) { 1801ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert !building : "during building"; 1802ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super.copyInto(array, offset); 1803ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1804ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1805ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1806ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public double[] asPrimitiveArray() { 1807ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert !building : "during building"; 1808ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return super.asPrimitiveArray(); 1809ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1810ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1811ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1812ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public Node.OfDouble build() { 1813ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert !building : "during building"; 1814ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return this; 1815ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1816ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1817ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1818ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin /* 1819ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * This and subclasses are not intended to be serializable 1820ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */ 1821ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("serial") 1822ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static abstract class SizedCollectorTask<P_IN, P_OUT, T_SINK extends Sink<P_OUT>, 1823ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin K extends SizedCollectorTask<P_IN, P_OUT, T_SINK, K>> 1824ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends CountedCompleter<Void> 1825ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Sink<P_OUT> { 1826ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected final Spliterator<P_IN> spliterator; 1827ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected final PipelineHelper<P_OUT> helper; 1828ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected final long targetSize; 1829ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected long offset; 1830ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected long length; 1831ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // For Sink implementation 1832ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected int index, fence; 1833ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1834ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin SizedCollectorTask(Spliterator<P_IN> spliterator, 1835ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin PipelineHelper<P_OUT> helper, 1836ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin int arrayLength) { 1837ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert spliterator.hasCharacteristics(Spliterator.SUBSIZED); 1838ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.spliterator = spliterator; 1839ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.helper = helper; 1840ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.targetSize = AbstractTask.suggestTargetSize(spliterator.estimateSize()); 1841ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.offset = 0; 1842ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.length = arrayLength; 1843ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1844ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1845ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin SizedCollectorTask(K parent, Spliterator<P_IN> spliterator, 1846ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long offset, long length, int arrayLength) { 1847ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(parent); 1848ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert spliterator.hasCharacteristics(Spliterator.SUBSIZED); 1849ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.spliterator = spliterator; 1850ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.helper = parent.helper; 1851ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.targetSize = parent.targetSize; 1852ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.offset = offset; 1853ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.length = length; 1854ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1855ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (offset < 0 || length < 0 || (offset + length - 1 >= arrayLength)) { 1856ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalArgumentException( 1857ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin String.format("offset and length interval [%d, %d + %d) is not within array size interval [0, %d)", 1858ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin offset, offset, length, arrayLength)); 1859ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1860ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1861ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1862ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1863ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void compute() { 1864ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin SizedCollectorTask<P_IN, P_OUT, T_SINK, K> task = this; 1865ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Spliterator<P_IN> rightSplit = spliterator, leftSplit; 1866ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin while (rightSplit.estimateSize() > task.targetSize && 1867ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin (leftSplit = rightSplit.trySplit()) != null) { 1868ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin task.setPendingCount(1); 1869ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long leftSplitSize = leftSplit.estimateSize(); 1870ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin task.makeChild(leftSplit, task.offset, leftSplitSize).fork(); 1871ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin task = task.makeChild(rightSplit, task.offset + leftSplitSize, 1872ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin task.length - leftSplitSize); 1873ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1874ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1875ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin assert task.offset + task.length < MAX_ARRAY_SIZE; 1876ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("unchecked") 1877ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T_SINK sink = (T_SINK) task; 1878ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin task.helper.wrapAndCopyInto(sink, rightSplit); 1879ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin task.propagateCompletion(); 1880ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1881ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1882ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin abstract K makeChild(Spliterator<P_IN> spliterator, long offset, long size); 1883ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1884ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1885ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void begin(long size) { 1886ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (size > length) 1887ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IllegalStateException("size passed to Sink.begin exceeds array length"); 1888ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // Casts to int are safe since absolute size is verified to be within 1889ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // bounds when the root concrete SizedCollectorTask is constructed 1890ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin // with the shared array 1891ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin index = (int) offset; 1892ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin fence = index + (int) length; 1893ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1894ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1895ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("serial") 1896ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfRef<P_IN, P_OUT> 1897ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends SizedCollectorTask<P_IN, P_OUT, Sink<P_OUT>, OfRef<P_IN, P_OUT>> 1898ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Sink<P_OUT> { 1899ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private final P_OUT[] array; 1900ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1901ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfRef(Spliterator<P_IN> spliterator, PipelineHelper<P_OUT> helper, P_OUT[] array) { 1902ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(spliterator, helper, array.length); 1903ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.array = array; 1904ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1905ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1906ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfRef(OfRef<P_IN, P_OUT> parent, Spliterator<P_IN> spliterator, 1907ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long offset, long length) { 1908ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(parent, spliterator, offset, length, parent.array.length); 1909ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.array = parent.array; 1910ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1911ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1912ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1913ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfRef<P_IN, P_OUT> makeChild(Spliterator<P_IN> spliterator, 1914ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long offset, long size) { 1915ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new OfRef<>(this, spliterator, offset, size); 1916ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1917ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1918ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1919ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void accept(P_OUT value) { 1920ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (index >= fence) { 1921ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IndexOutOfBoundsException(Integer.toString(index)); 1922ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1923ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array[index++] = value; 1924ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1925ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1926ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1927ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("serial") 1928ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfInt<P_IN> 1929ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends SizedCollectorTask<P_IN, Integer, Sink.OfInt, OfInt<P_IN>> 1930ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Sink.OfInt { 1931ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private final int[] array; 1932ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1933ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfInt(Spliterator<P_IN> spliterator, PipelineHelper<Integer> helper, int[] array) { 1934ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(spliterator, helper, array.length); 1935ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.array = array; 1936ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1937ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1938ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfInt(SizedCollectorTask.OfInt<P_IN> parent, Spliterator<P_IN> spliterator, 1939ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long offset, long length) { 1940ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(parent, spliterator, offset, length, parent.array.length); 1941ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.array = parent.array; 1942ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1943ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1944ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1945ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin SizedCollectorTask.OfInt<P_IN> makeChild(Spliterator<P_IN> spliterator, 1946ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long offset, long size) { 1947ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new SizedCollectorTask.OfInt<>(this, spliterator, offset, size); 1948ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1949ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1950ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1951ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void accept(int value) { 1952ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (index >= fence) { 1953ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IndexOutOfBoundsException(Integer.toString(index)); 1954ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1955ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array[index++] = value; 1956ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1957ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1958ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1959ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("serial") 1960ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfLong<P_IN> 1961ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends SizedCollectorTask<P_IN, Long, Sink.OfLong, OfLong<P_IN>> 1962ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Sink.OfLong { 1963ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private final long[] array; 1964ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1965ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfLong(Spliterator<P_IN> spliterator, PipelineHelper<Long> helper, long[] array) { 1966ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(spliterator, helper, array.length); 1967ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.array = array; 1968ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1969ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1970ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfLong(SizedCollectorTask.OfLong<P_IN> parent, Spliterator<P_IN> spliterator, 1971ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long offset, long length) { 1972ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(parent, spliterator, offset, length, parent.array.length); 1973ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.array = parent.array; 1974ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1975ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1976ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1977ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin SizedCollectorTask.OfLong<P_IN> makeChild(Spliterator<P_IN> spliterator, 1978ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long offset, long size) { 1979ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new SizedCollectorTask.OfLong<>(this, spliterator, offset, size); 1980ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1981ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1982ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 1983ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void accept(long value) { 1984ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (index >= fence) { 1985ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IndexOutOfBoundsException(Integer.toString(index)); 1986ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1987ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array[index++] = value; 1988ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1989ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 1990ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1991ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("serial") 1992ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin static final class OfDouble<P_IN> 1993ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends SizedCollectorTask<P_IN, Double, Sink.OfDouble, OfDouble<P_IN>> 1994ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin implements Sink.OfDouble { 1995ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private final double[] array; 1996ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 1997ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfDouble(Spliterator<P_IN> spliterator, PipelineHelper<Double> helper, double[] array) { 1998ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(spliterator, helper, array.length); 1999ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.array = array; 2000ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2001ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2002ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfDouble(SizedCollectorTask.OfDouble<P_IN> parent, Spliterator<P_IN> spliterator, 2003ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long offset, long length) { 2004ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(parent, spliterator, offset, length, parent.array.length); 2005ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.array = parent.array; 2006ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2007ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2008ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 2009ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin SizedCollectorTask.OfDouble<P_IN> makeChild(Spliterator<P_IN> spliterator, 2010ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin long offset, long size) { 2011ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new SizedCollectorTask.OfDouble<>(this, spliterator, offset, size); 2012ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2013ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2014ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 2015ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void accept(double value) { 2016ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (index >= fence) { 2017ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin throw new IndexOutOfBoundsException(Integer.toString(index)); 2018ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2019ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin array[index++] = value; 2020ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2021ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2022ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2023ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2024ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("serial") 2025ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static abstract class ToArrayTask<T, T_NODE extends Node<T>, 2026ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin K extends ToArrayTask<T, T_NODE, K>> 2027ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends CountedCompleter<Void> { 2028ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected final T_NODE node; 2029ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected final int offset; 2030ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2031ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin ToArrayTask(T_NODE node, int offset) { 2032ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.node = node; 2033ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.offset = offset; 2034ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2035ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2036ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin ToArrayTask(K parent, T_NODE node, int offset) { 2037ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(parent); 2038ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.node = node; 2039ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.offset = offset; 2040ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2041ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2042ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin abstract void copyNodeToArray(); 2043ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2044ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin abstract K makeChild(int childIndex, int offset); 2045ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2046ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 2047ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void compute() { 2048ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin ToArrayTask<T, T_NODE, K> task = this; 2049ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin while (true) { 2050ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (task.node.getChildCount() == 0) { 2051ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin task.copyNodeToArray(); 2052ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin task.propagateCompletion(); 2053ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return; 2054ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2055ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin else { 2056ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin task.setPendingCount(task.node.getChildCount() - 1); 2057ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2058ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin int size = 0; 2059ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin int i = 0; 2060ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin for (;i < task.node.getChildCount() - 1; i++) { 2061ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin K leftTask = task.makeChild(i, task.offset + size); 2062ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin size += leftTask.node.count(); 2063ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin leftTask.fork(); 2064ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2065ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin task = task.makeChild(i, task.offset + size); 2066ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2067ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2068ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2069ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2070ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("serial") 2071ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final class OfRef<T> 2072ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends ToArrayTask<T, Node<T>, OfRef<T>> { 2073ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private final T[] array; 2074ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2075ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private OfRef(Node<T> node, T[] array, int offset) { 2076ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(node, offset); 2077ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.array = array; 2078ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2079ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2080ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private OfRef(OfRef<T> parent, Node<T> node, int offset) { 2081ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(parent, node, offset); 2082ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.array = parent.array; 2083ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2084ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2085ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 2086ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfRef<T> makeChild(int childIndex, int offset) { 2087ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new OfRef<>(this, node.getChild(childIndex), offset); 2088ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2089ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2090ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 2091ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin void copyNodeToArray() { 2092ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin node.copyInto(array, offset); 2093ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2094ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2095ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2096ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("serial") 2097ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static class OfPrimitive<T, T_CONS, T_ARR, 2098ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>, 2099ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T_NODE extends Node.OfPrimitive<T, T_CONS, T_ARR, T_SPLITR, T_NODE>> 2100ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends ToArrayTask<T, T_NODE, OfPrimitive<T, T_CONS, T_ARR, T_SPLITR, T_NODE>> { 2101ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private final T_ARR array; 2102ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2103ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private OfPrimitive(T_NODE node, T_ARR array, int offset) { 2104ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(node, offset); 2105ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.array = array; 2106ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2107ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2108ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private OfPrimitive(OfPrimitive<T, T_CONS, T_ARR, T_SPLITR, T_NODE> parent, T_NODE node, int offset) { 2109ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(parent, node, offset); 2110ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.array = parent.array; 2111ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2112ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2113ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 2114ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfPrimitive<T, T_CONS, T_ARR, T_SPLITR, T_NODE> makeChild(int childIndex, int offset) { 2115ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new OfPrimitive<>(this, node.getChild(childIndex), offset); 2116ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2117ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2118ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 2119ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin void copyNodeToArray() { 2120ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin node.copyInto(array, offset); 2121ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2122ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2123ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2124ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("serial") 2125ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final class OfInt 2126ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends OfPrimitive<Integer, IntConsumer, int[], Spliterator.OfInt, Node.OfInt> { 2127ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private OfInt(Node.OfInt node, int[] array, int offset) { 2128ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(node, array, offset); 2129ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2130ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2131ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2132ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("serial") 2133ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final class OfLong 2134ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends OfPrimitive<Long, LongConsumer, long[], Spliterator.OfLong, Node.OfLong> { 2135ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private OfLong(Node.OfLong node, long[] array, int offset) { 2136ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(node, array, offset); 2137ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2138ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2139ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2140ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("serial") 2141ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final class OfDouble 2142ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends OfPrimitive<Double, DoubleConsumer, double[], Spliterator.OfDouble, Node.OfDouble> { 2143ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private OfDouble(Node.OfDouble node, double[] array, int offset) { 2144ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(node, array, offset); 2145ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2146ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2147ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2148ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2149ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("serial") 2150ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static class CollectorTask<P_IN, P_OUT, T_NODE extends Node<P_OUT>, T_BUILDER extends Node.Builder<P_OUT>> 2151ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends AbstractTask<P_IN, P_OUT, T_NODE, CollectorTask<P_IN, P_OUT, T_NODE, T_BUILDER>> { 2152ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected final PipelineHelper<P_OUT> helper; 2153ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected final LongFunction<T_BUILDER> builderFactory; 2154ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected final BinaryOperator<T_NODE> concFactory; 2155ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2156ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin CollectorTask(PipelineHelper<P_OUT> helper, 2157ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Spliterator<P_IN> spliterator, 2158ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin LongFunction<T_BUILDER> builderFactory, 2159ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin BinaryOperator<T_NODE> concFactory) { 2160ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(helper, spliterator); 2161ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.helper = helper; 2162ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.builderFactory = builderFactory; 2163ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin this.concFactory = concFactory; 2164ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2165ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2166ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin CollectorTask(CollectorTask<P_IN, P_OUT, T_NODE, T_BUILDER> parent, 2167ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Spliterator<P_IN> spliterator) { 2168ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(parent, spliterator); 2169ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin helper = parent.helper; 2170ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin builderFactory = parent.builderFactory; 2171ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin concFactory = parent.concFactory; 2172ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2173ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2174ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 2175ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected CollectorTask<P_IN, P_OUT, T_NODE, T_BUILDER> makeChild(Spliterator<P_IN> spliterator) { 2176ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return new CollectorTask<>(this, spliterator); 2177ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2178ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2179ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 2180ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("unchecked") 2181ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin protected T_NODE doLeaf() { 2182ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin T_BUILDER builder = builderFactory.apply(helper.exactOutputSizeIfKnown(spliterator)); 2183ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin return (T_NODE) helper.wrapAndCopyInto(builder, spliterator).build(); 2184ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2185ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2186ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @Override 2187ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin public void onCompletion(CountedCompleter<?> caller) { 2188ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin if (!isLeaf()) 2189ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin setLocalResult(concFactory.apply(leftChild.getLocalResult(), rightChild.getLocalResult())); 2190ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super.onCompletion(caller); 2191ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2192ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2193ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("serial") 2194ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final class OfRef<P_IN, P_OUT> 2195ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends CollectorTask<P_IN, P_OUT, Node<P_OUT>, Node.Builder<P_OUT>> { 2196ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfRef(PipelineHelper<P_OUT> helper, 2197ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin IntFunction<P_OUT[]> generator, 2198ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin Spliterator<P_IN> spliterator) { 2199ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(helper, spliterator, s -> builder(s, generator), ConcNode::new); 2200ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2201ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2202ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2203ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("serial") 2204ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final class OfInt<P_IN> 2205ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends CollectorTask<P_IN, Integer, Node.OfInt, Node.Builder.OfInt> { 2206ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfInt(PipelineHelper<Integer> helper, Spliterator<P_IN> spliterator) { 2207ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(helper, spliterator, Nodes::intBuilder, ConcNode.OfInt::new); 2208ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2209ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2210ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2211ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("serial") 2212ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final class OfLong<P_IN> 2213ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends CollectorTask<P_IN, Long, Node.OfLong, Node.Builder.OfLong> { 2214ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfLong(PipelineHelper<Long> helper, Spliterator<P_IN> spliterator) { 2215ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(helper, spliterator, Nodes::longBuilder, ConcNode.OfLong::new); 2216ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2217ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2218ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin 2219ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin @SuppressWarnings("serial") 2220ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin private static final class OfDouble<P_IN> 2221ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin extends CollectorTask<P_IN, Double, Node.OfDouble, Node.Builder.OfDouble> { 2222ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin OfDouble(PipelineHelper<Double> helper, Spliterator<P_IN> spliterator) { 2223ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin super(helper, spliterator, Nodes::doubleBuilder, ConcNode.OfDouble::new); 2224ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2225ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2226ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin } 2227ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin} 2228