github.com/searKing/golang/go@v1.2.74/container/stream/op/reduce/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 reduce
     6  
     7  import (
     8  	"context"
     9  
    10  	"github.com/searKing/golang/go/container/stream/op/terminal"
    11  	"github.com/searKing/golang/go/util/function/binary"
    12  	"github.com/searKing/golang/go/util/spliterator"
    13  )
    14  
    15  type ReduceTask struct {
    16  	terminal.TODOTask
    17  
    18  	op      ReduceOp
    19  	combine binary.BiFunction
    20  }
    21  
    22  func NewReduceTask(op ReduceOp, spliterator spliterator.Spliterator) *ReduceTask {
    23  	reducer := &ReduceTask{
    24  		op: op,
    25  	}
    26  	reducer.WithSpliterator(spliterator)
    27  	reducer.SetDerived(reducer)
    28  	return reducer
    29  }
    30  
    31  func NewReduceTaskFromParent(parent *ReduceTask, spliterator spliterator.Spliterator) *ReduceTask {
    32  	reducer := &ReduceTask{
    33  		op: parent.op,
    34  	}
    35  	reducer.WithParent(parent, spliterator)
    36  	reducer.SetDerived(reducer)
    37  	return reducer
    38  }
    39  
    40  func (t *ReduceTask) MakeChild(spliterator spliterator.Spliterator) terminal.Task {
    41  	return NewReduceTaskFromParent(t, spliterator)
    42  }
    43  
    44  func (t *ReduceTask) DoLeaf(ctx context.Context) terminal.Sink {
    45  	return terminal.WrapAndCopyInto(ctx, t.op.MakeSink(), t.GetSpliterator())
    46  }
    47  
    48  func (t *ReduceTask) OnCompletion(caller terminal.Task) {
    49  	task := t.GetDerivedElse(t).(terminal.Task)
    50  	if !task.IsLeaf() {
    51  		leftResult := task.LeftChild().GetLocalResult()
    52  		rightResult := task.RightChild().GetLocalResult()
    53  		sink := t.op.MakeSink()
    54  		sink.Begin(-1)
    55  		sink.Combine(leftResult)
    56  		sink.Combine(rightResult)
    57  		sink.End()
    58  		task.SetLocalResult(sink)
    59  	}
    60  	// GC spliterator, left and right child
    61  	t.TODOTask.OnCompletion(caller)
    62  }