github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/petri/acyclic/causet/implementation/simple_plans.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 implementation
    15  
    16  import (
    17  	causetembedded "github.com/whtcorpsinc/milevadb/causet/embedded"
    18  	"github.com/whtcorpsinc/milevadb/causet/memo"
    19  )
    20  
    21  // ProjectionImpl is the implementation of PhysicalProjection.
    22  type ProjectionImpl struct {
    23  	baseImpl
    24  }
    25  
    26  // NewProjectionImpl creates a new projection Implementation.
    27  func NewProjectionImpl(proj *causetembedded.PhysicalProjection) *ProjectionImpl {
    28  	return &ProjectionImpl{baseImpl{plan: proj}}
    29  }
    30  
    31  // CalcCost implements Implementation CalcCost interface.
    32  func (impl *ProjectionImpl) CalcCost(outCount float64, children ...memo.Implementation) float64 {
    33  	proj := impl.plan.(*causetembedded.PhysicalProjection)
    34  	impl.cost = proj.GetCost(children[0].GetCauset().Stats().RowCount) + children[0].GetCost()
    35  	return impl.cost
    36  }
    37  
    38  // ShowImpl is the Implementation of PhysicalShow.
    39  type ShowImpl struct {
    40  	baseImpl
    41  }
    42  
    43  // NewShowImpl creates a new ShowImpl.
    44  func NewShowImpl(show *causetembedded.PhysicalShow) *ShowImpl {
    45  	return &ShowImpl{baseImpl: baseImpl{plan: show}}
    46  }
    47  
    48  // MilevaDBSelectionImpl is the implementation of PhysicalSelection in MilevaDB layer.
    49  type MilevaDBSelectionImpl struct {
    50  	baseImpl
    51  }
    52  
    53  // CalcCost implements Implementation CalcCost interface.
    54  func (sel *MilevaDBSelectionImpl) CalcCost(outCount float64, children ...memo.Implementation) float64 {
    55  	sel.cost = children[0].GetCauset().Stats().RowCount*sel.plan.SCtx().GetStochastikVars().CPUFactor + children[0].GetCost()
    56  	return sel.cost
    57  }
    58  
    59  // NewMilevaDBSelectionImpl creates a new MilevaDBSelectionImpl.
    60  func NewMilevaDBSelectionImpl(sel *causetembedded.PhysicalSelection) *MilevaDBSelectionImpl {
    61  	return &MilevaDBSelectionImpl{baseImpl{plan: sel}}
    62  }
    63  
    64  // EinsteinDBSelectionImpl is the implementation of PhysicalSelection in EinsteinDB layer.
    65  type EinsteinDBSelectionImpl struct {
    66  	baseImpl
    67  }
    68  
    69  // CalcCost implements Implementation CalcCost interface.
    70  func (sel *EinsteinDBSelectionImpl) CalcCost(outCount float64, children ...memo.Implementation) float64 {
    71  	sel.cost = children[0].GetCauset().Stats().RowCount*sel.plan.SCtx().GetStochastikVars().CopCPUFactor + children[0].GetCost()
    72  	return sel.cost
    73  }
    74  
    75  // NewEinsteinDBSelectionImpl creates a new EinsteinDBSelectionImpl.
    76  func NewEinsteinDBSelectionImpl(sel *causetembedded.PhysicalSelection) *EinsteinDBSelectionImpl {
    77  	return &EinsteinDBSelectionImpl{baseImpl{plan: sel}}
    78  }
    79  
    80  // MilevaDBHashAggImpl is the implementation of PhysicalHashAgg in MilevaDB layer.
    81  type MilevaDBHashAggImpl struct {
    82  	baseImpl
    83  }
    84  
    85  // CalcCost implements Implementation CalcCost interface.
    86  func (agg *MilevaDBHashAggImpl) CalcCost(outCount float64, children ...memo.Implementation) float64 {
    87  	hashAgg := agg.plan.(*causetembedded.PhysicalHashAgg)
    88  	selfCost := hashAgg.GetCost(children[0].GetCauset().Stats().RowCount, true)
    89  	agg.cost = selfCost + children[0].GetCost()
    90  	return agg.cost
    91  }
    92  
    93  // AttachChildren implements Implementation AttachChildren interface.
    94  func (agg *MilevaDBHashAggImpl) AttachChildren(children ...memo.Implementation) memo.Implementation {
    95  	hashAgg := agg.plan.(*causetembedded.PhysicalHashAgg)
    96  	hashAgg.SetChildren(children[0].GetCauset())
    97  	return agg
    98  }
    99  
   100  // NewMilevaDBHashAggImpl creates a new MilevaDBHashAggImpl.
   101  func NewMilevaDBHashAggImpl(agg *causetembedded.PhysicalHashAgg) *MilevaDBHashAggImpl {
   102  	return &MilevaDBHashAggImpl{baseImpl{plan: agg}}
   103  }
   104  
   105  // EinsteinDBHashAggImpl is the implementation of PhysicalHashAgg in EinsteinDB layer.
   106  type EinsteinDBHashAggImpl struct {
   107  	baseImpl
   108  }
   109  
   110  // CalcCost implements Implementation CalcCost interface.
   111  func (agg *EinsteinDBHashAggImpl) CalcCost(outCount float64, children ...memo.Implementation) float64 {
   112  	hashAgg := agg.plan.(*causetembedded.PhysicalHashAgg)
   113  	selfCost := hashAgg.GetCost(children[0].GetCauset().Stats().RowCount, false)
   114  	agg.cost = selfCost + children[0].GetCost()
   115  	return agg.cost
   116  }
   117  
   118  // NewEinsteinDBHashAggImpl creates a new EinsteinDBHashAggImpl.
   119  func NewEinsteinDBHashAggImpl(agg *causetembedded.PhysicalHashAgg) *EinsteinDBHashAggImpl {
   120  	return &EinsteinDBHashAggImpl{baseImpl{plan: agg}}
   121  }
   122  
   123  // LimitImpl is the implementation of PhysicalLimit. Since PhysicalLimit on different
   124  // engines have the same behavior, and we don't calculate the cost of `Limit`, we only
   125  // have one Implementation for it.
   126  type LimitImpl struct {
   127  	baseImpl
   128  }
   129  
   130  // NewLimitImpl creates a new LimitImpl.
   131  func NewLimitImpl(limit *causetembedded.PhysicalLimit) *LimitImpl {
   132  	return &LimitImpl{baseImpl{plan: limit}}
   133  }
   134  
   135  // MilevaDBTopNImpl is the implementation of PhysicalTopN in MilevaDB layer.
   136  type MilevaDBTopNImpl struct {
   137  	baseImpl
   138  }
   139  
   140  // CalcCost implements Implementation CalcCost interface.
   141  func (impl *MilevaDBTopNImpl) CalcCost(outCount float64, children ...memo.Implementation) float64 {
   142  	topN := impl.plan.(*causetembedded.PhysicalTopN)
   143  	childCount := children[0].GetCauset().Stats().RowCount
   144  	impl.cost = topN.GetCost(childCount, true) + children[0].GetCost()
   145  	return impl.cost
   146  }
   147  
   148  // NewMilevaDBTopNImpl creates a new MilevaDBTopNImpl.
   149  func NewMilevaDBTopNImpl(topN *causetembedded.PhysicalTopN) *MilevaDBTopNImpl {
   150  	return &MilevaDBTopNImpl{baseImpl{plan: topN}}
   151  }
   152  
   153  // EinsteinDBTopNImpl is the implementation of PhysicalTopN in EinsteinDB layer.
   154  type EinsteinDBTopNImpl struct {
   155  	baseImpl
   156  }
   157  
   158  // CalcCost implements Implementation CalcCost interface.
   159  func (impl *EinsteinDBTopNImpl) CalcCost(outCount float64, children ...memo.Implementation) float64 {
   160  	topN := impl.plan.(*causetembedded.PhysicalTopN)
   161  	childCount := children[0].GetCauset().Stats().RowCount
   162  	impl.cost = topN.GetCost(childCount, false) + children[0].GetCost()
   163  	return impl.cost
   164  }
   165  
   166  // NewEinsteinDBTopNImpl creates a new EinsteinDBTopNImpl.
   167  func NewEinsteinDBTopNImpl(topN *causetembedded.PhysicalTopN) *EinsteinDBTopNImpl {
   168  	return &EinsteinDBTopNImpl{baseImpl{plan: topN}}
   169  }
   170  
   171  // UnionAllImpl is the implementation of PhysicalUnionAll.
   172  type UnionAllImpl struct {
   173  	baseImpl
   174  }
   175  
   176  // CalcCost implements Implementation CalcCost interface.
   177  func (impl *UnionAllImpl) CalcCost(outCount float64, children ...memo.Implementation) float64 {
   178  	var childMaxCost float64
   179  	for _, child := range children {
   180  		childCost := child.GetCost()
   181  		if childCost > childMaxCost {
   182  			childMaxCost = childCost
   183  		}
   184  	}
   185  	selfCost := float64(1+len(children)) * impl.plan.SCtx().GetStochastikVars().ConcurrencyFactor
   186  	// Children of UnionAll are executed in parallel.
   187  	impl.cost = selfCost + childMaxCost
   188  	return impl.cost
   189  }
   190  
   191  // GetCostLimit implements Implementation interface.
   192  func (impl *UnionAllImpl) GetCostLimit(costLimit float64, children ...memo.Implementation) float64 {
   193  	return costLimit
   194  }
   195  
   196  // NewUnionAllImpl creates a new UnionAllImpl.
   197  func NewUnionAllImpl(union *causetembedded.PhysicalUnionAll) *UnionAllImpl {
   198  	return &UnionAllImpl{baseImpl{plan: union}}
   199  }
   200  
   201  // ApplyImpl is the implementation of PhysicalApply.
   202  type ApplyImpl struct {
   203  	baseImpl
   204  }
   205  
   206  // CalcCost implements Implementation CalcCost interface.
   207  func (impl *ApplyImpl) CalcCost(outCount float64, children ...memo.Implementation) float64 {
   208  	apply := impl.plan.(*causetembedded.PhysicalApply)
   209  	impl.cost = apply.GetCost(
   210  		children[0].GetCauset().Stats().RowCount,
   211  		children[1].GetCauset().Stats().RowCount,
   212  		children[0].GetCost(),
   213  		children[1].GetCost())
   214  	return impl.cost
   215  }
   216  
   217  // GetCostLimit implements Implementation GetCostLimit interface.
   218  func (impl *ApplyImpl) GetCostLimit(costLimit float64, children ...memo.Implementation) float64 {
   219  	if len(children) == 0 {
   220  		return costLimit
   221  	}
   222  	// The Cost of Apply is: selfCost + leftCost + leftCount * rightCost.
   223  	// If we have implemented the leftChild, the costLimit for the right
   224  	// side should be (costLimit - selfCost - leftCost)/leftCount. Since
   225  	// we haven't implement the rightChild, we cannot calculate the `selfCost`.
   226  	// So we just use (costLimit - leftCost)/leftCount here.
   227  	leftCount, leftCost := children[0].GetCauset().Stats().RowCount, children[0].GetCost()
   228  	apply := impl.plan.(*causetembedded.PhysicalApply)
   229  	if len(apply.LeftConditions) > 0 {
   230  		leftCount *= causetembedded.SelectionFactor
   231  	}
   232  	return (costLimit - leftCost) / leftCount
   233  }
   234  
   235  // NewApplyImpl creates a new ApplyImpl.
   236  func NewApplyImpl(apply *causetembedded.PhysicalApply) *ApplyImpl {
   237  	return &ApplyImpl{baseImpl{plan: apply}}
   238  }
   239  
   240  // MaxOneRowImpl is the implementation of PhysicalApply.
   241  type MaxOneRowImpl struct {
   242  	baseImpl
   243  }
   244  
   245  // CalcCost implements Implementation CalcCost interface.
   246  func (impl *MaxOneRowImpl) CalcCost(outCount float64, children ...memo.Implementation) float64 {
   247  	impl.cost = children[0].GetCost()
   248  	return impl.cost
   249  }
   250  
   251  // NewMaxOneRowImpl creates a new MaxOneRowImpl.
   252  func NewMaxOneRowImpl(maxOneRow *causetembedded.PhysicalMaxOneRow) *MaxOneRowImpl {
   253  	return &MaxOneRowImpl{baseImpl{plan: maxOneRow}}
   254  }
   255  
   256  // WindowImpl is the implementation of PhysicalWindow.
   257  type WindowImpl struct {
   258  	baseImpl
   259  }
   260  
   261  // NewWindowImpl creates a new WindowImpl.
   262  func NewWindowImpl(window *causetembedded.PhysicalWindow) *WindowImpl {
   263  	return &WindowImpl{baseImpl{plan: window}}
   264  }
   265  
   266  // CalcCost implements Implementation CalcCost interface.
   267  func (impl *WindowImpl) CalcCost(outCount float64, children ...memo.Implementation) float64 {
   268  	impl.cost = children[0].GetCost()
   269  	return impl.cost
   270  }