github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/colexec/mergelimit/limit.go (about) 1 // Copyright 2021 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package mergelimit 16 17 import ( 18 "bytes" 19 "fmt" 20 21 "github.com/matrixorigin/matrixone/pkg/container/batch" 22 "github.com/matrixorigin/matrixone/pkg/vm" 23 "github.com/matrixorigin/matrixone/pkg/vm/process" 24 ) 25 26 const argName = "merge_limit" 27 28 func (arg *Argument) String(buf *bytes.Buffer) { 29 buf.WriteString(argName) 30 ap := arg 31 buf.WriteString(fmt.Sprintf("mergeLimit(%d)", ap.Limit)) 32 } 33 34 func (arg *Argument) Prepare(proc *process.Process) error { 35 ap := arg 36 ap.ctr = new(container) 37 ap.ctr.seen = 0 38 ap.ctr.InitReceiver(proc, true) 39 return nil 40 } 41 42 func (arg *Argument) Call(proc *process.Process) (vm.CallResult, error) { 43 if err, isCancel := vm.CancelCheck(proc); isCancel { 44 return vm.CancelResult, err 45 } 46 47 anal := proc.GetAnalyze(arg.GetIdx(), arg.GetParallelIdx(), arg.GetParallelMajor()) 48 anal.Start() 49 defer anal.Stop() 50 51 result := vm.NewCallResult() 52 var end bool 53 var err error 54 if arg.buf != nil { 55 proc.PutBatch(arg.buf) 56 arg.buf = nil 57 } 58 59 for { 60 arg.buf, end, err = arg.ctr.ReceiveFromAllRegs(anal) 61 if err != nil { 62 result.Status = vm.ExecStop 63 return result, nil 64 } 65 if end { 66 result.Batch = nil 67 result.Status = vm.ExecStop 68 return result, nil 69 } 70 if arg.buf.Last() { 71 result.Batch = arg.buf 72 return result, nil 73 } 74 75 anal.Input(arg.buf, arg.GetIsFirst()) 76 if arg.ctr.seen >= arg.Limit { 77 proc.PutBatch(arg.buf) 78 continue 79 } 80 newSeen := arg.ctr.seen + uint64(arg.buf.RowCount()) 81 if newSeen < arg.Limit { 82 arg.ctr.seen = newSeen 83 anal.Output(arg.buf, arg.GetIsLast()) 84 result.Batch = arg.buf 85 return result, nil 86 } else { 87 num := int(newSeen - arg.Limit) 88 batch.SetLength(arg.buf, arg.buf.RowCount()-num) 89 arg.ctr.seen = newSeen 90 anal.Output(arg.buf, arg.GetIsLast()) 91 result.Batch = arg.buf 92 return result, nil 93 } 94 } 95 }