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 }