github.com/searKing/golang/go@v1.2.74/container/stream/op/reduce/sink.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 "github.com/searKing/golang/go/container/stream/op/terminal" 9 "github.com/searKing/golang/go/util/function/binary" 10 "github.com/searKing/golang/go/util/object" 11 "github.com/searKing/golang/go/util/optional" 12 ) 13 14 /** 15 * A type of {@code TerminalSink} that implements an associative reducing 16 * operation on elements of type {@code T} and producing a result of type 17 * {@code R}. 18 * 19 * @param <T> the type of input element to the combining operation 20 * @param <R> the result type 21 * @param <K> the type of the {@code AccumulatingSink}. 22 */ 23 type AccumulatingSink interface { 24 Combine(other AccumulatingSink) 25 } 26 27 type ReducingSink struct { 28 terminal.TODOSink 29 seed optional.Optional 30 state optional.Optional 31 32 reducer binary.BiFunction 33 combiner binary.BiFunction 34 } 35 36 func NewReducingSink(seed optional.Optional, reducer binary.BiFunction, combiner binary.BiFunction) *ReducingSink { 37 object.RequireNonNull(reducer) 38 sink := &ReducingSink{ 39 seed: seed, 40 reducer: reducer, 41 combiner: combiner, 42 } 43 sink.SetDerived(sink) 44 return sink 45 } 46 47 func (sink *ReducingSink) Begin(size int) { 48 sink.state = sink.seed 49 } 50 51 func (sink *ReducingSink) Accept(t interface{}) { 52 if !sink.state.IsPresent() { 53 sink.state = optional.Of(t) 54 return 55 } 56 sink.state = optional.Of(sink.reducer.Apply(sink.state.Get(), t)) 57 return 58 } 59 60 func (sink *ReducingSink) Combine(other terminal.Sink) { 61 otherOptional := other.Get() 62 if !otherOptional.IsPresent() { 63 return 64 } 65 66 if !sink.state.IsPresent() { 67 sink.Accept(otherOptional.Get()) 68 return 69 } 70 if sink.combiner != nil { 71 sink.state = optional.Of(sink.combiner.Apply(sink.state.Get(), otherOptional.Get())) 72 return 73 } 74 sink.Accept(otherOptional.Get()) 75 return 76 } 77 78 func (sink *ReducingSink) Get() optional.Optional { 79 return sink.state 80 }