github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/interlock/aggfuncs/func_sum.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/types" 21 "github.com/whtcorpsinc/milevadb/soliton/chunk" 22 "github.com/whtcorpsinc/milevadb/soliton/replog" 23 "github.com/whtcorpsinc/milevadb/soliton/set" 24 ) 25 26 const ( 27 // DefPartialResult4SumFloat64Size is the size of partialResult4SumFloat64 28 DefPartialResult4SumFloat64Size = int64(unsafe.Sizeof(partialResult4SumFloat64{})) 29 // DefPartialResult4SumDecimalSize is the size of partialResult4SumDecimal 30 DefPartialResult4SumDecimalSize = int64(unsafe.Sizeof(partialResult4SumDecimal{})) 31 // DefPartialResult4SumDistinctFloat64Size is the size of partialResult4SumDistinctFloat64 32 DefPartialResult4SumDistinctFloat64Size = int64(unsafe.Sizeof(partialResult4SumDistinctFloat64{})) 33 // DefPartialResult4SumDistinctDecimalSize is the size of partialResult4SumDistinctDecimal 34 DefPartialResult4SumDistinctDecimalSize = int64(unsafe.Sizeof(partialResult4SumDistinctDecimal{})) 35 ) 36 37 type partialResult4SumFloat64 struct { 38 val float64 39 notNullEventCount int64 40 } 41 42 type partialResult4SumDecimal struct { 43 val types.MyDecimal 44 notNullEventCount int64 45 } 46 47 type partialResult4SumDistinctFloat64 struct { 48 val float64 49 isNull bool 50 valSet set.Float64Set 51 } 52 53 type partialResult4SumDistinctDecimal struct { 54 val types.MyDecimal 55 isNull bool 56 valSet set.StringSet 57 } 58 59 type baseSumAggFunc struct { 60 baseAggFunc 61 } 62 63 type baseSum4Float64 struct { 64 baseSumAggFunc 65 } 66 67 func (e *baseSum4Float64) AllocPartialResult() (pr PartialResult, memDelta int64) { 68 p := new(partialResult4SumFloat64) 69 return PartialResult(p), DefPartialResult4SumFloat64Size 70 } 71 72 func (e *baseSum4Float64) ResetPartialResult(pr PartialResult) { 73 p := (*partialResult4SumFloat64)(pr) 74 p.val = 0 75 p.notNullEventCount = 0 76 } 77 78 func (e *baseSum4Float64) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error { 79 p := (*partialResult4SumFloat64)(pr) 80 if p.notNullEventCount == 0 { 81 chk.AppendNull(e.ordinal) 82 return nil 83 } 84 chk.AppendFloat64(e.ordinal, p.val) 85 return nil 86 } 87 88 func (e *baseSum4Float64) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 89 p := (*partialResult4SumFloat64)(pr) 90 for _, event := range rowsInGroup { 91 input, isNull, err := e.args[0].EvalReal(sctx, event) 92 if err != nil { 93 return 0, err 94 } 95 if isNull { 96 continue 97 } 98 p.val += input 99 p.notNullEventCount++ 100 } 101 return 0, nil 102 } 103 104 func (e *baseSum4Float64) MergePartialResult(sctx stochastikctx.Context, src, dst PartialResult) (memDelta int64, err error) { 105 p1, p2 := (*partialResult4SumFloat64)(src), (*partialResult4SumFloat64)(dst) 106 if p1.notNullEventCount == 0 { 107 return 0, nil 108 } 109 p2.val += p1.val 110 p2.notNullEventCount += p1.notNullEventCount 111 return 0, nil 112 } 113 114 type sum4Float64 struct { 115 baseSum4Float64 116 } 117 118 func (e *sum4Float64) Slide(sctx stochastikctx.Context, rows []chunk.Event, lastStart, lastEnd uint64, shiftStart, shiftEnd uint64, pr PartialResult) error { 119 p := (*partialResult4SumFloat64)(pr) 120 for i := uint64(0); i < shiftEnd; i++ { 121 input, isNull, err := e.args[0].EvalReal(sctx, rows[lastEnd+i]) 122 if err != nil { 123 return err 124 } 125 if isNull { 126 continue 127 } 128 p.val += input 129 p.notNullEventCount++ 130 } 131 for i := uint64(0); i < shiftStart; i++ { 132 input, isNull, err := e.args[0].EvalReal(sctx, rows[lastStart+i]) 133 if err != nil { 134 return err 135 } 136 if isNull { 137 continue 138 } 139 p.val -= input 140 p.notNullEventCount-- 141 } 142 return nil 143 } 144 145 type sum4Float64HighPrecision struct { 146 baseSum4Float64 147 } 148 149 type sum4Decimal struct { 150 baseSumAggFunc 151 } 152 153 func (e *sum4Decimal) AllocPartialResult() (pr PartialResult, memDelta int64) { 154 p := new(partialResult4SumDecimal) 155 return PartialResult(p), DefPartialResult4SumDecimalSize 156 } 157 158 func (e *sum4Decimal) ResetPartialResult(pr PartialResult) { 159 p := (*partialResult4SumDecimal)(pr) 160 p.notNullEventCount = 0 161 } 162 163 func (e *sum4Decimal) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error { 164 p := (*partialResult4SumDecimal)(pr) 165 if p.notNullEventCount == 0 { 166 chk.AppendNull(e.ordinal) 167 return nil 168 } 169 chk.AppendMyDecimal(e.ordinal, &p.val) 170 return nil 171 } 172 173 func (e *sum4Decimal) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 174 p := (*partialResult4SumDecimal)(pr) 175 for _, event := range rowsInGroup { 176 input, isNull, err := e.args[0].EvalDecimal(sctx, event) 177 if err != nil { 178 return 0, err 179 } 180 if isNull { 181 continue 182 } 183 if p.notNullEventCount == 0 { 184 p.val = *input 185 p.notNullEventCount = 1 186 continue 187 } 188 189 newSum := new(types.MyDecimal) 190 err = types.DecimalAdd(&p.val, input, newSum) 191 if err != nil { 192 return 0, err 193 } 194 p.val = *newSum 195 p.notNullEventCount++ 196 } 197 return 0, nil 198 } 199 200 func (e *sum4Decimal) Slide(sctx stochastikctx.Context, rows []chunk.Event, lastStart, lastEnd uint64, shiftStart, shiftEnd uint64, pr PartialResult) error { 201 p := (*partialResult4SumDecimal)(pr) 202 for i := uint64(0); i < shiftEnd; i++ { 203 input, isNull, err := e.args[0].EvalDecimal(sctx, rows[lastEnd+i]) 204 if err != nil { 205 return err 206 } 207 if isNull { 208 continue 209 } 210 if p.notNullEventCount == 0 { 211 p.val = *input 212 p.notNullEventCount = 1 213 continue 214 } 215 newSum := new(types.MyDecimal) 216 err = types.DecimalAdd(&p.val, input, newSum) 217 if err != nil { 218 return err 219 } 220 p.val = *newSum 221 p.notNullEventCount++ 222 } 223 for i := uint64(0); i < shiftStart; i++ { 224 input, isNull, err := e.args[0].EvalDecimal(sctx, rows[lastStart+i]) 225 if err != nil { 226 return err 227 } 228 if isNull { 229 continue 230 } 231 newSum := new(types.MyDecimal) 232 err = types.DecimalSub(&p.val, input, newSum) 233 if err != nil { 234 return err 235 } 236 p.val = *newSum 237 p.notNullEventCount-- 238 } 239 return nil 240 } 241 242 func (e *sum4Decimal) MergePartialResult(sctx stochastikctx.Context, src, dst PartialResult) (memDelta int64, err error) { 243 p1, p2 := (*partialResult4SumDecimal)(src), (*partialResult4SumDecimal)(dst) 244 if p1.notNullEventCount == 0 { 245 return 0, nil 246 } 247 newSum := new(types.MyDecimal) 248 err = types.DecimalAdd(&p1.val, &p2.val, newSum) 249 if err != nil { 250 return 0, err 251 } 252 p2.val = *newSum 253 p2.notNullEventCount += p1.notNullEventCount 254 return 0, nil 255 } 256 257 type sum4DistinctFloat64 struct { 258 baseSumAggFunc 259 } 260 261 func (e *sum4DistinctFloat64) AllocPartialResult() (pr PartialResult, memDelta int64) { 262 p := new(partialResult4SumDistinctFloat64) 263 p.isNull = true 264 p.valSet = set.NewFloat64Set() 265 return PartialResult(p), DefPartialResult4SumDistinctFloat64Size 266 } 267 268 func (e *sum4DistinctFloat64) ResetPartialResult(pr PartialResult) { 269 p := (*partialResult4SumDistinctFloat64)(pr) 270 p.isNull = true 271 p.valSet = set.NewFloat64Set() 272 } 273 274 func (e *sum4DistinctFloat64) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 275 p := (*partialResult4SumDistinctFloat64)(pr) 276 for _, event := range rowsInGroup { 277 input, isNull, err := e.args[0].EvalReal(sctx, event) 278 if err != nil { 279 return memDelta, err 280 } 281 if isNull || p.valSet.Exist(input) { 282 continue 283 } 284 p.valSet.Insert(input) 285 memDelta += DefFloat64Size 286 if p.isNull { 287 p.val = input 288 p.isNull = false 289 continue 290 } 291 p.val += input 292 } 293 return memDelta, nil 294 } 295 296 func (e *sum4DistinctFloat64) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error { 297 p := (*partialResult4SumDistinctFloat64)(pr) 298 if p.isNull { 299 chk.AppendNull(e.ordinal) 300 return nil 301 } 302 chk.AppendFloat64(e.ordinal, p.val) 303 return nil 304 } 305 306 type sum4DistinctDecimal struct { 307 baseSumAggFunc 308 } 309 310 func (e *sum4DistinctDecimal) AllocPartialResult() (pr PartialResult, memDelta int64) { 311 p := new(partialResult4SumDistinctDecimal) 312 p.isNull = true 313 p.valSet = set.NewStringSet() 314 return PartialResult(p), DefPartialResult4SumDistinctDecimalSize 315 } 316 317 func (e *sum4DistinctDecimal) ResetPartialResult(pr PartialResult) { 318 p := (*partialResult4SumDistinctDecimal)(pr) 319 p.isNull = true 320 p.valSet = set.NewStringSet() 321 } 322 323 func (e *sum4DistinctDecimal) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 324 p := (*partialResult4SumDistinctDecimal)(pr) 325 for _, event := range rowsInGroup { 326 input, isNull, err := e.args[0].EvalDecimal(sctx, event) 327 if err != nil { 328 return memDelta, err 329 } 330 if isNull { 331 continue 332 } 333 hash, err := input.ToHashKey() 334 if err != nil { 335 return memDelta, err 336 } 337 decStr := string(replog.String(hash)) 338 if p.valSet.Exist(decStr) { 339 continue 340 } 341 p.valSet.Insert(decStr) 342 memDelta += int64(len(decStr)) 343 if p.isNull { 344 p.val = *input 345 p.isNull = false 346 continue 347 } 348 newSum := new(types.MyDecimal) 349 if err = types.DecimalAdd(&p.val, input, newSum); err != nil { 350 return memDelta, err 351 } 352 p.val = *newSum 353 } 354 return memDelta, nil 355 } 356 357 func (e *sum4DistinctDecimal) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error { 358 p := (*partialResult4SumDistinctDecimal)(pr) 359 if p.isNull { 360 chk.AppendNull(e.ordinal) 361 return nil 362 } 363 chk.AppendMyDecimal(e.ordinal, &p.val) 364 return nil 365 }