github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/interlock/aggfuncs/func_ntile.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 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 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package aggfuncs 15 16 import ( 17 "unsafe" 18 19 "github.com/whtcorpsinc/milevadb/stochastikctx" 20 "github.com/whtcorpsinc/milevadb/soliton/chunk" 21 ) 22 23 const ( 24 // DefPartialResult4Ntile is the size of partialResult4Ntile 25 DefPartialResult4Ntile = int64(unsafe.Sizeof(partialResult4Ntile{})) 26 ) 27 28 // ntile divides the partition into n ranked groups and returns the group number a event belongs to. 29 // e.g. We have 11 rows and n = 3. They will be divided into 3 groups. 30 // First 4 rows belongs to group 1. Following 4 rows belongs to group 2. The last 3 rows belongs to group 3. 31 type ntile struct { 32 n uint64 33 baseAggFunc 34 } 35 36 type partialResult4Ntile struct { 37 curIdx uint64 38 curGroupIdx uint64 39 remainder uint64 40 quotient uint64 41 numEvents uint64 42 } 43 44 func (n *ntile) AllocPartialResult() (pr PartialResult, memDelta int64) { 45 return PartialResult(&partialResult4Ntile{curGroupIdx: 1}), DefPartialResult4Ntile 46 } 47 48 func (n *ntile) ResetPartialResult(pr PartialResult) { 49 p := (*partialResult4Ntile)(pr) 50 p.curIdx = 0 51 p.curGroupIdx = 1 52 p.numEvents = 0 53 } 54 55 func (n *ntile) UFIDelatePartialResult(_ stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 56 p := (*partialResult4Ntile)(pr) 57 p.numEvents += uint64(len(rowsInGroup)) 58 // UFIDelate the quotient and remainder. 59 if n.n != 0 { 60 p.quotient = p.numEvents / n.n 61 p.remainder = p.numEvents % n.n 62 } 63 return 0, nil 64 } 65 66 func (n *ntile) AppendFinalResult2Chunk(_ stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error { 67 p := (*partialResult4Ntile)(pr) 68 69 // If the divisor is 0, the arg of NTILE would be NULL. So we just return NULL. 70 if n.n == 0 { 71 chk.AppendNull(n.ordinal) 72 return nil 73 } 74 75 chk.AppendUint64(n.ordinal, p.curGroupIdx) 76 77 p.curIdx++ 78 curMaxIdx := p.quotient 79 if p.curGroupIdx <= p.remainder { 80 curMaxIdx++ 81 } 82 if p.curIdx == curMaxIdx { 83 p.curIdx = 0 84 p.curGroupIdx++ 85 } 86 return nil 87 }