github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/bench_test.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 memex
    15  
    16  // This file contains benchmarks of our memex evaluation.
    17  
    18  import (
    19  	"flag"
    20  	"fmt"
    21  	"math/rand"
    22  	"net"
    23  	"reflect"
    24  	"strconv"
    25  	"strings"
    26  	"testing"
    27  	"time"
    28  
    29  	. "github.com/whtcorpsinc/check"
    30  	"github.com/whtcorpsinc/BerolinaSQL/ast"
    31  	"github.com/whtcorpsinc/BerolinaSQL/auth"
    32  	"github.com/whtcorpsinc/BerolinaSQL/charset"
    33  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    34  	"github.com/whtcorpsinc/BerolinaSQL/terror"
    35  	"github.com/whtcorpsinc/milevadb/stochastikctx"
    36  	"github.com/whtcorpsinc/milevadb/stochastikctx/variable"
    37  	"github.com/whtcorpsinc/milevadb/types"
    38  	"github.com/whtcorpsinc/milevadb/types/json"
    39  	"github.com/whtcorpsinc/milevadb/soliton/chunk"
    40  	"github.com/whtcorpsinc/milevadb/soliton/math"
    41  	"github.com/whtcorpsinc/milevadb/soliton/mock"
    42  )
    43  
    44  type benchHelper struct {
    45  	ctx   stochastikctx.Context
    46  	exprs []Expression
    47  
    48  	inputTypes  []*types.FieldType
    49  	outputTypes []*types.FieldType
    50  	inputChunk  *chunk.Chunk
    51  	outputChunk *chunk.Chunk
    52  }
    53  
    54  func (h *benchHelper) init() {
    55  	numEvents := 4 * 1024
    56  
    57  	h.ctx = mock.NewContext()
    58  	h.ctx.GetStochastikVars().StmtCtx.TimeZone = time.Local
    59  	h.ctx.GetStochastikVars().InitChunkSize = 32
    60  	h.ctx.GetStochastikVars().MaxChunkSize = numEvents
    61  
    62  	h.inputTypes = make([]*types.FieldType, 0, 10)
    63  	h.inputTypes = append(h.inputTypes, &types.FieldType{
    64  		Tp:      allegrosql.TypeLonglong,
    65  		Flen:    allegrosql.MaxIntWidth,
    66  		Decimal: 0,
    67  		Flag:    allegrosql.BinaryFlag,
    68  		Charset: charset.CharsetBin,
    69  		DefCauslate: charset.DefCauslationBin,
    70  	})
    71  	h.inputTypes = append(h.inputTypes, &types.FieldType{
    72  		Tp:      allegrosql.TypeDouble,
    73  		Flen:    allegrosql.MaxRealWidth,
    74  		Decimal: types.UnspecifiedLength,
    75  		Flag:    allegrosql.BinaryFlag,
    76  		Charset: charset.CharsetBin,
    77  		DefCauslate: charset.DefCauslationBin,
    78  	})
    79  	h.inputTypes = append(h.inputTypes, &types.FieldType{
    80  		Tp:      allegrosql.TypeNewDecimal,
    81  		Flen:    11,
    82  		Decimal: 0,
    83  		Flag:    allegrosql.BinaryFlag,
    84  		Charset: charset.CharsetBin,
    85  		DefCauslate: charset.DefCauslationBin,
    86  	})
    87  
    88  	// Use 20 string defCausumns to show the cache performance.
    89  	for i := 0; i < 20; i++ {
    90  		h.inputTypes = append(h.inputTypes, &types.FieldType{
    91  			Tp:      allegrosql.TypeVarString,
    92  			Flen:    0,
    93  			Decimal: types.UnspecifiedLength,
    94  			Charset: charset.CharsetUTF8,
    95  			DefCauslate: charset.DefCauslationUTF8,
    96  		})
    97  	}
    98  
    99  	h.inputChunk = chunk.NewChunkWithCapacity(h.inputTypes, numEvents)
   100  	for rowIdx := 0; rowIdx < numEvents; rowIdx++ {
   101  		h.inputChunk.AppendInt64(0, 4)
   102  		h.inputChunk.AppendFloat64(1, 2.019)
   103  		h.inputChunk.AppendMyDecimal(2, types.NewDecFromFloatForTest(5.9101))
   104  		for i := 0; i < 20; i++ {
   105  			h.inputChunk.AppendString(3+i, `abcdefughasfjsaljal1321798273528791!&(*#&@&^%&%^&!)sadfashqwer`)
   106  		}
   107  	}
   108  
   109  	defcaus := make([]*DeferredCauset, 0, len(h.inputTypes))
   110  	for i := 0; i < len(h.inputTypes); i++ {
   111  		defcaus = append(defcaus, &DeferredCauset{
   112  			UniqueID: int64(i),
   113  			RetType:  h.inputTypes[i],
   114  			Index:    i,
   115  		})
   116  	}
   117  
   118  	h.exprs = make([]Expression, 0, 10)
   119  	if expr, err := NewFunction(h.ctx, ast.Substr, h.inputTypes[3], []Expression{defcaus[3], defcaus[2]}...); err != nil {
   120  		panic("create SUBSTR function failed.")
   121  	} else {
   122  		h.exprs = append(h.exprs, expr)
   123  	}
   124  
   125  	if expr, err := NewFunction(h.ctx, ast.Plus, h.inputTypes[0], []Expression{defcaus[1], defcaus[2]}...); err != nil {
   126  		panic("create PLUS function failed.")
   127  	} else {
   128  		h.exprs = append(h.exprs, expr)
   129  	}
   130  
   131  	if expr, err := NewFunction(h.ctx, ast.GT, h.inputTypes[2], []Expression{defcaus[11], defcaus[8]}...); err != nil {
   132  		panic("create GT function failed.")
   133  	} else {
   134  		h.exprs = append(h.exprs, expr)
   135  	}
   136  
   137  	if expr, err := NewFunction(h.ctx, ast.GT, h.inputTypes[2], []Expression{defcaus[19], defcaus[10]}...); err != nil {
   138  		panic("create GT function failed.")
   139  	} else {
   140  		h.exprs = append(h.exprs, expr)
   141  	}
   142  
   143  	if expr, err := NewFunction(h.ctx, ast.GT, h.inputTypes[2], []Expression{defcaus[17], defcaus[4]}...); err != nil {
   144  		panic("create GT function failed.")
   145  	} else {
   146  		h.exprs = append(h.exprs, expr)
   147  	}
   148  
   149  	if expr, err := NewFunction(h.ctx, ast.GT, h.inputTypes[2], []Expression{defcaus[18], defcaus[5]}...); err != nil {
   150  		panic("create GT function failed.")
   151  	} else {
   152  		h.exprs = append(h.exprs, expr)
   153  	}
   154  
   155  	if expr, err := NewFunction(h.ctx, ast.LE, h.inputTypes[2], []Expression{defcaus[19], defcaus[4]}...); err != nil {
   156  		panic("create LE function failed.")
   157  	} else {
   158  		h.exprs = append(h.exprs, expr)
   159  	}
   160  
   161  	if expr, err := NewFunction(h.ctx, ast.EQ, h.inputTypes[2], []Expression{defcaus[20], defcaus[3]}...); err != nil {
   162  		panic("create EQ function failed.")
   163  	} else {
   164  		h.exprs = append(h.exprs, expr)
   165  	}
   166  	h.exprs = append(h.exprs, defcaus[2])
   167  	h.exprs = append(h.exprs, defcaus[2])
   168  
   169  	h.outputTypes = make([]*types.FieldType, 0, len(h.exprs))
   170  	for i := 0; i < len(h.exprs); i++ {
   171  		h.outputTypes = append(h.outputTypes, h.exprs[i].GetType())
   172  	}
   173  
   174  	h.outputChunk = chunk.NewChunkWithCapacity(h.outputTypes, numEvents)
   175  }
   176  
   177  func BenchmarkVectorizedInterDircute(b *testing.B) {
   178  	h := benchHelper{}
   179  	h.init()
   180  	inputIter := chunk.NewIterator4Chunk(h.inputChunk)
   181  
   182  	b.ResetTimer()
   183  	for i := 0; i < b.N; i++ {
   184  		h.outputChunk.Reset()
   185  		if err := VectorizedInterDircute(h.ctx, h.exprs, inputIter, h.outputChunk); err != nil {
   186  			panic("errors happened during \"VectorizedInterDircute\"")
   187  		}
   188  	}
   189  }
   190  
   191  func BenchmarkScalarFunctionClone(b *testing.B) {
   192  	defCaus := &DeferredCauset{RetType: types.NewFieldType(allegrosql.TypeLonglong)}
   193  	con1 := NewOne()
   194  	con2 := NewZero()
   195  	add := NewFunctionInternal(mock.NewContext(), ast.Plus, types.NewFieldType(allegrosql.TypeLonglong), defCaus, con1)
   196  	sub := NewFunctionInternal(mock.NewContext(), ast.Plus, types.NewFieldType(allegrosql.TypeLonglong), add, con2)
   197  	b.ResetTimer()
   198  	for i := 0; i < b.N; i++ {
   199  		sub.Clone()
   200  	}
   201  	b.ReportAllocs()
   202  }
   203  
   204  func getRandomTime(r *rand.Rand) types.CoreTime {
   205  	return types.FromDate(r.Intn(2200), r.Intn(10)+1, r.Intn(20)+1,
   206  		r.Intn(12), r.Intn(60), r.Intn(60), r.Intn(1000000))
   207  
   208  }
   209  
   210  // dataGenerator is used to generate data for test.
   211  type dataGenerator interface {
   212  	gen() interface{}
   213  }
   214  
   215  type defaultRandGen struct {
   216  	*rand.Rand
   217  }
   218  
   219  func newDefaultRandGen() *defaultRandGen {
   220  	return &defaultRandGen{rand.New(rand.NewSource(int64(rand.Uint64())))}
   221  }
   222  
   223  type defaultGener struct {
   224  	nullRation float64
   225  	eType      types.EvalType
   226  	randGen    *defaultRandGen
   227  }
   228  
   229  func newDefaultGener(nullRation float64, eType types.EvalType) *defaultGener {
   230  	return &defaultGener{
   231  		nullRation: nullRation,
   232  		eType:      eType,
   233  		randGen:    newDefaultRandGen(),
   234  	}
   235  }
   236  
   237  func (g *defaultGener) gen() interface{} {
   238  	if g.randGen.Float64() < g.nullRation {
   239  		return nil
   240  	}
   241  	switch g.eType {
   242  	case types.ETInt:
   243  		if g.randGen.Float64() < 0.5 {
   244  			return -g.randGen.Int63()
   245  		}
   246  		return g.randGen.Int63()
   247  	case types.ETReal:
   248  		if g.randGen.Float64() < 0.5 {
   249  			return -g.randGen.Float64() * 1000000
   250  		}
   251  		return g.randGen.Float64() * 1000000
   252  	case types.ETDecimal:
   253  		d := new(types.MyDecimal)
   254  		var f float64
   255  		if g.randGen.Float64() < 0.5 {
   256  			f = g.randGen.Float64() * 100000
   257  		} else {
   258  			f = -g.randGen.Float64() * 100000
   259  		}
   260  		if err := d.FromFloat64(f); err != nil {
   261  			panic(err)
   262  		}
   263  		return d
   264  	case types.ETDatetime, types.ETTimestamp:
   265  		gt := getRandomTime(g.randGen.Rand)
   266  		t := types.NewTime(gt, convertETType(g.eType), 0)
   267  		return t
   268  	case types.ETDuration:
   269  		d := types.Duration{
   270  			// use rand.Int32() to make it not overflow when AddDuration
   271  			Duration: time.Duration(g.randGen.Int31()),
   272  		}
   273  		return d
   274  	case types.ETJson:
   275  		j := new(json.BinaryJSON)
   276  		if err := j.UnmarshalJSON([]byte(fmt.Sprintf(`{"key":%v}`, g.randGen.Int()))); err != nil {
   277  			panic(err)
   278  		}
   279  		return *j
   280  	case types.ETString:
   281  		return randString(g.randGen.Rand)
   282  	}
   283  	return nil
   284  }
   285  
   286  // charInt64Gener is used to generate int which is equal to char's ascii
   287  type charInt64Gener struct{}
   288  
   289  func (g *charInt64Gener) gen() interface{} {
   290  	rand := time.Now().Nanosecond()
   291  	rand = rand % 1024
   292  	return int64(rand)
   293  }
   294  
   295  // charsetStringGener is used to generate "ascii" or "gbk"
   296  type charsetStringGener struct{}
   297  
   298  func (g *charsetStringGener) gen() interface{} {
   299  	rand := time.Now().Nanosecond() % 3
   300  	if rand == 0 {
   301  		return "ascii"
   302  	}
   303  	if rand == 1 {
   304  		return "utf8"
   305  	}
   306  	return "gbk"
   307  }
   308  
   309  // selectStringGener select one string randomly from the candidates array
   310  type selectStringGener struct {
   311  	candidates []string
   312  	randGen    *defaultRandGen
   313  }
   314  
   315  func newSelectStringGener(candidates []string) *selectStringGener {
   316  	return &selectStringGener{candidates, newDefaultRandGen()}
   317  }
   318  
   319  func (g *selectStringGener) gen() interface{} {
   320  	if len(g.candidates) == 0 {
   321  		return nil
   322  	}
   323  	return g.candidates[g.randGen.Intn(len(g.candidates))]
   324  }
   325  
   326  // selectRealGener select one real number randomly from the candidates array
   327  type selectRealGener struct {
   328  	candidates []float64
   329  	randGen    *defaultRandGen
   330  }
   331  
   332  func newSelectRealGener(candidates []float64) *selectRealGener {
   333  	return &selectRealGener{candidates, newDefaultRandGen()}
   334  }
   335  
   336  func (g *selectRealGener) gen() interface{} {
   337  	if len(g.candidates) == 0 {
   338  		return nil
   339  	}
   340  	return g.candidates[g.randGen.Intn(len(g.candidates))]
   341  }
   342  
   343  type constJSONGener struct {
   344  	jsonStr string
   345  }
   346  
   347  func (g *constJSONGener) gen() interface{} {
   348  	j := new(json.BinaryJSON)
   349  	if err := j.UnmarshalJSON([]byte(g.jsonStr)); err != nil {
   350  		panic(err)
   351  	}
   352  	return *j
   353  }
   354  
   355  type decimalJSONGener struct {
   356  	nullRation float64
   357  	randGen    *defaultRandGen
   358  }
   359  
   360  func newDecimalJSONGener(nullRation float64) *decimalJSONGener {
   361  	return &decimalJSONGener{nullRation, newDefaultRandGen()}
   362  }
   363  
   364  func (g *decimalJSONGener) gen() interface{} {
   365  	if g.randGen.Float64() < g.nullRation {
   366  		return nil
   367  	}
   368  
   369  	var f float64
   370  	if g.randGen.Float64() < 0.5 {
   371  		f = g.randGen.Float64() * 100000
   372  	} else {
   373  		f = -g.randGen.Float64() * 100000
   374  	}
   375  	if err := (&types.MyDecimal{}).FromFloat64(f); err != nil {
   376  		panic(err)
   377  	}
   378  	return json.CreateBinary(f)
   379  }
   380  
   381  type jsonStringGener struct {
   382  	randGen *defaultRandGen
   383  }
   384  
   385  func newJSONStringGener() *jsonStringGener {
   386  	return &jsonStringGener{newDefaultRandGen()}
   387  }
   388  
   389  func (g *jsonStringGener) gen() interface{} {
   390  	j := new(json.BinaryJSON)
   391  	if err := j.UnmarshalJSON([]byte(fmt.Sprintf(`{"key":%v}`, g.randGen.Int()))); err != nil {
   392  		panic(err)
   393  	}
   394  	return j.String()
   395  }
   396  
   397  type decimalStringGener struct {
   398  	randGen *defaultRandGen
   399  }
   400  
   401  func newDecimalStringGener() *decimalStringGener {
   402  	return &decimalStringGener{newDefaultRandGen()}
   403  }
   404  
   405  func (g *decimalStringGener) gen() interface{} {
   406  	temFIDelecimal := new(types.MyDecimal)
   407  	if err := temFIDelecimal.FromFloat64(g.randGen.Float64()); err != nil {
   408  		panic(err)
   409  	}
   410  	return temFIDelecimal.String()
   411  }
   412  
   413  type realStringGener struct {
   414  	randGen *defaultRandGen
   415  }
   416  
   417  func newRealStringGener() *realStringGener {
   418  	return &realStringGener{newDefaultRandGen()}
   419  }
   420  
   421  func (g *realStringGener) gen() interface{} {
   422  	return fmt.Sprintf("%f", g.randGen.Float64())
   423  }
   424  
   425  type jsonTimeGener struct {
   426  	randGen *defaultRandGen
   427  }
   428  
   429  func newJSONTimeGener() *jsonTimeGener {
   430  	return &jsonTimeGener{newDefaultRandGen()}
   431  }
   432  
   433  func (g *jsonTimeGener) gen() interface{} {
   434  	tm := types.NewTime(getRandomTime(g.randGen.Rand), allegrosql.TypeDatetime, types.DefaultFsp)
   435  	return json.CreateBinary(tm.String())
   436  }
   437  
   438  type rangeDurationGener struct {
   439  	nullRation float64
   440  	randGen    *defaultRandGen
   441  }
   442  
   443  func newRangeDurationGener(nullRation float64) *rangeDurationGener {
   444  	return &rangeDurationGener{nullRation, newDefaultRandGen()}
   445  }
   446  
   447  func (g *rangeDurationGener) gen() interface{} {
   448  	if g.randGen.Float64() < g.nullRation {
   449  		return nil
   450  	}
   451  	tm := (math.Abs(g.randGen.Int63n(12))*3600 + math.Abs(g.randGen.Int63n(60))*60 + math.Abs(g.randGen.Int63n(60))) * 1000
   452  	tu := (tm + math.Abs(g.randGen.Int63n(1000))) * 1000
   453  	return types.Duration{
   454  		Duration: time.Duration(tu * 1000)}
   455  }
   456  
   457  type timeFormatGener struct {
   458  	nullRation float64
   459  	randGen    *defaultRandGen
   460  }
   461  
   462  func newTimeFormatGener(nullRation float64) *timeFormatGener {
   463  	return &timeFormatGener{nullRation, newDefaultRandGen()}
   464  }
   465  
   466  func (g *timeFormatGener) gen() interface{} {
   467  	if g.randGen.Float64() < g.nullRation {
   468  		return nil
   469  	}
   470  	switch g.randGen.Uint32() % 4 {
   471  	case 0:
   472  		return "%H %i %S"
   473  	case 1:
   474  		return "%l %i %s"
   475  	case 2:
   476  		return "%p %i %s"
   477  	case 3:
   478  		return "%I %i %S %f"
   479  	case 4:
   480  		return "%T"
   481  	default:
   482  		return nil
   483  	}
   484  }
   485  
   486  // rangeRealGener is used to generate float64 items in [begin, end].
   487  type rangeRealGener struct {
   488  	begin float64
   489  	end   float64
   490  
   491  	nullRation float64
   492  	randGen    *defaultRandGen
   493  }
   494  
   495  func newRangeRealGener(begin, end, nullRation float64) *rangeRealGener {
   496  	return &rangeRealGener{begin, end, nullRation, newDefaultRandGen()}
   497  }
   498  
   499  func (g *rangeRealGener) gen() interface{} {
   500  	if g.randGen.Float64() < g.nullRation {
   501  		return nil
   502  	}
   503  	if g.end < g.begin {
   504  		g.begin = -100
   505  		g.end = 100
   506  	}
   507  	return g.randGen.Float64()*(g.end-g.begin) + g.begin
   508  }
   509  
   510  // rangeDecimalGener is used to generate decimal items in [begin, end].
   511  type rangeDecimalGener struct {
   512  	begin float64
   513  	end   float64
   514  
   515  	nullRation float64
   516  	randGen    *defaultRandGen
   517  }
   518  
   519  func newRangeDecimalGener(begin, end, nullRation float64) *rangeDecimalGener {
   520  	return &rangeDecimalGener{begin, end, nullRation, newDefaultRandGen()}
   521  }
   522  
   523  func (g *rangeDecimalGener) gen() interface{} {
   524  	if g.randGen.Float64() < g.nullRation {
   525  		return nil
   526  	}
   527  	if g.end < g.begin {
   528  		g.begin = -100000
   529  		g.end = 100000
   530  	}
   531  	d := new(types.MyDecimal)
   532  	f := g.randGen.Float64()*(g.end-g.begin) + g.begin
   533  	if err := d.FromFloat64(f); err != nil {
   534  		panic(err)
   535  	}
   536  	return d
   537  }
   538  
   539  // rangeInt64Gener is used to generate int64 items in [begin, end).
   540  type rangeInt64Gener struct {
   541  	begin   int
   542  	end     int
   543  	randGen *defaultRandGen
   544  }
   545  
   546  func newRangeInt64Gener(begin, end int) *rangeInt64Gener {
   547  	return &rangeInt64Gener{begin, end, newDefaultRandGen()}
   548  }
   549  
   550  func (rig *rangeInt64Gener) gen() interface{} {
   551  	return int64(rig.randGen.Intn(rig.end-rig.begin) + rig.begin)
   552  }
   553  
   554  // numStrGener is used to generate number strings.
   555  type numStrGener struct {
   556  	rangeInt64Gener
   557  }
   558  
   559  func (g *numStrGener) gen() interface{} {
   560  	return fmt.Sprintf("%v", g.rangeInt64Gener.gen())
   561  }
   562  
   563  // ipv6StrGener is used to generate ipv6 strings.
   564  type ipv6StrGener struct {
   565  	randGen *defaultRandGen
   566  }
   567  
   568  func (g *ipv6StrGener) gen() interface{} {
   569  	var ip net.IP = make([]byte, net.IPv6len)
   570  	for i := range ip {
   571  		ip[i] = uint8(g.randGen.Intn(256))
   572  	}
   573  	return ip.String()
   574  }
   575  
   576  // ipv4StrGener is used to generate ipv4 strings. For example 111.111.111.111
   577  type ipv4StrGener struct {
   578  	randGen *defaultRandGen
   579  }
   580  
   581  func (g *ipv4StrGener) gen() interface{} {
   582  	var ip net.IP = make([]byte, net.IPv4len)
   583  	for i := range ip {
   584  		ip[i] = uint8(g.randGen.Intn(256))
   585  	}
   586  	return ip.String()
   587  }
   588  
   589  // ipv6ByteGener is used to generate ipv6 address in 16 bytes string.
   590  type ipv6ByteGener struct {
   591  	randGen *defaultRandGen
   592  }
   593  
   594  func (g *ipv6ByteGener) gen() interface{} {
   595  	var ip = make([]byte, net.IPv6len)
   596  	for i := range ip {
   597  		ip[i] = uint8(g.randGen.Intn(256))
   598  	}
   599  	return string(ip[:net.IPv6len])
   600  }
   601  
   602  // ipv4ByteGener is used to generate ipv4 address in 4 bytes string.
   603  type ipv4ByteGener struct {
   604  	randGen *defaultRandGen
   605  }
   606  
   607  func (g *ipv4ByteGener) gen() interface{} {
   608  	var ip = make([]byte, net.IPv4len)
   609  	for i := range ip {
   610  		ip[i] = uint8(g.randGen.Intn(256))
   611  	}
   612  	return string(ip[:net.IPv4len])
   613  }
   614  
   615  // ipv4Compat is used to generate ipv4 compatible ipv6 strings
   616  type ipv4CompatByteGener struct {
   617  	randGen *defaultRandGen
   618  }
   619  
   620  func (g *ipv4CompatByteGener) gen() interface{} {
   621  	var ip = make([]byte, net.IPv6len)
   622  	for i := range ip {
   623  		if i < 12 {
   624  			ip[i] = 0
   625  		} else {
   626  			ip[i] = uint8(g.randGen.Intn(256))
   627  		}
   628  	}
   629  	return string(ip[:net.IPv6len])
   630  }
   631  
   632  // ipv4MappedByteGener is used to generate ipv4-mapped ipv6 bytes.
   633  type ipv4MappedByteGener struct {
   634  	randGen *defaultRandGen
   635  }
   636  
   637  func (g *ipv4MappedByteGener) gen() interface{} {
   638  	var ip = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0, 0, 0, 0}
   639  	for i := 12; i < 16; i++ {
   640  		ip[i] = uint8(g.randGen.Intn(256)) // reset the last 4 bytes
   641  	}
   642  	return string(ip[:net.IPv6len])
   643  }
   644  
   645  // randLenStrGener is used to generate strings whose lengths are in [lenBegin, lenEnd).
   646  type randLenStrGener struct {
   647  	lenBegin int
   648  	lenEnd   int
   649  	randGen  *defaultRandGen
   650  }
   651  
   652  func newRandLenStrGener(lenBegin, lenEnd int) *randLenStrGener {
   653  	return &randLenStrGener{lenBegin, lenEnd, newDefaultRandGen()}
   654  }
   655  
   656  func (g *randLenStrGener) gen() interface{} {
   657  	n := g.randGen.Intn(g.lenEnd-g.lenBegin) + g.lenBegin
   658  	buf := make([]byte, n)
   659  	for i := range buf {
   660  		x := g.randGen.Intn(62)
   661  		if x < 10 {
   662  			buf[i] = byte('0' + x)
   663  		} else if x-10 < 26 {
   664  			buf[i] = byte('a' + x - 10)
   665  		} else {
   666  			buf[i] = byte('A' + x - 10 - 26)
   667  		}
   668  	}
   669  	return string(buf)
   670  }
   671  
   672  type randHexStrGener struct {
   673  	lenBegin int
   674  	lenEnd   int
   675  	randGen  *defaultRandGen
   676  }
   677  
   678  func newRandHexStrGener(lenBegin, lenEnd int) *randHexStrGener {
   679  	return &randHexStrGener{lenBegin, lenEnd, newDefaultRandGen()}
   680  }
   681  
   682  func (g *randHexStrGener) gen() interface{} {
   683  	n := g.randGen.Intn(g.lenEnd-g.lenBegin) + g.lenBegin
   684  	buf := make([]byte, n)
   685  	for i := range buf {
   686  		x := g.randGen.Intn(16)
   687  		if x < 10 {
   688  			buf[i] = byte('0' + x)
   689  		} else {
   690  			if x%2 == 0 {
   691  				buf[i] = byte('a' + x - 10)
   692  			} else {
   693  				buf[i] = byte('A' + x - 10)
   694  			}
   695  		}
   696  	}
   697  	return string(buf)
   698  }
   699  
   700  // dateTimeGener is used to generate a dataTime
   701  type dateTimeGener struct {
   702  	Fsp     int
   703  	Year    int
   704  	Month   int
   705  	Day     int
   706  	randGen *defaultRandGen
   707  }
   708  
   709  func newDateTimeGener(fsp, year, month, day int) *dateTimeGener {
   710  	return &dateTimeGener{fsp, year, month, day, newDefaultRandGen()}
   711  }
   712  
   713  func (g *dateTimeGener) gen() interface{} {
   714  	if g.Year == 0 {
   715  		g.Year = 1970 + g.randGen.Intn(100)
   716  	}
   717  	if g.Month == 0 {
   718  		g.Month = g.randGen.Intn(10) + 1
   719  	}
   720  	if g.Day == 0 {
   721  		g.Day = g.randGen.Intn(20) + 1
   722  	}
   723  	var gt types.CoreTime
   724  	if g.Fsp > 0 && g.Fsp <= 6 {
   725  		gt = types.FromDate(g.Year, g.Month, g.Day, g.randGen.Intn(12), g.randGen.Intn(60), g.randGen.Intn(60), g.randGen.Intn(1000000))
   726  	} else {
   727  		gt = types.FromDate(g.Year, g.Month, g.Day, g.randGen.Intn(12), g.randGen.Intn(60), g.randGen.Intn(60), 0)
   728  	}
   729  	t := types.NewTime(gt, allegrosql.TypeDatetime, types.DefaultFsp)
   730  	return t
   731  }
   732  
   733  // dateTimeStrGener is used to generate strings which are dataTime format
   734  type dateTimeStrGener struct {
   735  	Fsp     int
   736  	Year    int
   737  	Month   int
   738  	Day     int
   739  	randGen *defaultRandGen
   740  }
   741  
   742  func (g *dateTimeStrGener) gen() interface{} {
   743  	if g.Year == 0 {
   744  		g.Year = 1970 + g.randGen.Intn(100)
   745  	}
   746  	if g.Month == 0 {
   747  		g.Month = g.randGen.Intn(10) + 1
   748  	}
   749  	if g.Day == 0 {
   750  		g.Day = g.randGen.Intn(20) + 1
   751  	}
   752  	hour := g.randGen.Intn(12)
   753  	minute := g.randGen.Intn(60)
   754  	second := g.randGen.Intn(60)
   755  	dataTimeStr := fmt.Sprintf("%d-%d-%d %d:%d:%d",
   756  		g.Year, g.Month, g.Day, hour, minute, second)
   757  	if g.Fsp > 0 && g.Fsp <= 6 {
   758  		microFmt := fmt.Sprintf(".%%0%dd", g.Fsp)
   759  		return dataTimeStr + fmt.Sprintf(microFmt, g.randGen.Int()%(10^g.Fsp))
   760  	}
   761  
   762  	return dataTimeStr
   763  }
   764  
   765  // dateStrGener is used to generate strings which are date format
   766  type dateStrGener struct {
   767  	Year       int
   768  	Month      int
   769  	Day        int
   770  	NullRation float64
   771  	randGen    *defaultRandGen
   772  }
   773  
   774  func (g *dateStrGener) gen() interface{} {
   775  	if g.NullRation > 1e-6 && g.randGen.Float64() < g.NullRation {
   776  		return nil
   777  	}
   778  
   779  	if g.Year == 0 {
   780  		g.Year = 1970 + g.randGen.Intn(100)
   781  	}
   782  	if g.Month == 0 {
   783  		g.Month = g.randGen.Intn(10) + 1
   784  	}
   785  	if g.Day == 0 {
   786  		g.Day = g.randGen.Intn(20) + 1
   787  	}
   788  
   789  	return fmt.Sprintf("%d-%d-%d", g.Year, g.Month, g.Day)
   790  }
   791  
   792  // timeStrGener is used to generate strings which are time format
   793  type timeStrGener struct {
   794  	nullRation float64
   795  	randGen    *defaultRandGen
   796  }
   797  
   798  func (g *timeStrGener) gen() interface{} {
   799  	if g.nullRation > 1e-6 && g.randGen.Float64() < g.nullRation {
   800  		return nil
   801  	}
   802  	hour := g.randGen.Intn(12)
   803  	minute := g.randGen.Intn(60)
   804  	second := g.randGen.Intn(60)
   805  
   806  	return fmt.Sprintf("%d:%d:%d", hour, minute, second)
   807  }
   808  
   809  type dateTimeIntGener struct {
   810  	dateTimeGener
   811  	nullRation float64
   812  }
   813  
   814  func (g *dateTimeIntGener) gen() interface{} {
   815  	if g.randGen.Float64() < g.nullRation {
   816  		return nil
   817  	}
   818  
   819  	t := g.dateTimeGener.gen().(types.Time)
   820  	num, err := t.ToNumber().ToInt()
   821  	if err != nil {
   822  		panic(err)
   823  	}
   824  	return num
   825  }
   826  
   827  // constStrGener always returns the given string
   828  type constStrGener struct {
   829  	s string
   830  }
   831  
   832  func (g *constStrGener) gen() interface{} {
   833  	return g.s
   834  }
   835  
   836  type randDurInt struct {
   837  	randGen *defaultRandGen
   838  }
   839  
   840  func newRandDurInt() *randDurInt {
   841  	return &randDurInt{newDefaultRandGen()}
   842  }
   843  
   844  func (g *randDurInt) gen() interface{} {
   845  	return int64(g.randGen.Intn(types.TimeMaxHour)*10000 + g.randGen.Intn(60)*100 + g.randGen.Intn(60))
   846  }
   847  
   848  type randDurReal struct {
   849  	randGen *defaultRandGen
   850  }
   851  
   852  func newRandDurReal() *randDurReal {
   853  	return &randDurReal{newDefaultRandGen()}
   854  }
   855  
   856  func (g *randDurReal) gen() interface{} {
   857  	return float64(g.randGen.Intn(types.TimeMaxHour)*10000 + g.randGen.Intn(60)*100 + g.randGen.Intn(60))
   858  }
   859  
   860  type randDurDecimal struct {
   861  	randGen *defaultRandGen
   862  }
   863  
   864  func newRandDurDecimal() *randDurDecimal {
   865  	return &randDurDecimal{newDefaultRandGen()}
   866  }
   867  
   868  func (g *randDurDecimal) gen() interface{} {
   869  	d := new(types.MyDecimal)
   870  	return d.FromFloat64(float64(g.randGen.Intn(types.TimeMaxHour)*10000 + g.randGen.Intn(60)*100 + g.randGen.Intn(60)))
   871  }
   872  
   873  type randDurString struct{}
   874  
   875  func (g *randDurString) gen() interface{} {
   876  	return strconv.Itoa(rand.Intn(types.TimeMaxHour)*10000 + rand.Intn(60)*100 + rand.Intn(60))
   877  }
   878  
   879  // locationGener is used to generate location for the built-in function GetFormat.
   880  type locationGener struct {
   881  	nullRation float64
   882  	randGen    *defaultRandGen
   883  }
   884  
   885  func newLocationGener(nullRation float64) *locationGener {
   886  	return &locationGener{nullRation, newDefaultRandGen()}
   887  }
   888  
   889  func (g *locationGener) gen() interface{} {
   890  	if g.randGen.Float64() < g.nullRation {
   891  		return nil
   892  	}
   893  	switch g.randGen.Uint32() % 5 {
   894  	case 0:
   895  		return usaLocation
   896  	case 1:
   897  		return jisLocation
   898  	case 2:
   899  		return isoLocation
   900  	case 3:
   901  		return eurLocation
   902  	case 4:
   903  		return internalLocation
   904  	default:
   905  		return nil
   906  	}
   907  }
   908  
   909  // formatGener is used to generate a format for the built-in function GetFormat.
   910  type formatGener struct {
   911  	nullRation float64
   912  	randGen    *defaultRandGen
   913  }
   914  
   915  func newFormatGener(nullRation float64) *formatGener {
   916  	return &formatGener{nullRation, newDefaultRandGen()}
   917  }
   918  
   919  func (g *formatGener) gen() interface{} {
   920  	if g.randGen.Float64() < g.nullRation {
   921  		return nil
   922  	}
   923  	switch g.randGen.Uint32() % 4 {
   924  	case 0:
   925  		return dateFormat
   926  	case 1:
   927  		return datetimeFormat
   928  	case 2:
   929  		return timestampFormat
   930  	case 3:
   931  		return timeFormat
   932  	default:
   933  		return nil
   934  	}
   935  }
   936  
   937  type nullWrappedGener struct {
   938  	nullRation float64
   939  	inner      dataGenerator
   940  	randGen    *defaultRandGen
   941  }
   942  
   943  func newNullWrappedGener(nullRation float64, inner dataGenerator) *nullWrappedGener {
   944  	return &nullWrappedGener{nullRation, inner, newDefaultRandGen()}
   945  }
   946  
   947  func (g *nullWrappedGener) gen() interface{} {
   948  	if g.randGen.Float64() < g.nullRation {
   949  		return nil
   950  	}
   951  	return g.inner.gen()
   952  }
   953  
   954  type vecExprBenchCase struct {
   955  	// retEvalType is the EvalType of the memex result.
   956  	// This field is required.
   957  	retEvalType types.EvalType
   958  	// childrenTypes is the EvalTypes of the memex children(arguments).
   959  	// This field is required.
   960  	childrenTypes []types.EvalType
   961  	// childrenFieldTypes is the field types of the memex children(arguments).
   962  	// If childrenFieldTypes is not set, it will be converted from childrenTypes.
   963  	// This field is optional.
   964  	childrenFieldTypes []*types.FieldType
   965  	// geners are used to generate data for children and geners[i] generates data for children[i].
   966  	// If geners[i] is nil, the default dataGenerator will be used for its corresponding child.
   967  	// The geners slice can be shorter than the children slice, if it has 3 children, then
   968  	// geners[gen1, gen2] will be regarded as geners[gen1, gen2, nil].
   969  	// This field is optional.
   970  	geners []dataGenerator
   971  	// aesModeAttr information, needed by encryption functions
   972  	aesModes string
   973  	// constants are used to generate constant data for children[i].
   974  	constants []*Constant
   975  	// chunkSize is used to specify the chunk size of children, the maximum is 1024.
   976  	// This field is optional, 1024 by default.
   977  	chunkSize int
   978  }
   979  
   980  type vecExprBenchCases map[string][]vecExprBenchCase
   981  
   982  func fillDeferredCauset(eType types.EvalType, chk *chunk.Chunk, defCausIdx int, testCase vecExprBenchCase) {
   983  	var gen dataGenerator
   984  	if len(testCase.geners) > defCausIdx && testCase.geners[defCausIdx] != nil {
   985  		gen = testCase.geners[defCausIdx]
   986  	}
   987  	fillDeferredCausetWithGener(eType, chk, defCausIdx, gen)
   988  }
   989  
   990  func fillDeferredCausetWithGener(eType types.EvalType, chk *chunk.Chunk, defCausIdx int, gen dataGenerator) {
   991  	batchSize := chk.Capacity()
   992  	if gen == nil {
   993  		gen = newDefaultGener(0.2, eType)
   994  	}
   995  
   996  	defCaus := chk.DeferredCauset(defCausIdx)
   997  	defCaus.Reset(eType)
   998  	for i := 0; i < batchSize; i++ {
   999  		v := gen.gen()
  1000  		if v == nil {
  1001  			defCaus.AppendNull()
  1002  			continue
  1003  		}
  1004  		switch eType {
  1005  		case types.ETInt:
  1006  			defCaus.AppendInt64(v.(int64))
  1007  		case types.ETReal:
  1008  			defCaus.AppendFloat64(v.(float64))
  1009  		case types.ETDecimal:
  1010  			defCaus.AppendMyDecimal(v.(*types.MyDecimal))
  1011  		case types.ETDatetime, types.ETTimestamp:
  1012  			defCaus.AppendTime(v.(types.Time))
  1013  		case types.ETDuration:
  1014  			defCaus.AppendDuration(v.(types.Duration))
  1015  		case types.ETJson:
  1016  			defCaus.AppendJSON(v.(json.BinaryJSON))
  1017  		case types.ETString:
  1018  			defCaus.AppendString(v.(string))
  1019  		}
  1020  	}
  1021  }
  1022  
  1023  func randString(r *rand.Rand) string {
  1024  	n := 10 + r.Intn(10)
  1025  	buf := make([]byte, n)
  1026  	for i := range buf {
  1027  		x := r.Intn(62)
  1028  		if x < 10 {
  1029  			buf[i] = byte('0' + x)
  1030  		} else if x-10 < 26 {
  1031  			buf[i] = byte('a' + x - 10)
  1032  		} else {
  1033  			buf[i] = byte('A' + x - 10 - 26)
  1034  		}
  1035  	}
  1036  	return string(buf)
  1037  }
  1038  
  1039  func eType2FieldType(eType types.EvalType) *types.FieldType {
  1040  	switch eType {
  1041  	case types.ETInt:
  1042  		return types.NewFieldType(allegrosql.TypeLonglong)
  1043  	case types.ETReal:
  1044  		return types.NewFieldType(allegrosql.TypeDouble)
  1045  	case types.ETDecimal:
  1046  		return types.NewFieldType(allegrosql.TypeNewDecimal)
  1047  	case types.ETDatetime, types.ETTimestamp:
  1048  		return types.NewFieldType(allegrosql.TypeDatetime)
  1049  	case types.ETDuration:
  1050  		return types.NewFieldType(allegrosql.TypeDuration)
  1051  	case types.ETJson:
  1052  		return types.NewFieldType(allegrosql.TypeJSON)
  1053  	case types.ETString:
  1054  		return types.NewFieldType(allegrosql.TypeVarString)
  1055  	default:
  1056  		panic(fmt.Sprintf("EvalType=%v is not supported.", eType))
  1057  	}
  1058  }
  1059  
  1060  func genVecExprBenchCase(ctx stochastikctx.Context, funcName string, testCase vecExprBenchCase) (expr Expression, fts []*types.FieldType, input *chunk.Chunk, output *chunk.Chunk) {
  1061  	fts = make([]*types.FieldType, len(testCase.childrenTypes))
  1062  	for i := range fts {
  1063  		if i < len(testCase.childrenFieldTypes) && testCase.childrenFieldTypes[i] != nil {
  1064  			fts[i] = testCase.childrenFieldTypes[i]
  1065  		} else {
  1066  			fts[i] = eType2FieldType(testCase.childrenTypes[i])
  1067  		}
  1068  	}
  1069  	if testCase.chunkSize <= 0 || testCase.chunkSize > 1024 {
  1070  		testCase.chunkSize = 1024
  1071  	}
  1072  	defcaus := make([]Expression, len(testCase.childrenTypes))
  1073  	input = chunk.New(fts, testCase.chunkSize, testCase.chunkSize)
  1074  	input.NumEvents()
  1075  	for i, eType := range testCase.childrenTypes {
  1076  		fillDeferredCauset(eType, input, i, testCase)
  1077  		if i < len(testCase.constants) && testCase.constants[i] != nil {
  1078  			defcaus[i] = testCase.constants[i]
  1079  		} else {
  1080  			defcaus[i] = &DeferredCauset{Index: i, RetType: fts[i]}
  1081  		}
  1082  	}
  1083  
  1084  	expr, err := NewFunction(ctx, funcName, eType2FieldType(testCase.retEvalType), defcaus...)
  1085  	if err != nil {
  1086  		panic(err)
  1087  	}
  1088  
  1089  	output = chunk.New([]*types.FieldType{eType2FieldType(expr.GetType().EvalType())}, testCase.chunkSize, testCase.chunkSize)
  1090  	return expr, fts, input, output
  1091  }
  1092  
  1093  // testVectorizedEvalOneVec is used to verify that the vectorized
  1094  // memex is evaluated correctly during projection
  1095  func testVectorizedEvalOneVec(c *C, vecExprCases vecExprBenchCases) {
  1096  	ctx := mock.NewContext()
  1097  	for funcName, testCases := range vecExprCases {
  1098  		for _, testCase := range testCases {
  1099  			expr, fts, input, output := genVecExprBenchCase(ctx, funcName, testCase)
  1100  			commentf := func(event int) CommentInterface {
  1101  				return Commentf("func: %v, case %+v, event: %v, rowData: %v", funcName, testCase, event, input.GetEvent(event).GetCausetEvent(fts))
  1102  			}
  1103  			output2 := output.CopyConstruct()
  1104  			c.Assert(evalOneVec(ctx, expr, input, output, 0), IsNil, Commentf("func: %v, case: %+v", funcName, testCase))
  1105  			it := chunk.NewIterator4Chunk(input)
  1106  			c.Assert(evalOneDeferredCauset(ctx, expr, it, output2, 0), IsNil, Commentf("func: %v, case: %+v", funcName, testCase))
  1107  
  1108  			c1, c2 := output.DeferredCauset(0), output2.DeferredCauset(0)
  1109  			switch expr.GetType().EvalType() {
  1110  			case types.ETInt:
  1111  				for i := 0; i < input.NumEvents(); i++ {
  1112  					c.Assert(c1.IsNull(i), Equals, c2.IsNull(i), commentf(i))
  1113  					if !c1.IsNull(i) {
  1114  						c.Assert(c1.GetInt64(i), Equals, c2.GetInt64(i), commentf(i))
  1115  					}
  1116  				}
  1117  			case types.ETReal:
  1118  				for i := 0; i < input.NumEvents(); i++ {
  1119  					c.Assert(c1.IsNull(i), Equals, c2.IsNull(i), commentf(i))
  1120  					if !c1.IsNull(i) {
  1121  						c.Assert(c1.GetFloat64(i), Equals, c2.GetFloat64(i), commentf(i))
  1122  					}
  1123  				}
  1124  			case types.ETDecimal:
  1125  				for i := 0; i < input.NumEvents(); i++ {
  1126  					c.Assert(c1.IsNull(i), Equals, c2.IsNull(i), commentf(i))
  1127  					if !c1.IsNull(i) {
  1128  						c.Assert(c1.GetDecimal(i), DeepEquals, c2.GetDecimal(i), commentf(i))
  1129  					}
  1130  				}
  1131  			case types.ETDatetime, types.ETTimestamp:
  1132  				for i := 0; i < input.NumEvents(); i++ {
  1133  					c.Assert(c1.IsNull(i), Equals, c2.IsNull(i), commentf(i))
  1134  					if !c1.IsNull(i) {
  1135  						c.Assert(c1.GetTime(i), DeepEquals, c2.GetTime(i), commentf(i))
  1136  					}
  1137  				}
  1138  			case types.ETDuration:
  1139  				for i := 0; i < input.NumEvents(); i++ {
  1140  					c.Assert(c1.IsNull(i), Equals, c2.IsNull(i), commentf(i))
  1141  					if !c1.IsNull(i) {
  1142  						c.Assert(c1.GetDuration(i, 0), Equals, c2.GetDuration(i, 0), commentf(i))
  1143  					}
  1144  				}
  1145  			case types.ETJson:
  1146  				for i := 0; i < input.NumEvents(); i++ {
  1147  					c.Assert(c1.IsNull(i), Equals, c2.IsNull(i), commentf(i))
  1148  					if !c1.IsNull(i) {
  1149  						c.Assert(c1.GetJSON(i), DeepEquals, c2.GetJSON(i), commentf(i))
  1150  					}
  1151  				}
  1152  			case types.ETString:
  1153  				for i := 0; i < input.NumEvents(); i++ {
  1154  					c.Assert(c1.IsNull(i), Equals, c2.IsNull(i), commentf(i))
  1155  					if !c1.IsNull(i) {
  1156  						c.Assert(c1.GetString(i), Equals, c2.GetString(i), commentf(i))
  1157  					}
  1158  				}
  1159  			}
  1160  		}
  1161  	}
  1162  }
  1163  
  1164  // benchmarkVectorizedEvalOneVec is used to get the effect of
  1165  // using the vectorized memex evaluations during projection
  1166  func benchmarkVectorizedEvalOneVec(b *testing.B, vecExprCases vecExprBenchCases) {
  1167  	ctx := mock.NewContext()
  1168  	for funcName, testCases := range vecExprCases {
  1169  		for _, testCase := range testCases {
  1170  			expr, _, input, output := genVecExprBenchCase(ctx, funcName, testCase)
  1171  			exprName := expr.String()
  1172  			if sf, ok := expr.(*ScalarFunction); ok {
  1173  				exprName = fmt.Sprintf("%v", reflect.TypeOf(sf.Function))
  1174  				tmp := strings.Split(exprName, ".")
  1175  				exprName = tmp[len(tmp)-1]
  1176  			}
  1177  
  1178  			b.Run(exprName+"-EvalOneVec", func(b *testing.B) {
  1179  				b.ResetTimer()
  1180  				for i := 0; i < b.N; i++ {
  1181  					if err := evalOneVec(ctx, expr, input, output, 0); err != nil {
  1182  						b.Fatal(err)
  1183  					}
  1184  				}
  1185  			})
  1186  			b.Run(exprName+"-EvalOneDefCaus", func(b *testing.B) {
  1187  				b.ResetTimer()
  1188  				for i := 0; i < b.N; i++ {
  1189  					it := chunk.NewIterator4Chunk(input)
  1190  					if err := evalOneDeferredCauset(ctx, expr, it, output, 0); err != nil {
  1191  						b.Fatal(err)
  1192  					}
  1193  				}
  1194  			})
  1195  		}
  1196  	}
  1197  }
  1198  
  1199  func genVecBuiltinFuncBenchCase(ctx stochastikctx.Context, funcName string, testCase vecExprBenchCase) (baseFunc builtinFunc, fts []*types.FieldType, input *chunk.Chunk, result *chunk.DeferredCauset) {
  1200  	childrenNumber := len(testCase.childrenTypes)
  1201  	fts = make([]*types.FieldType, childrenNumber)
  1202  	for i := range fts {
  1203  		if i < len(testCase.childrenFieldTypes) && testCase.childrenFieldTypes[i] != nil {
  1204  			fts[i] = testCase.childrenFieldTypes[i]
  1205  		} else {
  1206  			fts[i] = eType2FieldType(testCase.childrenTypes[i])
  1207  		}
  1208  	}
  1209  	defcaus := make([]Expression, childrenNumber)
  1210  	if testCase.chunkSize <= 0 || testCase.chunkSize > 1024 {
  1211  		testCase.chunkSize = 1024
  1212  	}
  1213  	input = chunk.New(fts, testCase.chunkSize, testCase.chunkSize)
  1214  	for i, eType := range testCase.childrenTypes {
  1215  		fillDeferredCauset(eType, input, i, testCase)
  1216  		if i < len(testCase.constants) && testCase.constants[i] != nil {
  1217  			defcaus[i] = testCase.constants[i]
  1218  		} else {
  1219  			defcaus[i] = &DeferredCauset{Index: i, RetType: fts[i]}
  1220  		}
  1221  	}
  1222  	if len(defcaus) == 0 {
  1223  		input.SetNumVirtualEvents(testCase.chunkSize)
  1224  	}
  1225  
  1226  	var err error
  1227  	if funcName == ast.Cast {
  1228  		var fc functionClass
  1229  		tp := eType2FieldType(testCase.retEvalType)
  1230  		switch testCase.retEvalType {
  1231  		case types.ETInt:
  1232  			fc = &castAsIntFunctionClass{baseFunctionClass{ast.Cast, 1, 1}, tp}
  1233  		case types.ETDecimal:
  1234  			fc = &castAsDecimalFunctionClass{baseFunctionClass{ast.Cast, 1, 1}, tp}
  1235  		case types.ETReal:
  1236  			fc = &castAsRealFunctionClass{baseFunctionClass{ast.Cast, 1, 1}, tp}
  1237  		case types.ETDatetime, types.ETTimestamp:
  1238  			fc = &castAsTimeFunctionClass{baseFunctionClass{ast.Cast, 1, 1}, tp}
  1239  		case types.ETDuration:
  1240  			fc = &castAsDurationFunctionClass{baseFunctionClass{ast.Cast, 1, 1}, tp}
  1241  		case types.ETJson:
  1242  			fc = &castAsJSONFunctionClass{baseFunctionClass{ast.Cast, 1, 1}, tp}
  1243  		case types.ETString:
  1244  			fc = &castAsStringFunctionClass{baseFunctionClass{ast.Cast, 1, 1}, tp}
  1245  		}
  1246  		baseFunc, err = fc.getFunction(ctx, defcaus)
  1247  	} else {
  1248  		baseFunc, err = funcs[funcName].getFunction(ctx, defcaus)
  1249  	}
  1250  	if err != nil {
  1251  		panic(err)
  1252  	}
  1253  	result = chunk.NewDeferredCauset(eType2FieldType(testCase.retEvalType), testCase.chunkSize)
  1254  	// Mess up the output to make sure vecEvalXXX to call ResizeXXX/ReserveXXX itself.
  1255  	result.AppendNull()
  1256  	return baseFunc, fts, input, result
  1257  }
  1258  
  1259  // a replog way to calculate length of a chunk.DeferredCauset.
  1260  func getDeferredCausetLen(defCaus *chunk.DeferredCauset, eType types.EvalType) int {
  1261  	chk := chunk.New([]*types.FieldType{eType2FieldType(eType)}, 1024, 1024)
  1262  	chk.SetDefCaus(0, defCaus)
  1263  	return chk.NumEvents()
  1264  }
  1265  
  1266  // removeTestOptions removes all not needed options like '-test.timeout=' from argument list
  1267  func removeTestOptions(args []string) []string {
  1268  	argList := args[:0]
  1269  
  1270  	// args contains '-test.timeout=' option for example
  1271  	// excluding it to be able to run all tests
  1272  	for _, arg := range args {
  1273  		if strings.HasPrefix(arg, "builtin") || IsFunctionSupported(arg) {
  1274  			argList = append(argList, arg)
  1275  		}
  1276  	}
  1277  	return argList
  1278  }
  1279  
  1280  // testVectorizedBuiltinFunc is used to verify that the vectorized
  1281  // memex is evaluated correctly
  1282  func testVectorizedBuiltinFunc(c *C, vecExprCases vecExprBenchCases) {
  1283  	testFunc := make(map[string]bool)
  1284  	argList := removeTestOptions(flag.Args())
  1285  	testAll := len(argList) == 0
  1286  	for _, arg := range argList {
  1287  		testFunc[arg] = true
  1288  	}
  1289  	for funcName, testCases := range vecExprCases {
  1290  		for _, testCase := range testCases {
  1291  			ctx := mock.NewContext()
  1292  			err := ctx.GetStochastikVars().SetSystemVar(variable.BlockEncryptionMode, testCase.aesModes)
  1293  			c.Assert(err, IsNil)
  1294  			if funcName == ast.CurrentUser || funcName == ast.User {
  1295  				ctx.GetStochastikVars().User = &auth.UserIdentity{
  1296  					Username:     "milevadb",
  1297  					Hostname:     "localhost",
  1298  					CurrentUser:  true,
  1299  					AuthHostname: "localhost",
  1300  					AuthUsername: "milevadb",
  1301  				}
  1302  			}
  1303  			if funcName == ast.GetParam {
  1304  				testTime := time.Now()
  1305  				ctx.GetStochastikVars().PreparedParams = []types.Causet{
  1306  					types.NewIntCauset(1),
  1307  					types.NewDecimalCauset(types.NewDecFromStringForTest("20170118123950.123")),
  1308  					types.NewTimeCauset(types.NewTime(types.FromGoTime(testTime), allegrosql.TypeTimestamp, 6)),
  1309  					types.NewDurationCauset(types.ZeroDuration),
  1310  					types.NewStringCauset("{}"),
  1311  					types.NewBinaryLiteralCauset([]byte{1}),
  1312  					types.NewBytesCauset([]byte{'b'}),
  1313  					types.NewFloat32Causet(1.1),
  1314  					types.NewFloat64Causet(2.1),
  1315  					types.NewUintCauset(100),
  1316  					types.NewMysqlBitCauset([]byte{1}),
  1317  					types.NewMysqlEnumCauset(types.Enum{Name: "n", Value: 2}),
  1318  				}
  1319  			}
  1320  			baseFunc, fts, input, output := genVecBuiltinFuncBenchCase(ctx, funcName, testCase)
  1321  			baseFuncName := fmt.Sprintf("%v", reflect.TypeOf(baseFunc))
  1322  			tmp := strings.Split(baseFuncName, ".")
  1323  			baseFuncName = tmp[len(tmp)-1]
  1324  
  1325  			if !testAll && (testFunc[baseFuncName] != true && testFunc[funcName] != true) {
  1326  				continue
  1327  			}
  1328  			// do not forget to implement the vectorized method.
  1329  			c.Assert(baseFunc.vectorized(), IsTrue, Commentf("func: %v, case: %+v", baseFuncName, testCase))
  1330  			commentf := func(event int) CommentInterface {
  1331  				return Commentf("func: %v, case %+v, event: %v, rowData: %v", baseFuncName, testCase, event, input.GetEvent(event).GetCausetEvent(fts))
  1332  			}
  1333  			it := chunk.NewIterator4Chunk(input)
  1334  			i := 0
  1335  			var vecWarnCnt uint16
  1336  			switch testCase.retEvalType {
  1337  			case types.ETInt:
  1338  				err := baseFunc.vecEvalInt(input, output)
  1339  				c.Assert(err, IsNil, Commentf("func: %v, case: %+v", baseFuncName, testCase))
  1340  				// do not forget to call ResizeXXX/ReserveXXX
  1341  				c.Assert(getDeferredCausetLen(output, testCase.retEvalType), Equals, input.NumEvents())
  1342  				vecWarnCnt = ctx.GetStochastikVars().StmtCtx.WarningCount()
  1343  				i64s := output.Int64s()
  1344  				for event := it.Begin(); event != it.End(); event = it.Next() {
  1345  					val, isNull, err := baseFunc.evalInt(event)
  1346  					c.Assert(err, IsNil, commentf(i))
  1347  					c.Assert(isNull, Equals, output.IsNull(i), commentf(i))
  1348  					if !isNull {
  1349  						c.Assert(val, Equals, i64s[i], commentf(i))
  1350  					}
  1351  					i++
  1352  				}
  1353  			case types.ETReal:
  1354  				err := baseFunc.vecEvalReal(input, output)
  1355  				c.Assert(err, IsNil, Commentf("func: %v, case: %+v", baseFuncName, testCase))
  1356  				// do not forget to call ResizeXXX/ReserveXXX
  1357  				c.Assert(getDeferredCausetLen(output, testCase.retEvalType), Equals, input.NumEvents())
  1358  				vecWarnCnt = ctx.GetStochastikVars().StmtCtx.WarningCount()
  1359  				f64s := output.Float64s()
  1360  				for event := it.Begin(); event != it.End(); event = it.Next() {
  1361  					val, isNull, err := baseFunc.evalReal(event)
  1362  					c.Assert(err, IsNil, commentf(i))
  1363  					c.Assert(isNull, Equals, output.IsNull(i), commentf(i))
  1364  					if !isNull {
  1365  						c.Assert(val, Equals, f64s[i], commentf(i))
  1366  					}
  1367  					i++
  1368  				}
  1369  			case types.ETDecimal:
  1370  				err := baseFunc.vecEvalDecimal(input, output)
  1371  				c.Assert(err, IsNil, Commentf("func: %v, case: %+v", baseFuncName, testCase))
  1372  				// do not forget to call ResizeXXX/ReserveXXX
  1373  				c.Assert(getDeferredCausetLen(output, testCase.retEvalType), Equals, input.NumEvents())
  1374  				vecWarnCnt = ctx.GetStochastikVars().StmtCtx.WarningCount()
  1375  				d64s := output.Decimals()
  1376  				for event := it.Begin(); event != it.End(); event = it.Next() {
  1377  					val, isNull, err := baseFunc.evalDecimal(event)
  1378  					c.Assert(err, IsNil, commentf(i))
  1379  					c.Assert(isNull, Equals, output.IsNull(i), commentf(i))
  1380  					if !isNull {
  1381  						c.Assert(*val, Equals, d64s[i], commentf(i))
  1382  					}
  1383  					i++
  1384  				}
  1385  			case types.ETDatetime, types.ETTimestamp:
  1386  				err := baseFunc.vecEvalTime(input, output)
  1387  				c.Assert(err, IsNil, Commentf("func: %v, case: %+v", baseFuncName, testCase))
  1388  				// do not forget to call ResizeXXX/ReserveXXX
  1389  				c.Assert(getDeferredCausetLen(output, testCase.retEvalType), Equals, input.NumEvents())
  1390  				vecWarnCnt = ctx.GetStochastikVars().StmtCtx.WarningCount()
  1391  				t64s := output.Times()
  1392  				for event := it.Begin(); event != it.End(); event = it.Next() {
  1393  					val, isNull, err := baseFunc.evalTime(event)
  1394  					c.Assert(err, IsNil, commentf(i))
  1395  					c.Assert(isNull, Equals, output.IsNull(i), commentf(i))
  1396  					if !isNull {
  1397  						c.Assert(val, Equals, t64s[i], commentf(i))
  1398  					}
  1399  					i++
  1400  				}
  1401  			case types.ETDuration:
  1402  				err := baseFunc.vecEvalDuration(input, output)
  1403  				c.Assert(err, IsNil, Commentf("func: %v, case: %+v", baseFuncName, testCase))
  1404  				// do not forget to call ResizeXXX/ReserveXXX
  1405  				c.Assert(getDeferredCausetLen(output, testCase.retEvalType), Equals, input.NumEvents())
  1406  				vecWarnCnt = ctx.GetStochastikVars().StmtCtx.WarningCount()
  1407  				d64s := output.GoDurations()
  1408  				for event := it.Begin(); event != it.End(); event = it.Next() {
  1409  					val, isNull, err := baseFunc.evalDuration(event)
  1410  					c.Assert(err, IsNil, commentf(i))
  1411  					c.Assert(isNull, Equals, output.IsNull(i), commentf(i))
  1412  					if !isNull {
  1413  						c.Assert(val.Duration, Equals, d64s[i], commentf(i))
  1414  					}
  1415  					i++
  1416  				}
  1417  			case types.ETJson:
  1418  				err := baseFunc.vecEvalJSON(input, output)
  1419  				c.Assert(err, IsNil, Commentf("func: %v, case: %+v", baseFuncName, testCase))
  1420  				// do not forget to call ResizeXXX/ReserveXXX
  1421  				c.Assert(getDeferredCausetLen(output, testCase.retEvalType), Equals, input.NumEvents())
  1422  				vecWarnCnt = ctx.GetStochastikVars().StmtCtx.WarningCount()
  1423  				for event := it.Begin(); event != it.End(); event = it.Next() {
  1424  					val, isNull, err := baseFunc.evalJSON(event)
  1425  					c.Assert(err, IsNil, commentf(i))
  1426  					c.Assert(isNull, Equals, output.IsNull(i), commentf(i))
  1427  					if !isNull {
  1428  						cmp := json.CompareBinary(val, output.GetJSON(i))
  1429  						c.Assert(cmp, Equals, 0, commentf(i))
  1430  					}
  1431  					i++
  1432  				}
  1433  			case types.ETString:
  1434  				err := baseFunc.vecEvalString(input, output)
  1435  				c.Assert(err, IsNil, Commentf("func: %v, case: %+v", baseFuncName, testCase))
  1436  				// do not forget to call ResizeXXX/ReserveXXX
  1437  				c.Assert(getDeferredCausetLen(output, testCase.retEvalType), Equals, input.NumEvents())
  1438  				vecWarnCnt = ctx.GetStochastikVars().StmtCtx.WarningCount()
  1439  				for event := it.Begin(); event != it.End(); event = it.Next() {
  1440  					val, isNull, err := baseFunc.evalString(event)
  1441  					c.Assert(err, IsNil, commentf(i))
  1442  					c.Assert(isNull, Equals, output.IsNull(i), commentf(i))
  1443  					if !isNull {
  1444  						c.Assert(val, Equals, output.GetString(i), commentf(i))
  1445  					}
  1446  					i++
  1447  				}
  1448  			default:
  1449  				c.Fatal(fmt.Sprintf("evalType=%v is not supported", testCase.retEvalType))
  1450  			}
  1451  
  1452  			// check warnings
  1453  			totalWarns := ctx.GetStochastikVars().StmtCtx.WarningCount()
  1454  			c.Assert(2*vecWarnCnt, Equals, totalWarns)
  1455  			warns := ctx.GetStochastikVars().StmtCtx.GetWarnings()
  1456  			for i := 0; i < int(vecWarnCnt); i++ {
  1457  				c.Assert(terror.ErrorEqual(warns[i].Err, warns[i+int(vecWarnCnt)].Err), IsTrue)
  1458  			}
  1459  		}
  1460  	}
  1461  }
  1462  
  1463  // testVectorizedBuiltinFuncForRand is used to verify that the vectorized
  1464  // memex is evaluated correctly
  1465  func testVectorizedBuiltinFuncForRand(c *C, vecExprCases vecExprBenchCases) {
  1466  	for funcName, testCases := range vecExprCases {
  1467  		c.Assert(strings.EqualFold("rand", funcName), Equals, true)
  1468  
  1469  		for _, testCase := range testCases {
  1470  			c.Assert(len(testCase.childrenTypes), Equals, 0)
  1471  
  1472  			ctx := mock.NewContext()
  1473  			baseFunc, _, input, output := genVecBuiltinFuncBenchCase(ctx, funcName, testCase)
  1474  			baseFuncName := fmt.Sprintf("%v", reflect.TypeOf(baseFunc))
  1475  			tmp := strings.Split(baseFuncName, ".")
  1476  			baseFuncName = tmp[len(tmp)-1]
  1477  			// do not forget to implement the vectorized method.
  1478  			c.Assert(baseFunc.vectorized(), IsTrue, Commentf("func: %v", baseFuncName))
  1479  			switch testCase.retEvalType {
  1480  			case types.ETReal:
  1481  				err := baseFunc.vecEvalReal(input, output)
  1482  				c.Assert(err, IsNil)
  1483  				// do not forget to call ResizeXXX/ReserveXXX
  1484  				c.Assert(getDeferredCausetLen(output, testCase.retEvalType), Equals, input.NumEvents())
  1485  				// check result
  1486  				res := output.Float64s()
  1487  				for _, v := range res {
  1488  					c.Assert((0 <= v) && (v < 1), Equals, true)
  1489  				}
  1490  			default:
  1491  				c.Fatal(fmt.Sprintf("evalType=%v is not supported", testCase.retEvalType))
  1492  			}
  1493  		}
  1494  	}
  1495  }
  1496  
  1497  // benchmarkVectorizedBuiltinFunc is used to get the effect of
  1498  // using the vectorized memex evaluations
  1499  func benchmarkVectorizedBuiltinFunc(b *testing.B, vecExprCases vecExprBenchCases) {
  1500  	ctx := mock.NewContext()
  1501  	testFunc := make(map[string]bool)
  1502  	argList := removeTestOptions(flag.Args())
  1503  	testAll := len(argList) == 0
  1504  	for _, arg := range argList {
  1505  		testFunc[arg] = true
  1506  	}
  1507  	for funcName, testCases := range vecExprCases {
  1508  		for _, testCase := range testCases {
  1509  			err := ctx.GetStochastikVars().SetSystemVar(variable.BlockEncryptionMode, testCase.aesModes)
  1510  			if err != nil {
  1511  				panic(err)
  1512  			}
  1513  			if funcName == ast.CurrentUser || funcName == ast.User {
  1514  				ctx.GetStochastikVars().User = &auth.UserIdentity{
  1515  					Username:     "milevadb",
  1516  					Hostname:     "localhost",
  1517  					CurrentUser:  true,
  1518  					AuthHostname: "localhost",
  1519  					AuthUsername: "milevadb",
  1520  				}
  1521  			}
  1522  			if funcName == ast.GetParam {
  1523  				testTime := time.Now()
  1524  				ctx.GetStochastikVars().PreparedParams = []types.Causet{
  1525  					types.NewIntCauset(1),
  1526  					types.NewDecimalCauset(types.NewDecFromStringForTest("20170118123950.123")),
  1527  					types.NewTimeCauset(types.NewTime(types.FromGoTime(testTime), allegrosql.TypeTimestamp, 6)),
  1528  					types.NewDurationCauset(types.ZeroDuration),
  1529  					types.NewStringCauset("{}"),
  1530  					types.NewBinaryLiteralCauset([]byte{1}),
  1531  					types.NewBytesCauset([]byte{'b'}),
  1532  					types.NewFloat32Causet(1.1),
  1533  					types.NewFloat64Causet(2.1),
  1534  					types.NewUintCauset(100),
  1535  					types.NewMysqlBitCauset([]byte{1}),
  1536  					types.NewMysqlEnumCauset(types.Enum{Name: "n", Value: 2}),
  1537  				}
  1538  			}
  1539  			baseFunc, _, input, output := genVecBuiltinFuncBenchCase(ctx, funcName, testCase)
  1540  			baseFuncName := fmt.Sprintf("%v", reflect.TypeOf(baseFunc))
  1541  			tmp := strings.Split(baseFuncName, ".")
  1542  			baseFuncName = tmp[len(tmp)-1]
  1543  
  1544  			if !testAll && testFunc[baseFuncName] != true && testFunc[funcName] != true {
  1545  				continue
  1546  			}
  1547  
  1548  			b.Run(baseFuncName+"-VecBuiltinFunc", func(b *testing.B) {
  1549  				b.ResetTimer()
  1550  				switch testCase.retEvalType {
  1551  				case types.ETInt:
  1552  					for i := 0; i < b.N; i++ {
  1553  						if err := baseFunc.vecEvalInt(input, output); err != nil {
  1554  							b.Fatal(err)
  1555  						}
  1556  					}
  1557  				case types.ETReal:
  1558  					for i := 0; i < b.N; i++ {
  1559  						if err := baseFunc.vecEvalReal(input, output); err != nil {
  1560  							b.Fatal(err)
  1561  						}
  1562  					}
  1563  				case types.ETDecimal:
  1564  					for i := 0; i < b.N; i++ {
  1565  						if err := baseFunc.vecEvalDecimal(input, output); err != nil {
  1566  							b.Fatal(err)
  1567  						}
  1568  					}
  1569  				case types.ETDatetime, types.ETTimestamp:
  1570  					for i := 0; i < b.N; i++ {
  1571  						if err := baseFunc.vecEvalTime(input, output); err != nil {
  1572  							b.Fatal(err)
  1573  						}
  1574  					}
  1575  				case types.ETDuration:
  1576  					for i := 0; i < b.N; i++ {
  1577  						if err := baseFunc.vecEvalDuration(input, output); err != nil {
  1578  							b.Fatal(err)
  1579  						}
  1580  					}
  1581  				case types.ETJson:
  1582  					for i := 0; i < b.N; i++ {
  1583  						if err := baseFunc.vecEvalJSON(input, output); err != nil {
  1584  							b.Fatal(err)
  1585  						}
  1586  					}
  1587  				case types.ETString:
  1588  					for i := 0; i < b.N; i++ {
  1589  						if err := baseFunc.vecEvalString(input, output); err != nil {
  1590  							b.Fatal(err)
  1591  						}
  1592  					}
  1593  				default:
  1594  					b.Fatal(fmt.Sprintf("evalType=%v is not supported", testCase.retEvalType))
  1595  				}
  1596  			})
  1597  			b.Run(baseFuncName+"-NonVecBuiltinFunc", func(b *testing.B) {
  1598  				b.ResetTimer()
  1599  				it := chunk.NewIterator4Chunk(input)
  1600  				switch testCase.retEvalType {
  1601  				case types.ETInt:
  1602  					for i := 0; i < b.N; i++ {
  1603  						output.Reset(testCase.retEvalType)
  1604  						for event := it.Begin(); event != it.End(); event = it.Next() {
  1605  							v, isNull, err := baseFunc.evalInt(event)
  1606  							if err != nil {
  1607  								b.Fatal(err)
  1608  							}
  1609  							if isNull {
  1610  								output.AppendNull()
  1611  							} else {
  1612  								output.AppendInt64(v)
  1613  							}
  1614  						}
  1615  					}
  1616  				case types.ETReal:
  1617  					for i := 0; i < b.N; i++ {
  1618  						output.Reset(testCase.retEvalType)
  1619  						for event := it.Begin(); event != it.End(); event = it.Next() {
  1620  							v, isNull, err := baseFunc.evalReal(event)
  1621  							if err != nil {
  1622  								b.Fatal(err)
  1623  							}
  1624  							if isNull {
  1625  								output.AppendNull()
  1626  							} else {
  1627  								output.AppendFloat64(v)
  1628  							}
  1629  						}
  1630  					}
  1631  				case types.ETDecimal:
  1632  					for i := 0; i < b.N; i++ {
  1633  						output.Reset(testCase.retEvalType)
  1634  						for event := it.Begin(); event != it.End(); event = it.Next() {
  1635  							v, isNull, err := baseFunc.evalDecimal(event)
  1636  							if err != nil {
  1637  								b.Fatal(err)
  1638  							}
  1639  							if isNull {
  1640  								output.AppendNull()
  1641  							} else {
  1642  								output.AppendMyDecimal(v)
  1643  							}
  1644  						}
  1645  					}
  1646  				case types.ETDatetime, types.ETTimestamp:
  1647  					for i := 0; i < b.N; i++ {
  1648  						output.Reset(testCase.retEvalType)
  1649  						for event := it.Begin(); event != it.End(); event = it.Next() {
  1650  							v, isNull, err := baseFunc.evalTime(event)
  1651  							if err != nil {
  1652  								b.Fatal(err)
  1653  							}
  1654  							if isNull {
  1655  								output.AppendNull()
  1656  							} else {
  1657  								output.AppendTime(v)
  1658  							}
  1659  						}
  1660  					}
  1661  				case types.ETDuration:
  1662  					for i := 0; i < b.N; i++ {
  1663  						output.Reset(testCase.retEvalType)
  1664  						for event := it.Begin(); event != it.End(); event = it.Next() {
  1665  							v, isNull, err := baseFunc.evalDuration(event)
  1666  							if err != nil {
  1667  								b.Fatal(err)
  1668  							}
  1669  							if isNull {
  1670  								output.AppendNull()
  1671  							} else {
  1672  								output.AppendDuration(v)
  1673  							}
  1674  						}
  1675  					}
  1676  				case types.ETJson:
  1677  					for i := 0; i < b.N; i++ {
  1678  						output.Reset(testCase.retEvalType)
  1679  						for event := it.Begin(); event != it.End(); event = it.Next() {
  1680  							v, isNull, err := baseFunc.evalJSON(event)
  1681  							if err != nil {
  1682  								b.Fatal(err)
  1683  							}
  1684  							if isNull {
  1685  								output.AppendNull()
  1686  							} else {
  1687  								output.AppendJSON(v)
  1688  							}
  1689  						}
  1690  					}
  1691  				case types.ETString:
  1692  					for i := 0; i < b.N; i++ {
  1693  						output.Reset(testCase.retEvalType)
  1694  						for event := it.Begin(); event != it.End(); event = it.Next() {
  1695  							v, isNull, err := baseFunc.evalString(event)
  1696  							if err != nil {
  1697  								b.Fatal(err)
  1698  							}
  1699  							if isNull {
  1700  								output.AppendNull()
  1701  							} else {
  1702  								output.AppendString(v)
  1703  							}
  1704  						}
  1705  					}
  1706  				default:
  1707  					b.Fatal(fmt.Sprintf("evalType=%v is not supported", testCase.retEvalType))
  1708  				}
  1709  			})
  1710  		}
  1711  	}
  1712  }
  1713  
  1714  func genVecEvalBool(numDefCauss int, defCausTypes, eTypes []types.EvalType) (CNFExprs, *chunk.Chunk) {
  1715  	gens := make([]dataGenerator, 0, len(eTypes))
  1716  	for _, eType := range eTypes {
  1717  		if eType == types.ETString {
  1718  			gens = append(gens, &numStrGener{*newRangeInt64Gener(0, 10)})
  1719  		} else {
  1720  			gens = append(gens, newDefaultGener(0.05, eType))
  1721  		}
  1722  	}
  1723  
  1724  	ts := make([]types.EvalType, 0, numDefCauss)
  1725  	gs := make([]dataGenerator, 0, numDefCauss)
  1726  	fts := make([]*types.FieldType, 0, numDefCauss)
  1727  	randGen := newDefaultRandGen()
  1728  	for i := 0; i < numDefCauss; i++ {
  1729  		idx := randGen.Intn(len(eTypes))
  1730  		if defCausTypes != nil {
  1731  			for j := range eTypes {
  1732  				if defCausTypes[i] == eTypes[j] {
  1733  					idx = j
  1734  					break
  1735  				}
  1736  			}
  1737  		}
  1738  		ts = append(ts, eTypes[idx])
  1739  		gs = append(gs, gens[idx])
  1740  		fts = append(fts, eType2FieldType(eTypes[idx]))
  1741  	}
  1742  
  1743  	input := chunk.New(fts, 1024, 1024)
  1744  	exprs := make(CNFExprs, 0, numDefCauss)
  1745  	for i := 0; i < numDefCauss; i++ {
  1746  		fillDeferredCauset(ts[i], input, i, vecExprBenchCase{geners: gs})
  1747  		exprs = append(exprs, &DeferredCauset{Index: i, RetType: fts[i]})
  1748  	}
  1749  	return exprs, input
  1750  }
  1751  
  1752  func generateRandomSel() []int {
  1753  	randGen := newDefaultRandGen()
  1754  	randGen.Seed(time.Now().UnixNano())
  1755  	var sel []int
  1756  	count := 0
  1757  	// Use constant 256 to make it faster to generate randomly arranged sel slices
  1758  	num := randGen.Intn(256) + 1
  1759  	existed := make([]bool, 1024)
  1760  	for i := 0; i < 1024; i++ {
  1761  		existed[i] = false
  1762  	}
  1763  	for count < num {
  1764  		val := randGen.Intn(1024)
  1765  		if !existed[val] {
  1766  			existed[val] = true
  1767  			count++
  1768  		}
  1769  	}
  1770  	for i := 0; i < 1024; i++ {
  1771  		if existed[i] {
  1772  			sel = append(sel, i)
  1773  		}
  1774  	}
  1775  	return sel
  1776  }
  1777  
  1778  func (s *testVectorizeSuite2) TestVecEvalBool(c *C) {
  1779  	ctx := mock.NewContext()
  1780  	eTypes := []types.EvalType{types.ETReal, types.ETDecimal, types.ETString, types.ETTimestamp, types.ETDatetime, types.ETDuration}
  1781  	for numDefCauss := 1; numDefCauss <= 5; numDefCauss++ {
  1782  		for round := 0; round < 16; round++ {
  1783  			exprs, input := genVecEvalBool(numDefCauss, nil, eTypes)
  1784  			selected, nulls, err := VecEvalBool(ctx, exprs, input, nil, nil)
  1785  			c.Assert(err, IsNil)
  1786  			it := chunk.NewIterator4Chunk(input)
  1787  			i := 0
  1788  			for event := it.Begin(); event != it.End(); event = it.Next() {
  1789  				ok, null, err := EvalBool(mock.NewContext(), exprs, event)
  1790  				c.Assert(err, IsNil)
  1791  				c.Assert(null, Equals, nulls[i])
  1792  				c.Assert(ok, Equals, selected[i])
  1793  				i++
  1794  			}
  1795  		}
  1796  	}
  1797  }
  1798  
  1799  func BenchmarkVecEvalBool(b *testing.B) {
  1800  	ctx := mock.NewContext()
  1801  	selected := make([]bool, 0, 1024)
  1802  	nulls := make([]bool, 0, 1024)
  1803  	eTypes := []types.EvalType{types.ETInt, types.ETReal, types.ETDecimal, types.ETString, types.ETTimestamp, types.ETDatetime, types.ETDuration}
  1804  	tNames := []string{"int", "real", "decimal", "string", "timestamp", "datetime", "duration"}
  1805  	for numDefCauss := 1; numDefCauss <= 2; numDefCauss++ {
  1806  		typeCombination := make([]types.EvalType, numDefCauss)
  1807  		var combFunc func(nDefCauss int)
  1808  		combFunc = func(nDefCauss int) {
  1809  			if nDefCauss == 0 {
  1810  				name := ""
  1811  				for _, t := range typeCombination {
  1812  					for i := range eTypes {
  1813  						if t == eTypes[i] {
  1814  							name += tNames[t] + "/"
  1815  						}
  1816  					}
  1817  				}
  1818  				exprs, input := genVecEvalBool(numDefCauss, typeCombination, eTypes)
  1819  				b.Run("Vec-"+name, func(b *testing.B) {
  1820  					b.ResetTimer()
  1821  					for i := 0; i < b.N; i++ {
  1822  						_, _, err := VecEvalBool(ctx, exprs, input, selected, nulls)
  1823  						if err != nil {
  1824  							b.Fatal(err)
  1825  						}
  1826  					}
  1827  				})
  1828  				b.Run("Event-"+name, func(b *testing.B) {
  1829  					b.ResetTimer()
  1830  					for i := 0; i < b.N; i++ {
  1831  						it := chunk.NewIterator4Chunk(input)
  1832  						for event := it.Begin(); event != it.End(); event = it.Next() {
  1833  							_, _, err := EvalBool(ctx, exprs, event)
  1834  							if err != nil {
  1835  								b.Fatal(err)
  1836  							}
  1837  						}
  1838  					}
  1839  				})
  1840  				return
  1841  			}
  1842  			for _, eType := range eTypes {
  1843  				typeCombination[nDefCauss-1] = eType
  1844  				combFunc(nDefCauss - 1)
  1845  			}
  1846  		}
  1847  
  1848  		combFunc(numDefCauss)
  1849  	}
  1850  }
  1851  
  1852  func (s *testVectorizeSuite2) TestEventBasedFilterAndVectorizedFilter(c *C) {
  1853  	ctx := mock.NewContext()
  1854  	eTypes := []types.EvalType{types.ETInt, types.ETReal, types.ETDecimal, types.ETString, types.ETTimestamp, types.ETDatetime, types.ETDuration}
  1855  	for numDefCauss := 1; numDefCauss <= 5; numDefCauss++ {
  1856  		for round := 0; round < 16; round++ {
  1857  			exprs, input := genVecEvalBool(numDefCauss, nil, eTypes)
  1858  			it := chunk.NewIterator4Chunk(input)
  1859  			isNull := make([]bool, it.Len())
  1860  			selected, nulls, err := rowBasedFilter(ctx, exprs, it, nil, isNull)
  1861  			c.Assert(err, IsNil)
  1862  			selected2, nulls2, err2 := vectorizedFilter(ctx, exprs, it, nil, isNull)
  1863  			c.Assert(err2, IsNil)
  1864  			length := it.Len()
  1865  			for i := 0; i < length; i++ {
  1866  				c.Assert(nulls2[i], Equals, nulls[i])
  1867  				c.Assert(selected2[i], Equals, selected[i])
  1868  			}
  1869  		}
  1870  	}
  1871  }
  1872  
  1873  func BenchmarkEventBasedFilterAndVectorizedFilter(b *testing.B) {
  1874  	ctx := mock.NewContext()
  1875  	selected := make([]bool, 0, 1024)
  1876  	nulls := make([]bool, 0, 1024)
  1877  	eTypes := []types.EvalType{types.ETInt, types.ETReal, types.ETDecimal, types.ETString, types.ETTimestamp, types.ETDatetime, types.ETDuration}
  1878  	tNames := []string{"int", "real", "decimal", "string", "timestamp", "datetime", "duration"}
  1879  	for numDefCauss := 1; numDefCauss <= 2; numDefCauss++ {
  1880  		typeCombination := make([]types.EvalType, numDefCauss)
  1881  		var combFunc func(nDefCauss int)
  1882  		combFunc = func(nDefCauss int) {
  1883  			if nDefCauss == 0 {
  1884  				name := ""
  1885  				for _, t := range typeCombination {
  1886  					for i := range eTypes {
  1887  						if t == eTypes[i] {
  1888  							name += tNames[t] + "/"
  1889  						}
  1890  					}
  1891  				}
  1892  				exprs, input := genVecEvalBool(numDefCauss, typeCombination, eTypes)
  1893  				it := chunk.NewIterator4Chunk(input)
  1894  				b.Run("Vec-"+name, func(b *testing.B) {
  1895  					b.ResetTimer()
  1896  					for i := 0; i < b.N; i++ {
  1897  						_, _, err := vectorizedFilter(ctx, exprs, it, selected, nulls)
  1898  						if err != nil {
  1899  							b.Fatal(err)
  1900  						}
  1901  					}
  1902  				})
  1903  				b.Run("Event-"+name, func(b *testing.B) {
  1904  					b.ResetTimer()
  1905  					for i := 0; i < b.N; i++ {
  1906  						_, _, err := rowBasedFilter(ctx, exprs, it, selected, nulls)
  1907  						if err != nil {
  1908  							b.Fatal(err)
  1909  						}
  1910  					}
  1911  				})
  1912  				return
  1913  			}
  1914  			for _, eType := range eTypes {
  1915  				typeCombination[nDefCauss-1] = eType
  1916  				combFunc(nDefCauss - 1)
  1917  			}
  1918  		}
  1919  		combFunc(numDefCauss)
  1920  	}
  1921  
  1922  	// Add special case to prove when some calculations are added,
  1923  	// the vectorizedFilter for int types will be more faster than rowBasedFilter.
  1924  	funcName := ast.Least
  1925  	testCase := vecExprBenchCase{retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETInt, types.ETInt}}
  1926  	expr, _, input, _ := genVecExprBenchCase(ctx, funcName, testCase)
  1927  	it := chunk.NewIterator4Chunk(input)
  1928  
  1929  	b.Run("Vec-special case", func(b *testing.B) {
  1930  		b.ResetTimer()
  1931  		for i := 0; i < b.N; i++ {
  1932  			_, _, err := vectorizedFilter(ctx, []Expression{expr}, it, selected, nulls)
  1933  			if err != nil {
  1934  				panic(err)
  1935  			}
  1936  		}
  1937  	})
  1938  	b.Run("Event-special case", func(b *testing.B) {
  1939  		b.ResetTimer()
  1940  		for i := 0; i < b.N; i++ {
  1941  			_, _, err := rowBasedFilter(ctx, []Expression{expr}, it, selected, nulls)
  1942  			if err != nil {
  1943  				panic(err)
  1944  			}
  1945  		}
  1946  	})
  1947  }
  1948  
  1949  func (s *testVectorizeSuite2) TestVectorizedFilterConsiderNull(c *C) {
  1950  	ctx := mock.NewContext()
  1951  	dafaultEnableVectorizedExpressionVar := ctx.GetStochastikVars().EnableVectorizedExpression
  1952  	eTypes := []types.EvalType{types.ETInt, types.ETReal, types.ETDecimal, types.ETString, types.ETTimestamp, types.ETDatetime, types.ETDuration}
  1953  	for numDefCauss := 1; numDefCauss <= 5; numDefCauss++ {
  1954  		for round := 0; round < 16; round++ {
  1955  			exprs, input := genVecEvalBool(numDefCauss, nil, eTypes)
  1956  			it := chunk.NewIterator4Chunk(input)
  1957  			isNull := make([]bool, it.Len())
  1958  			ctx.GetStochastikVars().EnableVectorizedExpression = false
  1959  			selected, nulls, err := VectorizedFilterConsiderNull(ctx, exprs, it, nil, isNull)
  1960  			c.Assert(err, IsNil)
  1961  			ctx.GetStochastikVars().EnableVectorizedExpression = true
  1962  			selected2, nulls2, err2 := VectorizedFilterConsiderNull(ctx, exprs, it, nil, isNull)
  1963  			c.Assert(err2, IsNil)
  1964  			length := it.Len()
  1965  			for i := 0; i < length; i++ {
  1966  				c.Assert(nulls2[i], Equals, nulls[i])
  1967  				c.Assert(selected2[i], Equals, selected[i])
  1968  			}
  1969  
  1970  			// add test which sel is not nil
  1971  			randomSel := generateRandomSel()
  1972  			input.SetSel(randomSel)
  1973  			it2 := chunk.NewIterator4Chunk(input)
  1974  			isNull = isNull[:0]
  1975  			ctx.GetStochastikVars().EnableVectorizedExpression = false
  1976  			selected3, nulls, err := VectorizedFilterConsiderNull(ctx, exprs, it2, nil, isNull)
  1977  			c.Assert(err, IsNil)
  1978  			ctx.GetStochastikVars().EnableVectorizedExpression = true
  1979  			selected4, nulls2, err2 := VectorizedFilterConsiderNull(ctx, exprs, it2, nil, isNull)
  1980  			c.Assert(err2, IsNil)
  1981  			for i := 0; i < length; i++ {
  1982  				c.Assert(nulls2[i], Equals, nulls[i])
  1983  				c.Assert(selected4[i], Equals, selected3[i])
  1984  			}
  1985  
  1986  			unselected := make([]bool, length)
  1987  			// unselected[i] == false means that the i-th event is selected
  1988  			for i := 0; i < length; i++ {
  1989  				unselected[i] = true
  1990  			}
  1991  			for _, idx := range randomSel {
  1992  				unselected[idx] = false
  1993  			}
  1994  			for i := range selected2 {
  1995  				if selected2[i] && unselected[i] {
  1996  					selected2[i] = false
  1997  				}
  1998  			}
  1999  			for i := 0; i < length; i++ {
  2000  				c.Assert(selected2[i], Equals, selected4[i])
  2001  			}
  2002  		}
  2003  	}
  2004  	ctx.GetStochastikVars().EnableVectorizedExpression = dafaultEnableVectorizedExpressionVar
  2005  }