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  }