github.com/matrixorigin/matrixone@v1.2.0/pkg/partition/partition.go (about)

     1  // Copyright 2021 Matrix Origin
     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  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package partition
    16  
    17  import (
    18  	"bytes"
    19  
    20  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    21  	"github.com/matrixorigin/matrixone/pkg/container/nulls"
    22  	"github.com/matrixorigin/matrixone/pkg/container/types"
    23  	"github.com/matrixorigin/matrixone/pkg/container/vector"
    24  )
    25  
    26  func genericPartition[T types.FixedSizeT](sels []int64, diffs []bool, partitions []int64, vec *vector.Vector) []int64 {
    27  	partitions = partitions[:0]
    28  	if len(sels) == 0 {
    29  		return partitions
    30  	}
    31  	diffs[0] = true
    32  	diffs = diffs[:len(sels)]
    33  
    34  	if vec.IsConst() {
    35  		if vec.IsConstNull() {
    36  			for i := range sels {
    37  				diffs[i] = false
    38  			}
    39  		}
    40  		partitions = append(partitions, 0)
    41  
    42  	} else {
    43  		var n bool
    44  		var v T
    45  
    46  		vs := vector.MustFixedCol[T](vec)
    47  		nsp := vec.GetNulls()
    48  		if nsp.Any() {
    49  			for i, sel := range sels {
    50  				w := vs[sel]
    51  				isNull := nulls.Contains(nsp, uint64(sel))
    52  				if n != isNull {
    53  					diffs[i] = true
    54  				} else if n && isNull {
    55  					diffs[i] = false
    56  				} else {
    57  					diffs[i] = diffs[i] || (v != vs[sel])
    58  				}
    59  				n = isNull
    60  				v = w
    61  			}
    62  		} else {
    63  			for i, sel := range sels {
    64  				w := vs[sel]
    65  				diffs[i] = diffs[i] || (v != w)
    66  				v = w
    67  			}
    68  		}
    69  
    70  		for i, j := int64(0), int64(len(diffs)); i < j; i++ {
    71  			if diffs[i] {
    72  				partitions = append(partitions, i)
    73  			}
    74  		}
    75  	}
    76  
    77  	return partitions
    78  }
    79  
    80  func bytesPartition(sels []int64, diffs []bool, partitions []int64, vec *vector.Vector) []int64 {
    81  	partitions = partitions[:0]
    82  	if len(sels) == 0 {
    83  		return partitions
    84  	}
    85  	diffs[0] = true
    86  	diffs = diffs[:len(sels)]
    87  
    88  	if vec.IsConst() {
    89  		if vec.IsConstNull() {
    90  			for i := range sels {
    91  				diffs[i] = false
    92  			}
    93  		}
    94  		partitions = append(partitions, 0)
    95  
    96  	} else {
    97  		var n bool
    98  		var v []byte
    99  
   100  		vs := vector.MustBytesCol(vec)
   101  		nsp := vec.GetNulls()
   102  		if nsp.Any() {
   103  			for i, sel := range sels {
   104  				w := vs[sel]
   105  				isNull := nulls.Contains(nsp, uint64(sel))
   106  				if n != isNull {
   107  					diffs[i] = true
   108  				} else if n && isNull {
   109  					diffs[i] = false
   110  				} else {
   111  					diffs[i] = diffs[i] || !(bytes.Equal(v, vs[sel]))
   112  				}
   113  				n = isNull
   114  				v = w
   115  			}
   116  		} else {
   117  			for i, sel := range sels {
   118  				w := vs[sel]
   119  				diffs[i] = diffs[i] || !(bytes.Equal(v, w))
   120  				v = w
   121  			}
   122  		}
   123  		for i, j := int64(0), int64(len(diffs)); i < j; i++ {
   124  			if diffs[i] {
   125  				partitions = append(partitions, i)
   126  			}
   127  		}
   128  	}
   129  
   130  	return partitions
   131  }
   132  
   133  // Partitions will return the rowSels; vs[rowSel] != vs[last_rowSel].
   134  // by default, the 0th row is always not equal to the one before it
   135  // (though it doesn't exist)
   136  func Partition(sels []int64, diffs []bool, partitions []int64, vec *vector.Vector) []int64 {
   137  	switch vec.GetType().Oid {
   138  	case types.T_bool:
   139  		return genericPartition[bool](sels, diffs, partitions, vec)
   140  	case types.T_bit:
   141  		return genericPartition[uint64](sels, diffs, partitions, vec)
   142  	case types.T_int8:
   143  		return genericPartition[int8](sels, diffs, partitions, vec)
   144  	case types.T_int16:
   145  		return genericPartition[int16](sels, diffs, partitions, vec)
   146  	case types.T_int32:
   147  		return genericPartition[int32](sels, diffs, partitions, vec)
   148  	case types.T_int64:
   149  		return genericPartition[int64](sels, diffs, partitions, vec)
   150  	case types.T_uint8:
   151  		return genericPartition[uint8](sels, diffs, partitions, vec)
   152  	case types.T_uint16:
   153  		return genericPartition[uint16](sels, diffs, partitions, vec)
   154  	case types.T_uint32:
   155  		return genericPartition[uint32](sels, diffs, partitions, vec)
   156  	case types.T_uint64:
   157  		return genericPartition[uint64](sels, diffs, partitions, vec)
   158  	case types.T_float32:
   159  		return genericPartition[float32](sels, diffs, partitions, vec)
   160  	case types.T_float64:
   161  		return genericPartition[float64](sels, diffs, partitions, vec)
   162  	case types.T_date:
   163  		return genericPartition[types.Date](sels, diffs, partitions, vec)
   164  	case types.T_datetime:
   165  		return genericPartition[types.Datetime](sels, diffs, partitions, vec)
   166  	case types.T_time:
   167  		return genericPartition[types.Time](sels, diffs, partitions, vec)
   168  	case types.T_timestamp:
   169  		return genericPartition[types.Timestamp](sels, diffs, partitions, vec)
   170  	case types.T_enum:
   171  		return genericPartition[types.Enum](sels, diffs, partitions, vec)
   172  	case types.T_decimal64:
   173  		return genericPartition[types.Decimal64](sels, diffs, partitions, vec)
   174  	case types.T_decimal128:
   175  		return genericPartition[types.Decimal128](sels, diffs, partitions, vec)
   176  	case types.T_char, types.T_varchar, types.T_json, types.T_text,
   177  		types.T_array_float32, types.T_array_float64:
   178  		return bytesPartition(sels, diffs, partitions, vec)
   179  		//Used by ORDER_BY SQL clause.
   180  		//Byte partition logic doesn't use byte.Compare or Str.
   181  		//Hence, we can use bytesPartition here.
   182  	default:
   183  		panic(moerr.NewNotSupportedNoCtx(vec.GetType().Oid.String()))
   184  	}
   185  }