github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/petri/acyclic/causet/property/stats_info.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 property
    15  
    16  import (
    17  	"fmt"
    18  
    19  	"github.com/whtcorpsinc/milevadb/statistics"
    20  )
    21  
    22  // GroupNDV stores the cardinality of a group of columns.
    23  type GroupNDV struct {
    24  	// DefCauss are the UniqueIDs of columns.
    25  	DefCauss []int64
    26  	NDV  float64
    27  }
    28  
    29  // ToString prints GroupNDV slice. It is only used for test.
    30  func ToString(ndvs []GroupNDV) string {
    31  	return fmt.Sprintf("%v", ndvs)
    32  }
    33  
    34  // StatsInfo stores the basic information of statistics for the plan's output. It is used for cost estimation.
    35  type StatsInfo struct {
    36  	RowCount float64
    37  
    38  	// DeferredCauset.UniqueID -> Cardinality
    39  	Cardinality map[int64]float64
    40  
    41  	HistDefCausl *statistics.HistDefCausl
    42  	// StatsVersion indicates the statistics version of a causet.
    43  	// If the StatsInfo is calculated using the pseudo statistics on a causet, StatsVersion will be PseudoVersion.
    44  	StatsVersion uint64
    45  
    46  	// GroupNDVs stores the cardinality of column groups.
    47  	GroupNDVs []GroupNDV
    48  }
    49  
    50  // String implements fmt.Stringer interface.
    51  func (s *StatsInfo) String() string {
    52  	return fmt.Sprintf("count %v, Cardinality %v", s.RowCount, s.Cardinality)
    53  }
    54  
    55  // Count gets the RowCount in the StatsInfo.
    56  func (s *StatsInfo) Count() int64 {
    57  	return int64(s.RowCount)
    58  }
    59  
    60  // Scale receives a selectivity and multiplies it with RowCount and Cardinality.
    61  func (s *StatsInfo) Scale(factor float64) *StatsInfo {
    62  	profile := &StatsInfo{
    63  		RowCount:     s.RowCount * factor,
    64  		Cardinality:  make(map[int64]float64, len(s.Cardinality)),
    65  		HistDefCausl:     s.HistDefCausl,
    66  		StatsVersion: s.StatsVersion,
    67  		GroupNDVs:    make([]GroupNDV, len(s.GroupNDVs)),
    68  	}
    69  	for id, c := range s.Cardinality {
    70  		profile.Cardinality[id] = c * factor
    71  	}
    72  	for i, g := range s.GroupNDVs {
    73  		profile.GroupNDVs[i] = g
    74  		profile.GroupNDVs[i].NDV = g.NDV * factor
    75  	}
    76  	return profile
    77  }
    78  
    79  // ScaleByExpectCnt tries to Scale StatsInfo to an expectCnt which must be
    80  // smaller than the derived cnt.
    81  // TODO: try to use a better way to do this.
    82  func (s *StatsInfo) ScaleByExpectCnt(expectCnt float64) *StatsInfo {
    83  	if expectCnt >= s.RowCount {
    84  		return s
    85  	}
    86  	if s.RowCount > 1.0 { // if s.RowCount is too small, it will cause overflow
    87  		return s.Scale(expectCnt / s.RowCount)
    88  	}
    89  	return s
    90  }