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 }