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  }