github.com/searKing/golang/go@v1.2.74/container/stream/op/while/drop_while_task.go (about)

     1  // Copyright 2020 The searKing Author. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package while
     6  
     7  import (
     8  	"context"
     9  
    10  	"github.com/searKing/golang/go/container/stream/op/terminal"
    11  	"github.com/searKing/golang/go/util/spliterator"
    12  )
    13  
    14  type DropWhileTask struct {
    15  	terminal.TODOShortCircuitTask
    16  
    17  	op DropWhileOp
    18  
    19  	isOrdered    bool
    20  	thisNodeSize int
    21  	// The index from which elements of the node should be taken
    22  	// i.e. the node should be truncated from [takeIndex, thisNodeSize)
    23  	// Equivalent to the count of dropped elements
    24  	index int
    25  }
    26  
    27  /**
    28   * Constructor for root tasks.
    29   *
    30   * @param helper the {@code PipelineHelper} describing the stream pipeline
    31   *               up to this operation
    32   * @param spliterator the {@code Spliterator} describing the source for this
    33   *                    pipeline
    34   */
    35  func (task *DropWhileTask) WithSpliterator(op DropWhileOp, spliterator spliterator.Spliterator) *DropWhileTask {
    36  	task.TODOTask.WithSpliterator(spliterator)
    37  	task.op = op
    38  	//task.isOrdered = op
    39  	task.SetDerived(task)
    40  	return task
    41  }
    42  
    43  /**
    44   * Constructor for non-root nodes.
    45   *
    46   * @param parent parent task in the computation tree
    47   * @param spliterator the {@code Spliterator} for the portion of the
    48   *                    computation tree described by this task
    49   */
    50  func (task *DropWhileTask) WithParent(parent *DropWhileTask, spliterator spliterator.Spliterator) *DropWhileTask {
    51  	task.TODOTask.WithParent(parent, spliterator)
    52  	task.op = parent.op
    53  	task.isOrdered = parent.isOrdered
    54  	task.SetDerived(task)
    55  	return task
    56  }
    57  
    58  func (task *DropWhileTask) MakeChild(spliterator spliterator.Spliterator) terminal.Task {
    59  	child := &DropWhileTask{}
    60  	return child.WithParent(task, spliterator)
    61  }
    62  
    63  func (task *DropWhileTask) foundResult(answer terminal.Sink) {
    64  	if task.IsLeftmostNode() {
    65  		task.ShortCircuit(answer)
    66  		return
    67  	}
    68  	task.CancelLaterNodes()
    69  }
    70  
    71  func (task *DropWhileTask) DoLeaf(ctx context.Context) terminal.Sink {
    72  	result := terminal.WrapAndCopyInto(ctx, task.op.MakeSink(), task.GetSpliterator())
    73  	if !task.isOrdered {
    74  		if result != nil && result.Get().IsPresent() {
    75  			task.ShortCircuit(result)
    76  		}
    77  		return nil
    78  	}
    79  	if result != nil && result.Get().IsPresent() {
    80  		task.foundResult(result)
    81  		return result
    82  	}
    83  	return nil
    84  }
    85  
    86  func (task *DropWhileTask) OnCompletion(caller terminal.Task) {
    87  	if task.isOrdered {
    88  		child := task.LeftChild()
    89  		var p terminal.Task
    90  		for child != p {
    91  			result := child.GetLocalResult()
    92  			if result != nil && result.Get().IsPresent() {
    93  				task.SetLocalResult(result)
    94  				task.foundResult(result)
    95  				break
    96  			}
    97  
    98  			p = child
    99  			child = task.RightChild()
   100  		}
   101  	}
   102  	// GC spliterator, left and right child
   103  	task.TODOTask.OnCompletion(caller)
   104  }