github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/schema.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 memex
    15  
    16  import (
    17  	"strings"
    18  )
    19  
    20  // KeyInfo stores the defCausumns of one unique key or primary key.
    21  type KeyInfo []*DeferredCauset
    22  
    23  // Clone copies the entire UniqueKey.
    24  func (ki KeyInfo) Clone() KeyInfo {
    25  	result := make([]*DeferredCauset, 0, len(ki))
    26  	for _, defCaus := range ki {
    27  		result = append(result, defCaus.Clone().(*DeferredCauset))
    28  	}
    29  	return result
    30  }
    31  
    32  // Schema stands for the event schemaReplicant and unique key information get from input.
    33  type Schema struct {
    34  	DeferredCausets []*DeferredCauset
    35  	Keys    []KeyInfo
    36  }
    37  
    38  // String implements fmt.Stringer interface.
    39  func (s *Schema) String() string {
    40  	defCausStrs := make([]string, 0, len(s.DeferredCausets))
    41  	for _, defCaus := range s.DeferredCausets {
    42  		defCausStrs = append(defCausStrs, defCaus.String())
    43  	}
    44  	ukStrs := make([]string, 0, len(s.Keys))
    45  	for _, key := range s.Keys {
    46  		ukDefCausStrs := make([]string, 0, len(key))
    47  		for _, defCaus := range key {
    48  			ukDefCausStrs = append(ukDefCausStrs, defCaus.String())
    49  		}
    50  		ukStrs = append(ukStrs, "["+strings.Join(ukDefCausStrs, ",")+"]")
    51  	}
    52  	return "DeferredCauset: [" + strings.Join(defCausStrs, ",") + "] Unique key: [" + strings.Join(ukStrs, ",") + "]"
    53  }
    54  
    55  // Clone copies the total schemaReplicant.
    56  func (s *Schema) Clone() *Schema {
    57  	defcaus := make([]*DeferredCauset, 0, s.Len())
    58  	keys := make([]KeyInfo, 0, len(s.Keys))
    59  	for _, defCaus := range s.DeferredCausets {
    60  		defcaus = append(defcaus, defCaus.Clone().(*DeferredCauset))
    61  	}
    62  	for _, key := range s.Keys {
    63  		keys = append(keys, key.Clone())
    64  	}
    65  	schemaReplicant := NewSchema(defcaus...)
    66  	schemaReplicant.SetUniqueKeys(keys)
    67  	return schemaReplicant
    68  }
    69  
    70  // ExprFromSchema checks if all defCausumns of this memex are from the same schemaReplicant.
    71  func ExprFromSchema(expr Expression, schemaReplicant *Schema) bool {
    72  	switch v := expr.(type) {
    73  	case *DeferredCauset:
    74  		return schemaReplicant.Contains(v)
    75  	case *ScalarFunction:
    76  		for _, arg := range v.GetArgs() {
    77  			if !ExprFromSchema(arg, schemaReplicant) {
    78  				return false
    79  			}
    80  		}
    81  		return true
    82  	case *CorrelatedDeferredCauset, *Constant:
    83  		return true
    84  	}
    85  	return false
    86  }
    87  
    88  // RetrieveDeferredCauset retrieves defCausumn in memex from the defCausumns in schemaReplicant.
    89  func (s *Schema) RetrieveDeferredCauset(defCaus *DeferredCauset) *DeferredCauset {
    90  	index := s.DeferredCausetIndex(defCaus)
    91  	if index != -1 {
    92  		return s.DeferredCausets[index]
    93  	}
    94  	return nil
    95  }
    96  
    97  // IsUniqueKey checks if this defCausumn is a unique key.
    98  func (s *Schema) IsUniqueKey(defCaus *DeferredCauset) bool {
    99  	for _, key := range s.Keys {
   100  		if len(key) == 1 && key[0].Equal(nil, defCaus) {
   101  			return true
   102  		}
   103  	}
   104  	return false
   105  }
   106  
   107  // DeferredCausetIndex finds the index for a defCausumn.
   108  func (s *Schema) DeferredCausetIndex(defCaus *DeferredCauset) int {
   109  	for i, c := range s.DeferredCausets {
   110  		if c.UniqueID == defCaus.UniqueID {
   111  			return i
   112  		}
   113  	}
   114  	return -1
   115  }
   116  
   117  // Contains checks if the schemaReplicant contains the defCausumn.
   118  func (s *Schema) Contains(defCaus *DeferredCauset) bool {
   119  	return s.DeferredCausetIndex(defCaus) != -1
   120  }
   121  
   122  // Len returns the number of defCausumns in schemaReplicant.
   123  func (s *Schema) Len() int {
   124  	return len(s.DeferredCausets)
   125  }
   126  
   127  // Append append new defCausumn to the defCausumns stored in schemaReplicant.
   128  func (s *Schema) Append(defCaus ...*DeferredCauset) {
   129  	s.DeferredCausets = append(s.DeferredCausets, defCaus...)
   130  }
   131  
   132  // SetUniqueKeys will set the value of Schema.Keys.
   133  func (s *Schema) SetUniqueKeys(keys []KeyInfo) {
   134  	s.Keys = keys
   135  }
   136  
   137  // DeferredCausetsIndices will return a slice which contains the position of each defCausumn in schemaReplicant.
   138  // If there is one defCausumn that doesn't match, nil will be returned.
   139  func (s *Schema) DeferredCausetsIndices(defcaus []*DeferredCauset) (ret []int) {
   140  	ret = make([]int, 0, len(defcaus))
   141  	for _, defCaus := range defcaus {
   142  		pos := s.DeferredCausetIndex(defCaus)
   143  		if pos != -1 {
   144  			ret = append(ret, pos)
   145  		} else {
   146  			return nil
   147  		}
   148  	}
   149  	return
   150  }
   151  
   152  // DeferredCausetsByIndices returns defCausumns by multiple offsets.
   153  // Callers should guarantee that all the offsets provided should be valid, which means offset should:
   154  // 1. not smaller than 0, and
   155  // 2. not exceed len(s.DeferredCausets)
   156  func (s *Schema) DeferredCausetsByIndices(offsets []int) []*DeferredCauset {
   157  	defcaus := make([]*DeferredCauset, 0, len(offsets))
   158  	for _, offset := range offsets {
   159  		defcaus = append(defcaus, s.DeferredCausets[offset])
   160  	}
   161  	return defcaus
   162  }
   163  
   164  // ExtractDefCausGroups checks if defCausumn groups are from current schemaReplicant, and returns
   165  // offsets of those satisfied defCausumn groups.
   166  func (s *Schema) ExtractDefCausGroups(defCausGroups [][]*DeferredCauset) ([][]int, []int) {
   167  	if len(defCausGroups) == 0 {
   168  		return nil, nil
   169  	}
   170  	extracted := make([][]int, 0, len(defCausGroups))
   171  	offsets := make([]int, 0, len(defCausGroups))
   172  	for i, g := range defCausGroups {
   173  		if j := s.DeferredCausetsIndices(g); j != nil {
   174  			extracted = append(extracted, j)
   175  			offsets = append(offsets, i)
   176  		}
   177  	}
   178  	return extracted, offsets
   179  }
   180  
   181  // MergeSchema will merge two schemaReplicant into one schemaReplicant. We shouldn't need to consider unique keys.
   182  // That will be processed in build_key_info.go.
   183  func MergeSchema(lSchema, rSchema *Schema) *Schema {
   184  	if lSchema == nil && rSchema == nil {
   185  		return nil
   186  	}
   187  	if lSchema == nil {
   188  		return rSchema.Clone()
   189  	}
   190  	if rSchema == nil {
   191  		return lSchema.Clone()
   192  	}
   193  	tmpL := lSchema.Clone()
   194  	tmpR := rSchema.Clone()
   195  	ret := NewSchema(append(tmpL.DeferredCausets, tmpR.DeferredCausets...)...)
   196  	return ret
   197  }
   198  
   199  // GetUsedList shows whether each defCausumn in schemaReplicant is contained in usedDefCauss.
   200  func GetUsedList(usedDefCauss []*DeferredCauset, schemaReplicant *Schema) []bool {
   201  	tmpSchema := NewSchema(usedDefCauss...)
   202  	used := make([]bool, schemaReplicant.Len())
   203  	for i, defCaus := range schemaReplicant.DeferredCausets {
   204  		used[i] = tmpSchema.Contains(defCaus)
   205  	}
   206  	return used
   207  }
   208  
   209  // NewSchema returns a schemaReplicant made by its parameter.
   210  func NewSchema(defcaus ...*DeferredCauset) *Schema {
   211  	return &Schema{DeferredCausets: defcaus}
   212  }