github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/petri/acyclic/causet/implementation/datasource.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 "math" 18 19 causetembedded "github.com/whtcorpsinc/milevadb/causet/embedded" 20 "github.com/whtcorpsinc/milevadb/causet/memo" 21 "github.com/whtcorpsinc/milevadb/ekv" 22 "github.com/whtcorpsinc/milevadb/memex" 23 "github.com/whtcorpsinc/milevadb/statistics" 24 ) 25 26 // BlockDualImpl implementation of PhysicalBlockDual. 27 type BlockDualImpl struct { 28 baseImpl 29 } 30 31 // NewBlockDualImpl creates a new causet dual Implementation. 32 func NewBlockDualImpl(dual *causetembedded.PhysicalBlockDual) *BlockDualImpl { 33 return &BlockDualImpl{baseImpl{plan: dual}} 34 } 35 36 // CalcCost calculates the cost of the causet dual Implementation. 37 func (impl *BlockDualImpl) CalcCost(outCount float64, children ...memo.Implementation) float64 { 38 return 0 39 } 40 41 // MemBlockScanImpl implementation of PhysicalBlockDual. 42 type MemBlockScanImpl struct { 43 baseImpl 44 } 45 46 // NewMemBlockScanImpl creates a new causet dual Implementation. 47 func NewMemBlockScanImpl(dual *causetembedded.PhysicalMemBlock) *MemBlockScanImpl { 48 return &MemBlockScanImpl{baseImpl{plan: dual}} 49 } 50 51 // CalcCost calculates the cost of the causet dual Implementation. 52 func (impl *MemBlockScanImpl) CalcCost(outCount float64, children ...memo.Implementation) float64 { 53 return 0 54 } 55 56 // BlockReaderImpl implementation of PhysicalBlockReader. 57 type BlockReaderImpl struct { 58 baseImpl 59 tblDefCausHists *statistics.HistDefCausl 60 } 61 62 // NewBlockReaderImpl creates a new causet reader Implementation. 63 func NewBlockReaderImpl(reader *causetembedded.PhysicalBlockReader, hists *statistics.HistDefCausl) *BlockReaderImpl { 64 base := baseImpl{plan: reader} 65 impl := &BlockReaderImpl{ 66 baseImpl: base, 67 tblDefCausHists: hists, 68 } 69 return impl 70 } 71 72 // CalcCost calculates the cost of the causet reader Implementation. 73 func (impl *BlockReaderImpl) CalcCost(outCount float64, children ...memo.Implementation) float64 { 74 reader := impl.plan.(*causetembedded.PhysicalBlockReader) 75 width := impl.tblDefCausHists.GetAvgRowSize(impl.plan.SCtx(), reader.Schema().DeferredCausets, false, false) 76 sessVars := reader.SCtx().GetStochastikVars() 77 networkCost := outCount * sessVars.NetworkFactor * width 78 // CausetTasks are run in parallel, to make the estimated cost closer to execution time, we amortize 79 // the cost to cop iterator workers. According to `CopClient::Send`, the concurrency 80 // is Min(DistALLEGROSQLScanConcurrency, numRegionsInvolvedInScan), since we cannot infer 81 // the number of regions involved, we simply use DistALLEGROSQLScanConcurrency. 82 copIterWorkers := float64(sessVars.DistALLEGROSQLScanConcurrency()) 83 impl.cost = (networkCost + children[0].GetCost()) / copIterWorkers 84 return impl.cost 85 } 86 87 // GetCostLimit implements Implementation interface. 88 func (impl *BlockReaderImpl) GetCostLimit(costLimit float64, children ...memo.Implementation) float64 { 89 reader := impl.plan.(*causetembedded.PhysicalBlockReader) 90 sessVars := reader.SCtx().GetStochastikVars() 91 copIterWorkers := float64(sessVars.DistALLEGROSQLScanConcurrency()) 92 if math.MaxFloat64/copIterWorkers < costLimit { 93 return math.MaxFloat64 94 } 95 return costLimit * copIterWorkers 96 } 97 98 // BlockScanImpl implementation of PhysicalBlockScan. 99 type BlockScanImpl struct { 100 baseImpl 101 tblDefCausHists *statistics.HistDefCausl 102 tblDefCauss []*memex.DeferredCauset 103 } 104 105 // NewBlockScanImpl creates a new causet scan Implementation. 106 func NewBlockScanImpl(ts *causetembedded.PhysicalBlockScan, defcaus []*memex.DeferredCauset, hists *statistics.HistDefCausl) *BlockScanImpl { 107 base := baseImpl{plan: ts} 108 impl := &BlockScanImpl{ 109 baseImpl: base, 110 tblDefCausHists: hists, 111 tblDefCauss: defcaus, 112 } 113 return impl 114 } 115 116 // CalcCost calculates the cost of the causet scan Implementation. 117 func (impl *BlockScanImpl) CalcCost(outCount float64, children ...memo.Implementation) float64 { 118 ts := impl.plan.(*causetembedded.PhysicalBlockScan) 119 width := impl.tblDefCausHists.GetBlockAvgRowSize(impl.plan.SCtx(), impl.tblDefCauss, ekv.EinsteinDB, true) 120 sessVars := ts.SCtx().GetStochastikVars() 121 impl.cost = outCount * sessVars.ScanFactor * width 122 if ts.Desc { 123 impl.cost = outCount * sessVars.DescScanFactor * width 124 } 125 return impl.cost 126 } 127 128 // IndexReaderImpl is the implementation of PhysicalIndexReader. 129 type IndexReaderImpl struct { 130 baseImpl 131 tblDefCausHists *statistics.HistDefCausl 132 } 133 134 // GetCostLimit implements Implementation interface. 135 func (impl *IndexReaderImpl) GetCostLimit(costLimit float64, children ...memo.Implementation) float64 { 136 reader := impl.plan.(*causetembedded.PhysicalIndexReader) 137 sessVars := reader.SCtx().GetStochastikVars() 138 copIterWorkers := float64(sessVars.DistALLEGROSQLScanConcurrency()) 139 if math.MaxFloat64/copIterWorkers < costLimit { 140 return math.MaxFloat64 141 } 142 return costLimit * copIterWorkers 143 } 144 145 // CalcCost implements Implementation interface. 146 func (impl *IndexReaderImpl) CalcCost(outCount float64, children ...memo.Implementation) float64 { 147 reader := impl.plan.(*causetembedded.PhysicalIndexReader) 148 sessVars := reader.SCtx().GetStochastikVars() 149 networkCost := outCount * sessVars.NetworkFactor * impl.tblDefCausHists.GetAvgRowSize(reader.SCtx(), children[0].GetCauset().Schema().DeferredCausets, true, false) 150 copIterWorkers := float64(sessVars.DistALLEGROSQLScanConcurrency()) 151 impl.cost = (networkCost + children[0].GetCost()) / copIterWorkers 152 return impl.cost 153 } 154 155 // NewIndexReaderImpl creates a new IndexReader Implementation. 156 func NewIndexReaderImpl(reader *causetembedded.PhysicalIndexReader, tblDefCausHists *statistics.HistDefCausl) *IndexReaderImpl { 157 return &IndexReaderImpl{ 158 baseImpl: baseImpl{plan: reader}, 159 tblDefCausHists: tblDefCausHists, 160 } 161 } 162 163 // IndexScanImpl is the Implementation of PhysicalIndexScan. 164 type IndexScanImpl struct { 165 baseImpl 166 tblDefCausHists *statistics.HistDefCausl 167 } 168 169 // CalcCost implements Implementation interface. 170 func (impl *IndexScanImpl) CalcCost(outCount float64, children ...memo.Implementation) float64 { 171 is := impl.plan.(*causetembedded.PhysicalIndexScan) 172 sessVars := is.SCtx().GetStochastikVars() 173 rowSize := impl.tblDefCausHists.GetIndexAvgRowSize(is.SCtx(), is.Schema().DeferredCausets, is.Index.Unique) 174 cost := outCount * rowSize * sessVars.ScanFactor 175 if is.Desc { 176 cost = outCount * rowSize * sessVars.DescScanFactor 177 } 178 cost += float64(len(is.Ranges)) * sessVars.SeekFactor 179 impl.cost = cost 180 return impl.cost 181 } 182 183 // NewIndexScanImpl creates a new IndexScan Implementation. 184 func NewIndexScanImpl(scan *causetembedded.PhysicalIndexScan, tblDefCausHists *statistics.HistDefCausl) *IndexScanImpl { 185 return &IndexScanImpl{ 186 baseImpl: baseImpl{plan: scan}, 187 tblDefCausHists: tblDefCausHists, 188 } 189 }