github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/generator/other_vec.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  // +build ignore
    15  
    16  package main
    17  
    18  import (
    19  	"bytes"
    20  	"go/format"
    21  	"io/ioutil"
    22  	"log"
    23  	"path/filepath"
    24  	"text/template"
    25  
    26  	. "github.com/whtcorpsinc/milevadb/memex/generator/helper"
    27  )
    28  
    29  const header = `// Copyright 2020 WHTCORPS INC, Inc.
    30  //
    31  // Licensed under the Apache License, Version 2.0 (the "License");
    32  // you may not use this file except in compliance with the License.
    33  // You may obtain a copy of the License at
    34  //
    35  //     http://www.apache.org/licenses/LICENSE-2.0
    36  //
    37  // Unless required by applicable law or agreed to in writing, software
    38  // distributed under the License is distributed on an "AS IS" BASIS,
    39  // See the License for the specific language governing permissions and
    40  // limitations under the License.
    41  
    42  // Code generated by go generate in memex/generator; DO NOT EDIT.
    43  
    44  package memex
    45  `
    46  
    47  const newLine = "\n"
    48  
    49  const builtinOtherImports = `import (
    50  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    51  	"github.com/whtcorpsinc/milevadb/types"
    52  	"github.com/whtcorpsinc/milevadb/types/json"
    53  	"github.com/whtcorpsinc/milevadb/soliton/chunk"
    54  	"github.com/whtcorpsinc/milevadb/soliton/defCauslate"
    55  )
    56  `
    57  
    58  var builtinInTmpl = template.Must(template.New("builtinInTmpl").Parse(`
    59  {{ define "BufSlabPredictor" }}
    60  	buf0, err := b.bufSlabPredictor.get(types.ET{{ .Input.ETName }}, n)
    61  	if err != nil {
    62  		return err
    63  	}
    64  	defer b.bufSlabPredictor.put(buf0)
    65  	if err := b.args[0].VecEval{{ .Input.TypeName }}(b.ctx, input, buf0); err != nil {
    66  		return err
    67  	}
    68  	buf1, err := b.bufSlabPredictor.get(types.ET{{ .Input.ETName }}, n)
    69  	if err != nil {
    70  		return err
    71  	}
    72  	defer b.bufSlabPredictor.put(buf1)
    73  {{ end }}
    74  {{ define "SetHasNull" }}
    75  	for i := 0; i < n; i++ {
    76  		if result.IsNull(i) {
    77  			result.SetNull(i, hasNull[i])
    78  		}
    79  	}
    80  	return nil
    81  {{ end }}
    82  {{ define "Compare" }}
    83  	{{ if eq .Input.TypeName "Int" -}}
    84  		compareResult = 1
    85  		switch {
    86  			case (isUnsigned0 && isUnsigned), (!isUnsigned0 && !isUnsigned):
    87  				if arg1 == arg0 {
    88  					compareResult = 0
    89  				}
    90  			case !isUnsigned0 && isUnsigned:
    91  				if arg0 >= 0 && arg1 == arg0 {
    92  					compareResult = 0
    93  				}
    94  			case isUnsigned0 && !isUnsigned:
    95  				if arg1 >= 0 && arg1 == arg0 {
    96  					compareResult = 0
    97  				}
    98  		}
    99  	{{- else if eq .Input.TypeName "Decimal" -}}
   100  		compareResult = 1
   101  		if arg0.Compare(&arg1) == 0 {
   102  			compareResult = 0
   103  		}
   104  	{{- else if eq .Input.TypeName "Time" -}}
   105  		compareResult = arg0.Compare(arg1)
   106  	{{- else if eq .Input.TypeName "Duration" -}}
   107  		compareResult = types.CompareDuration(arg0, arg1)
   108  	{{- else if eq .Input.TypeName "JSON" -}}
   109  		compareResult = json.CompareBinary(arg0, arg1)
   110  	{{- else if eq .Input.TypeName "String" -}}
   111  		compareResult = types.CompareString(arg0, arg1, b.defCauslation)
   112  	{{- else -}}
   113  		compareResult = types.Compare{{ .Input.TypeNameInDeferredCauset }}(arg0, arg1)
   114  	{{- end -}}
   115  {{ end }}
   116  
   117  {{ range . }}
   118  {{ $InputInt := (eq .Input.TypeName "Int") }}
   119  {{ $InputJSON := (eq .Input.TypeName "JSON")}}
   120  {{ $InputString := (eq .Input.TypeName "String") }}
   121  {{ $InputFixed := ( .Input.Fixed ) }}
   122  {{ $UseHashKey := ( or (eq .Input.TypeName "Decimal") (eq .Input.TypeName "JSON") )}}
   123  func (b *{{.SigName}}) vecEvalInt(input *chunk.Chunk, result *chunk.DeferredCauset) error {
   124  	n := input.NumEvents()
   125  	{{- template "BufSlabPredictor" . }}
   126  	{{- if $InputFixed }}
   127  		args0 := buf0.{{.Input.TypeNameInDeferredCauset}}s()
   128  	{{- end }}
   129  	result.ResizeInt64(n, true)
   130  	r64s := result.Int64s()
   131  	for i:=0; i<n; i++ {
   132  		r64s[i] = 0
   133  	}
   134  	hasNull := make([]bool, n)
   135  	{{- if not $InputJSON}}
   136  	if b.hasNull {
   137  		for i := 0; i < n; i++ {
   138  			hasNull[i] = true
   139  		}
   140  	}
   141  	{{- end }}
   142  	{{- if $InputInt }}
   143  		isUnsigned0 := allegrosql.HasUnsignedFlag(b.args[0].GetType().Flag)
   144  	{{- end }}
   145  	var compareResult int
   146  	args := b.args
   147  	{{- if not $InputJSON}}
   148  	if len(b.hashSet) != 0 {
   149  		{{- if $InputString }}
   150  			defCauslator := defCauslate.GetDefCauslator(b.defCauslation)
   151  		{{- end }}
   152  		args = b.nonConstArgs
   153  		for i := 0; i < n; i++ {
   154  			if buf0.IsNull(i) {
   155  				hasNull[i] = true
   156  				continue
   157  			}
   158  			{{- if $InputInt }}
   159  				arg0 := args0[i]
   160  				if isUnsigned, ok := b.hashSet[arg0]; ok {
   161  					if (isUnsigned0 && isUnsigned) || (!isUnsigned0 && !isUnsigned) {
   162  						r64s[i] = 1
   163  						result.SetNull(i, false)
   164  					}
   165  					if arg0 >= 0 {
   166  						r64s[i] = 1
   167  						result.SetNull(i, false)
   168  					}
   169  				}
   170  			{{- else }}
   171  				{{- if $InputFixed }}
   172  					arg0 := args0[i]
   173  				{{- else }}
   174  					arg0 := buf0.Get{{ .Input.TypeName }}(i)
   175  				{{- end }}
   176  
   177  				{{- if $UseHashKey }}
   178  					key, err := arg0.ToHashKey()
   179  					if err != nil{
   180  						return err
   181  					}
   182  					if _, ok := b.hashSet[string(key)]; ok {
   183  						r64s[i] = 1
   184  						result.SetNull(i, false)
   185  					}
   186  				{{- else if $InputString }}
   187  					if _, ok := b.hashSet[string(defCauslator.Key(arg0))]; ok {
   188  						r64s[i] = 1
   189  						result.SetNull(i, false)
   190  					}
   191  				{{- else }}
   192  					if _, ok := b.hashSet[arg0]; ok {
   193  						r64s[i] = 1
   194  						result.SetNull(i, false)
   195  					}
   196  				{{- end }}
   197  			{{- end }}
   198  		}
   199  	}
   200  	{{- end }}
   201  
   202  	for j := 1; j < len(args); j++ {
   203  		if err := args[j].VecEval{{ .Input.TypeName }}(b.ctx, input, buf1); err != nil {
   204  			return err
   205  		}
   206  		{{- if $InputInt }}
   207  			isUnsigned := allegrosql.HasUnsignedFlag(args[j].GetType().Flag)
   208  		{{- end }}
   209  		{{- if $InputFixed }}
   210  			args1 := buf1.{{.Input.TypeNameInDeferredCauset}}s()
   211  			buf1.MergeNulls(buf0)
   212  		{{- end }}
   213  		for i := 0; i < n; i++ {
   214  			if r64s[i] != 0 {
   215  				continue
   216  			}
   217  {{- /* if is null */}}
   218  			if buf1.IsNull(i) {{- if not $InputFixed -}} || buf0.IsNull(i) {{- end -}} {
   219  				hasNull[i] = true
   220  				continue
   221  			}
   222  
   223  {{- /* get args */}}
   224  			{{- if $InputFixed }}
   225  				arg0 := args0[i]
   226  				arg1 := args1[i]
   227  			{{- else }}
   228  				arg0 := buf0.Get{{ .Input.TypeName }}(i)
   229  				arg1 := buf1.Get{{ .Input.TypeName }}(i)
   230  			{{- end }}
   231  
   232  {{- /* compare */}}
   233  			{{- template "Compare" . }}
   234  			if compareResult == 0 {
   235  				result.SetNull(i, false)
   236  				r64s[i] = 1
   237  			}
   238  		} // for i
   239  	} // for j
   240  	{{- template "SetHasNull" . -}}
   241  }
   242  
   243  func (b *{{.SigName}}) vectorized() bool {
   244  	return true
   245  }
   246  {{ end }}{{/* range */}}
   247  `))
   248  
   249  var testFile = template.Must(template.New("").Parse(`// Copyright 2020 WHTCORPS INC, Inc.
   250  //
   251  // Licensed under the Apache License, Version 2.0 (the "License");
   252  // you may not use this file except in compliance with the License.
   253  // You may obtain a copy of the License at
   254  //
   255  //     http://www.apache.org/licenses/LICENSE-2.0
   256  //
   257  // Unless required by applicable law or agreed to in writing, software
   258  // distributed under the License is distributed on an "AS IS" BASIS,
   259  // See the License for the specific language governing permissions and
   260  // limitations under the License.
   261  
   262  // Code generated by go generate in memex/generator; DO NOT EDIT.
   263  
   264  package memex
   265  
   266  import (
   267  	"fmt"
   268  	"math/rand"
   269  	"testing"
   270  	"time"
   271  
   272  	. "github.com/whtcorpsinc/check"
   273  	"github.com/whtcorpsinc/BerolinaSQL/ast"
   274  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
   275  	"github.com/whtcorpsinc/milevadb/types"
   276  	"github.com/whtcorpsinc/milevadb/types/json"
   277  )
   278  
   279  type inGener struct {
   280  	defaultGener
   281  }
   282  
   283  func (g inGener) gen() interface{} {
   284  	if rand.Float64() < g.nullRation {
   285  		return nil
   286  	}
   287  	randNum := rand.Int63n(10)
   288  	switch g.eType {
   289  	case types.ETInt:
   290  		if rand.Float64() < 0.5 {
   291  			return -randNum
   292  		}
   293  		return randNum
   294  	case types.ETReal:
   295  		if rand.Float64() < 0.5 {
   296  			return -float64(randNum)
   297  		}
   298  		return float64(randNum)
   299  	case types.ETDecimal:
   300  		d := new(types.MyDecimal)
   301  		f := float64(randNum * 100000)
   302  		if err := d.FromFloat64(f); err != nil {
   303  			panic(err)
   304  		}
   305  		return d
   306  	case types.ETDatetime, types.ETTimestamp:
   307  		gt := types.FromDate(2020, 11, 2, 22, 00, int(randNum), rand.Intn(1000000))
   308  		t := types.NewTime(gt, convertETType(g.eType), 0)
   309  		return t
   310  	case types.ETDuration:
   311  		return types.Duration{ Duration: time.Duration(randNum) }
   312  	case types.ETJson:
   313  		j := new(json.BinaryJSON)
   314  		jsonStr := fmt.Sprintf("{\"key\":%v}", randNum)
   315  		if err := j.UnmarshalJSON([]byte(jsonStr)); err != nil {
   316  			panic(err)
   317  		}
   318  		return *j
   319  	case types.ETString:
   320  		return fmt.Sprint(randNum)
   321  	}
   322  	return randNum
   323  }
   324  
   325  {{/* Add more test cases here if we have more functions in this file */}}
   326  var vecBuiltin{{ .Category }}GeneratedCases = map[string][]vecExprBenchCase {
   327  {{- range $.Functions }}
   328  	ast.{{ .FuncName }}: {
   329  	{{- range .Sigs }}
   330  		// {{ .SigName }}
   331  		{
   332  			retEvalType: types.ET{{ .Output.ETName }},
   333  			childrenTypes: []types.EvalType{
   334  				types.ET{{ .Input.ETName }},
   335  				types.ET{{ .Input.ETName }},
   336  				types.ET{{ .Input.ETName }},
   337  				types.ET{{ .Input.ETName }},
   338  			},
   339  			geners: []dataGenerator{
   340  				inGener{*newDefaultGener(0.2, types.ET{{.Input.ETName}})},
   341  				inGener{*newDefaultGener(0.2, types.ET{{.Input.ETName}})},
   342  				inGener{*newDefaultGener(0.2, types.ET{{.Input.ETName}})},
   343  				inGener{*newDefaultGener(0.2, types.ET{{.Input.ETName}})},
   344  			},
   345  		},
   346  	{{- end }}
   347  	{{- range .Sigs }}
   348  		// {{ .SigName }} with const arguments
   349  		{
   350  			retEvalType: types.ET{{ .Output.ETName }},
   351  			childrenTypes: []types.EvalType{
   352  				types.ET{{ .Input.ETName }},
   353  				types.ET{{ .Input.ETName }}, types.ET{{ .Input.ETName }},
   354  			},
   355  			constants: []*Constant{
   356  				nil,
   357  				{{- if eq .Input.ETName "Int" }}
   358  					{Value: types.NewCauset(1), RetType: types.NewFieldType(allegrosql.TypeInt24)},
   359  					{Value: types.NewCauset(2), RetType: types.NewFieldType(allegrosql.TypeInt24)},
   360  				{{- end }}
   361  				{{- if eq .Input.ETName "String" }}
   362  					{Value: types.NewStringCauset("aaaa"), RetType: types.NewFieldType(allegrosql.TypeString)},
   363  					{Value: types.NewStringCauset("bbbb"), RetType: types.NewFieldType(allegrosql.TypeString)},
   364  				{{- end }}
   365  				{{- if eq .Input.ETName "Datetime" }}
   366  					{Value: types.NewTimeCauset(dateTimeFromString("2020-01-01")), RetType: types.NewFieldType(allegrosql.TypeDatetime)},
   367  					{Value: types.NewTimeCauset(dateTimeFromString("2020-01-01")), RetType: types.NewFieldType(allegrosql.TypeDatetime)},
   368  				{{- end }}
   369  				{{- if eq .Input.ETName "Json" }}
   370  					{Value: types.NewJSONCauset(json.CreateBinary("aaaa")), RetType: types.NewFieldType(allegrosql.TypeJSON)},
   371  					{Value: types.NewJSONCauset(json.CreateBinary("bbbb")), RetType: types.NewFieldType(allegrosql.TypeJSON)},
   372  				{{- end }}
   373  				{{- if eq .Input.ETName "Duration" }}
   374  					{Value: types.NewDurationCauset(types.Duration{Duration: time.Duration(1000)}), RetType: types.NewFieldType(allegrosql.TypeDuration)},
   375  					{Value: types.NewDurationCauset(types.Duration{Duration: time.Duration(2000)}), RetType: types.NewFieldType(allegrosql.TypeDuration)},
   376  				{{- end }}
   377  				{{- if eq .Input.ETName "Real" }}
   378  					{Value: types.NewFloat64Causet(0.1), RetType: types.NewFieldType(allegrosql.TypeFloat)},
   379  					{Value: types.NewFloat64Causet(0.2), RetType: types.NewFieldType(allegrosql.TypeFloat)},
   380  				{{- end }}
   381  				{{- if eq .Input.ETName "Decimal" }}
   382  					{Value: types.NewDecimalCauset(types.NewDecFromInt(10)), RetType: types.NewFieldType(allegrosql.TypeNewDecimal)},
   383  					{Value: types.NewDecimalCauset(types.NewDecFromInt(20)), RetType: types.NewFieldType(allegrosql.TypeNewDecimal)},
   384  				{{- end }}
   385  			},
   386  		},
   387  	{{- end }}
   388  {{- end }}
   389  	},
   390  }
   391  
   392  func (s *testEvaluatorSuite) TestVectorizedBuiltin{{.Category}}EvalOneVecGenerated(c *C) {
   393  	testVectorizedEvalOneVec(c, vecBuiltin{{.Category}}GeneratedCases)
   394  }
   395  
   396  func (s *testEvaluatorSuite) TestVectorizedBuiltin{{.Category}}FuncGenerated(c *C) {
   397  	testVectorizedBuiltinFunc(c, vecBuiltin{{.Category}}GeneratedCases)
   398  }
   399  
   400  func BenchmarkVectorizedBuiltin{{.Category}}EvalOneVecGenerated(b *testing.B) {
   401  	benchmarkVectorizedEvalOneVec(b, vecBuiltin{{.Category}}GeneratedCases)
   402  }
   403  
   404  func BenchmarkVectorizedBuiltin{{.Category}}FuncGenerated(b *testing.B) {
   405  	benchmarkVectorizedBuiltinFunc(b, vecBuiltin{{.Category}}GeneratedCases)
   406  }
   407  `))
   408  
   409  type sig struct {
   410  	SigName       string
   411  	Input, Output TypeContext
   412  }
   413  
   414  var inSigsTmpl = []sig{
   415  	{SigName: "builtinInIntSig", Input: TypeInt, Output: TypeInt},
   416  	{SigName: "builtinInStringSig", Input: TypeString, Output: TypeInt},
   417  	{SigName: "builtinInDecimalSig", Input: TypeDecimal, Output: TypeInt},
   418  	{SigName: "builtinInRealSig", Input: TypeReal, Output: TypeInt},
   419  	{SigName: "builtinInTimeSig", Input: TypeDatetime, Output: TypeInt},
   420  	{SigName: "builtinInDurationSig", Input: TypeDuration, Output: TypeInt},
   421  	{SigName: "builtinInJSONSig", Input: TypeJSON, Output: TypeInt},
   422  }
   423  
   424  type function struct {
   425  	FuncName string
   426  	Sigs     []sig
   427  }
   428  
   429  var tmplVal = struct {
   430  	Category  string
   431  	Functions []function
   432  }{
   433  	Category: "Other",
   434  	Functions: []function{
   435  		{FuncName: "In", Sigs: inSigsTmpl},
   436  	},
   437  }
   438  
   439  func generateDotGo(fileName string) error {
   440  	w := new(bytes.Buffer)
   441  	w.WriteString(header)
   442  	w.WriteString(newLine)
   443  	w.WriteString(builtinOtherImports)
   444  	err := builtinInTmpl.InterDircute(w, inSigsTmpl)
   445  	if err != nil {
   446  		return err
   447  	}
   448  	data, err := format.Source(w.Bytes())
   449  	if err != nil {
   450  		log.Println("[Warn]", fileName+": gofmt failed", err)
   451  		data = w.Bytes() // write original data for debugging
   452  	}
   453  	return ioutil.WriteFile(fileName, data, 0644)
   454  }
   455  
   456  func generateTestDotGo(fileName string) error {
   457  	w := new(bytes.Buffer)
   458  	err := testFile.InterDircute(w, tmplVal)
   459  	if err != nil {
   460  		return err
   461  	}
   462  	data, err := format.Source(w.Bytes())
   463  	if err != nil {
   464  		log.Println("[Warn]", fileName+": gofmt failed", err)
   465  		data = w.Bytes() // write original data for debugging
   466  	}
   467  	return ioutil.WriteFile(fileName, data, 0644)
   468  }
   469  
   470  // generateOneFile generate one xxx.go file and the associated xxx_test.go file.
   471  func generateOneFile(fileNamePrefix string) (err error) {
   472  	err = generateDotGo(fileNamePrefix + ".go")
   473  	if err != nil {
   474  		return
   475  	}
   476  	err = generateTestDotGo(fileNamePrefix + "_test.go")
   477  	return
   478  }
   479  
   480  func main() {
   481  	var err error
   482  	outputDir := "."
   483  	err = generateOneFile(filepath.Join(outputDir, "builtin_other_vec_generated"))
   484  	if err != nil {
   485  		log.Fatalln("generateOneFile", err)
   486  	}
   487  }