github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/opt/opbench/spec.go (about) 1 // Copyright 2019 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package opbench 12 13 import ( 14 "regexp" 15 "sort" 16 "strings" 17 ) 18 19 // Spec defines a single parameterized Plan which we would like to 20 // benchmark. 21 // A Spec has "parameters", which are values that get substituted into 22 // the Plan, and "inputs", which are the values from which the parameters 23 // are derived. These might differ in cases like where a Spec 24 // must scan tables of different widths, and the "input" is the width 25 // of the table, and the "parameter" is the name of the table that is 26 // scanned. 27 type Spec struct { 28 // Name is the title of spec. It is what determines the filename of 29 // this spec's results. 30 Name string 31 32 // Plan is the parameterized exprgen Plan, with each parameter prefixed with 33 // a $. 34 Plan string 35 36 // Inputs is the set of possible inputs, along with a set of potential values 37 // for each. This allows enumerating all combinations. 38 Inputs []Options 39 40 // GetParam maps the name of a parameter to its value, given 41 // the configuration. 42 GetParam func(string, Configuration) string 43 } 44 45 // paramRegex matches parameters in a Plan (words prefixed with a $). 46 var paramRegex = regexp.MustCompile(`\$[a-zA-Z_]+`) 47 48 // getParams extracts all the $dollarsign prefixed parameters from the spec's 49 // Plan, sorting and deduplicating them. 50 func (s *Spec) getParams() []string { 51 paramRefs := paramRegex.FindAllString(s.Plan, -1) 52 // Sort them for deduplication. 53 sort.Strings(paramRefs) 54 result := make([]string, 0, len(paramRefs)) 55 last := "" 56 for i := 0; i < len(paramRefs); i++ { 57 if last != paramRefs[i] { 58 // Get rid of the leading $. 59 next := paramRefs[i][1:] 60 result = append(result, next) 61 last = paramRefs[i] 62 } 63 } 64 return result 65 } 66 67 // InputNames returns a slice of the names of the inputs to the spec. 68 func (s *Spec) InputNames() []string { 69 var result []string 70 for _, i := range s.Inputs { 71 result = append(result, i.Field) 72 } 73 return result 74 } 75 76 // FillInParams returns the Spec's Plan with parameters filled 77 // in with respect to the given configuration. 78 func (s *Spec) FillInParams(c Configuration) string { 79 // Replace all the parameters in the Plan with their values. 80 text := s.Plan 81 params := s.getParams() 82 for _, k := range params { 83 text = strings.Replace(text, "$"+k, s.GetParam(k, c), -1) 84 } 85 86 return text 87 }