AbstractConcNode(T_NODE left, T_NODE right) { this.left = left; this.right = right; // The Node count will be required when the Node spliterator is // obtained and it is cheaper to aggressively calculate bottom up // as the tree is built rather than later on from the top down // traversing the tree this.size = left.count() + right.count(); }
AbstractConcNode(T_NODE left, T_NODE right) { this.left = left; this.right = right; // The Node count will be required when the Node spliterator is // obtained and it is cheaper to aggressively calculate bottom up // as the tree is built rather than later on from the top down // traversing the tree this.size = left.count() + right.count(); }
private Node<P_OUT> doTruncate(Node<P_OUT> input) { return isOrdered ? input.truncate(index, input.count(), generator) : input; } }
private Node<P_OUT> doTruncate(Node<P_OUT> input) { long to = targetSize >= 0 ? Math.min(input.count(), targetOffset + targetSize) : thisNodeSize; return input.truncate(targetOffset, to, generator); }
private Node<P_OUT> doTruncate(Node<P_OUT> input) { long to = targetSize >= 0 ? Math.min(input.count(), targetOffset + targetSize) : thisNodeSize; return input.truncate(targetOffset, to, generator); }
private Node<P_OUT> doTruncate(Node<P_OUT> input) { return isOrdered ? input.truncate(index, input.count(), generator) : input; } }
/** * Depth first search, in left-to-right order, of the node tree, using * an explicit stack, to find the next non-empty leaf node. */ @SuppressWarnings("unchecked") protected final N findNextLeafNode(Deque<N> stack) { N n = null; while ((n = stack.pollFirst()) != null) { if (n.getChildCount() == 0) { if (n.count() > 0) return n; } else { for (int i = n.getChildCount() - 1; i >= 0; i--) stack.addFirst((N) n.getChild(i)); } } return null; }
/** * Depth first search, in left-to-right order, of the node tree, using * an explicit stack, to find the next non-empty leaf node. */ @SuppressWarnings("unchecked") protected final N findNextLeafNode(Deque<N> stack) { N n = null; while ((n = stack.pollFirst()) != null) { if (n.getChildCount() == 0) { if (n.count() > 0) return n; } else { for (int i = n.getChildCount() - 1; i >= 0; i--) stack.addFirst((N) n.getChild(i)); } } return null; }
@Override public void copyInto(T[] array, int offset) { Objects.requireNonNull(array); left.copyInto(array, offset); // Cast to int is safe since it is the callers responsibility to // ensure that there is sufficient room in the array right.copyInto(array, offset + (int) left.count()); }
@Override public void copyInto(T[] array, int offset) { Objects.requireNonNull(array); left.copyInto(array, offset); // Cast to int is safe since it is the callers responsibility to // ensure that there is sufficient room in the array right.copyInto(array, offset + (int) left.count()); }
@Override public final long estimateSize() { if (curNode == null) return 0; // Will not reflect the effects of partial traversal. // This is compliant with the specification if (lastNodeSpliterator != null) return lastNodeSpliterator.estimateSize(); else { long size = 0; for (int i = curChildIndex; i < curNode.getChildCount(); i++) size += curNode.getChild(i).count(); return size; } }
@Override public final long estimateSize() { if (curNode == null) return 0; // Will not reflect the effects of partial traversal. // This is compliant with the specification if (lastNodeSpliterator != null) return lastNodeSpliterator.estimateSize(); else { long size = 0; for (int i = curChildIndex; i < curNode.getChildCount(); i++) size += curNode.getChild(i).count(); return size; } }
/** * Flatten, in parallel, a {@link Node}. A flattened node is one that has * no children. If the node is already flat, it is simply returned. * * <p><b>Implementation Requirements:</b><br> * If a new node is to be created, the generator is used to create an array * whose length is {@link Node#count()}. Then the node tree is traversed * and leaf node elements are placed in the array concurrently by leaf tasks * at the correct offsets. * * @param <T> type of elements contained by the node * @param node the node to flatten * @param generator the array factory used to create array instances * @return a flat {@code Node} */ public static <T> Node<T> flatten(Node<T> node, IntFunction<T[]> generator) { if (node.getChildCount() > 0) { long size = node.count(); if (size >= MAX_ARRAY_SIZE) throw new IllegalArgumentException(BAD_SIZE); T[] array = generator.apply((int) size); new ToArrayTask.OfRef<>(node, array, 0).invoke(); return node(array); } else { return node; } }
@Override protected final Node<P_OUT> doLeaf() { Node.Builder<P_OUT> builder = helper.makeNodeBuilder(-1, generator); Sink<P_OUT> s = op.opWrapSink(helper.getStreamAndOpFlags(), builder); if (shortCircuited = helper.copyIntoWithCancel(helper.wrapSink(s), spliterator)) { // Cancel later nodes if the predicate returned false // during traversal cancelLaterNodes(); } Node<P_OUT> node = builder.build(); thisNodeSize = node.count(); return node; }
@Override protected final Node<P_OUT> doLeaf() { Node.Builder<P_OUT> builder = helper.makeNodeBuilder(-1, generator); Sink<P_OUT> s = op.opWrapSink(helper.getStreamAndOpFlags(), builder); if (shortCircuited = helper.copyIntoWithCancel(helper.wrapSink(s), spliterator)) { // Cancel later nodes if the predicate returned false // during traversal cancelLaterNodes(); } Node<P_OUT> node = builder.build(); thisNodeSize = node.count(); return node; }
@Override public Node<T> truncate(long from, long to, IntFunction<T[]> generator) { if (from == 0 && to == count()) return this; long leftCount = left.count(); if (from >= leftCount) return right.truncate(from - leftCount, to - leftCount, generator); else if (to <= leftCount) return left.truncate(from, to, generator); else { return Nodes.conc(getShape(), left.truncate(from, leftCount, generator), right.truncate(0, to - leftCount, generator)); } }
@Override public Node<T> truncate(long from, long to, IntFunction<T[]> generator) { if (from == 0 && to == count()) return this; long leftCount = left.count(); if (from >= leftCount) return right.truncate(from - leftCount, to - leftCount, generator); else if (to <= leftCount) return left.truncate(from, to, generator); else { return Nodes.conc(getShape(), left.truncate(from, leftCount, generator), right.truncate(0, to - leftCount, generator)); } }
@Override protected final Node<P_OUT> doLeaf() { boolean isChild = !isRoot(); // If this not the root and pipeline is ordered and size is known // then pre-size the builder long sizeIfKnown = isChild && isOrdered && StreamOpFlag.SIZED.isPreserved(op.sourceOrOpFlags) ? op.exactOutputSizeIfKnown(spliterator) : -1; Node.Builder<P_OUT> builder = helper.makeNodeBuilder(sizeIfKnown, generator); @SuppressWarnings("unchecked") DropWhileOp<P_OUT> dropOp = (DropWhileOp<P_OUT>) op; // If this leaf is the root then there is no merging on completion // and there is no need to retain dropped elements DropWhileSink<P_OUT> s = dropOp.opWrapSink(builder, isOrdered && isChild); helper.wrapAndCopyInto(s, spliterator); Node<P_OUT> node = builder.build(); thisNodeSize = node.count(); index = s.getDropCount(); return node; }
@Override protected final Node<P_OUT> doLeaf() { boolean isChild = !isRoot(); // If this not the root and pipeline is ordered and size is known // then pre-size the builder long sizeIfKnown = isChild && isOrdered && StreamOpFlag.SIZED.isPreserved(op.sourceOrOpFlags) ? op.exactOutputSizeIfKnown(spliterator) : -1; Node.Builder<P_OUT> builder = helper.makeNodeBuilder(sizeIfKnown, generator); @SuppressWarnings("unchecked") DropWhileOp<P_OUT> dropOp = (DropWhileOp<P_OUT>) op; // If this leaf is the root then there is no merging on completion // and there is no need to retain dropped elements DropWhileSink<P_OUT> s = dropOp.opWrapSink(builder, isOrdered && isChild); helper.wrapAndCopyInto(s, spliterator); Node<P_OUT> node = builder.build(); thisNodeSize = node.count(); index = s.getDropCount(); return node; }
@Override public void compute() { ToArrayTask<T, T_NODE, K> task = this; while (true) { if (task.node.getChildCount() == 0) { task.copyNodeToArray(); task.propagateCompletion(); return; } else { task.setPendingCount(task.node.getChildCount() - 1); int size = 0; int i = 0; for (;i < task.node.getChildCount() - 1; i++) { K leftTask = task.makeChild(i, task.offset + size); size += leftTask.node.count(); leftTask.fork(); } task = task.makeChild(i, task.offset + size); } } }