github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/petri/acyclic/causet/embedded/stringer.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 cascades 15 16 import ( 17 "bytes" 18 "fmt" 19 "strings" 20 21 "github.com/whtcorpsinc/milevadb/causet/memo" 22 ) 23 24 // ToString stringifies a Group Tree. 25 func ToString(g *memo.Group) []string { 26 idMap := make(map[*memo.Group]int) 27 idMap[g] = 0 28 return toString(g, idMap, map[*memo.Group]struct{}{}, []string{}) 29 } 30 31 // toString recursively stringifies a Group Tree using a preorder traversal method. 32 func toString(g *memo.Group, idMap map[*memo.Group]int, visited map[*memo.Group]struct{}, strs []string) []string { 33 if _, exists := visited[g]; exists { 34 return strs 35 } 36 visited[g] = struct{}{} 37 // Add new Groups to idMap. 38 for item := g.Equivalents.Front(); item != nil; item = item.Next() { 39 expr := item.Value.(*memo.GroupExpr) 40 for _, childGroup := range expr.Children { 41 if _, exists := idMap[childGroup]; !exists { 42 idMap[childGroup] = len(idMap) 43 } 44 } 45 } 46 // Visit self first. 47 strs = append(strs, groupToString(g, idMap)...) 48 // Visit children then. 49 for item := g.Equivalents.Front(); item != nil; item = item.Next() { 50 expr := item.Value.(*memo.GroupExpr) 51 for _, childGroup := range expr.Children { 52 strs = toString(childGroup, idMap, visited, strs) 53 } 54 } 55 return strs 56 } 57 58 // groupToString only stringifies a single Group. 59 // Format: 60 // Group#1 DeferredCauset: [DeferredCauset#1,DeferredCauset#2,DeferredCauset#13] Unique key: [] 61 // Selection_4 input:[Group#2], eq(DeferredCauset#13, DeferredCauset#2), gt(DeferredCauset#1, 10) 62 // Projection_15 input:Group#3 DeferredCauset#1, DeferredCauset#2 63 func groupToString(g *memo.Group, idMap map[*memo.Group]int) []string { 64 schemaReplicant := g.Prop.Schema 65 defCausStrs := make([]string, 0, len(schemaReplicant.DeferredCausets)) 66 for _, defCaus := range schemaReplicant.DeferredCausets { 67 defCausStrs = append(defCausStrs, defCaus.String()) 68 } 69 70 groupLine := bytes.NewBufferString("") 71 fmt.Fprintf(groupLine, "Group#%d Schema:[%s]", idMap[g], strings.Join(defCausStrs, ",")) 72 73 if len(g.Prop.Schema.Keys) > 0 { 74 ukStrs := make([]string, 0, len(schemaReplicant.Keys)) 75 for _, key := range schemaReplicant.Keys { 76 ukDefCausStrs := make([]string, 0, len(key)) 77 for _, defCaus := range key { 78 ukDefCausStrs = append(ukDefCausStrs, defCaus.String()) 79 } 80 ukStrs = append(ukStrs, strings.Join(ukDefCausStrs, ",")) 81 } 82 fmt.Fprintf(groupLine, ", UniqueKey:[%s]", strings.Join(ukStrs, ",")) 83 } 84 85 result := make([]string, 0, g.Equivalents.Len()+1) 86 result = append(result, groupLine.String()) 87 for item := g.Equivalents.Front(); item != nil; item = item.Next() { 88 expr := item.Value.(*memo.GroupExpr) 89 result = append(result, " "+groupExprToString(expr, idMap)) 90 } 91 return result 92 } 93 94 // groupExprToString stringifies a groupExpr(or a LogicalCauset). 95 // Format: 96 // Selection_13 input:Group#2 gt(DeferredCauset#1, DeferredCauset#4) 97 func groupExprToString(expr *memo.GroupExpr, idMap map[*memo.Group]int) string { 98 buffer := bytes.NewBufferString(expr.ExprNode.ExplainID().String()) 99 if len(expr.Children) == 0 { 100 fmt.Fprintf(buffer, " %s", expr.ExprNode.ExplainInfo()) 101 } else { 102 fmt.Fprintf(buffer, " %s", getChildrenGroupID(expr, idMap)) 103 explainInfo := expr.ExprNode.ExplainInfo() 104 if len(explainInfo) != 0 { 105 fmt.Fprintf(buffer, ", %s", explainInfo) 106 } 107 } 108 return buffer.String() 109 } 110 111 func getChildrenGroupID(expr *memo.GroupExpr, idMap map[*memo.Group]int) string { 112 children := make([]string, 0, len(expr.Children)) 113 for _, child := range expr.Children { 114 children = append(children, fmt.Sprintf("Group#%d", idMap[child])) 115 } 116 return "input:[" + strings.Join(children, ",") + "]" 117 }