示例#1
0
 protected internal ForEachOrderedTask(PipelineHelper <T> helper, Spliterator <S> spliterator, Sink <T> action) : base(null)
 {
     this.Helper      = helper;
     this.Spliterator = spliterator;
     this.TargetSize  = AbstractTask.SuggestTargetSize(spliterator.EstimateSize());
     // Size map to avoid concurrent re-sizes
     this.CompletionMap   = new ConcurrentDictionary <>(System.Math.Max(16, AbstractTask.LEAF_TARGET << 1));
     this.Action          = action;
     this.LeftPredecessor = null;
 }
示例#2
0
            // Similar to AbstractTask but doesn't need to track child tasks
            public void Compute()
            {
                Spliterator <S> rightSplit = Spliterator, leftSplit;
                long            sizeEstimate = rightSplit.EstimateSize(), sizeThreshold;

                if ((sizeThreshold = TargetSize) == 0L)
                {
                    TargetSize = sizeThreshold = AbstractTask.SuggestTargetSize(sizeEstimate);
                }
                bool               isShortCircuit = StreamOpFlag.SHORT_CIRCUIT.isKnown(Helper.StreamAndOpFlags);
                bool               forkRight      = false;
                Sink <S>           taskSink       = Sink;
                ForEachTask <S, T> task           = this;

                while (!isShortCircuit || !taskSink.cancellationRequested())
                {
                    if (sizeEstimate <= sizeThreshold || (leftSplit = rightSplit.TrySplit()) == null)
                    {
                        task.Helper.CopyInto(taskSink, rightSplit);
                        break;
                    }
                    ForEachTask <S, T> leftTask = new ForEachTask <S, T>(task, leftSplit);
                    task.AddToPendingCount(1);
                    ForEachTask <S, T> taskToFork;
                    if (forkRight)
                    {
                        forkRight  = false;
                        rightSplit = leftSplit;
                        taskToFork = task;
                        task       = leftTask;
                    }
                    else
                    {
                        forkRight  = true;
                        taskToFork = leftTask;
                    }
                    taskToFork.Fork();
                    sizeEstimate = rightSplit.EstimateSize();
                }
                task.Spliterator = null;
                task.PropagateCompletion();
            }