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  }