github.com/matrixorigin/matrixone@v1.2.0/pkg/container/vector/utils.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 vector
    16  
    17  import (
    18  	"bytes"
    19  
    20  	"github.com/matrixorigin/matrixone/pkg/container/types"
    21  	"github.com/matrixorigin/matrixone/pkg/vectorize/moarray"
    22  )
    23  
    24  // FindFirstIndexInSortedSlice finds the first index of v in a sorted slice s
    25  // If v is not found, return -1
    26  func OrderedFindFirstIndexInSortedSlice[T types.OrderedT](v T, s []T) int {
    27  	if len(s) == 0 {
    28  		return -1
    29  	}
    30  	if len(s) == 1 {
    31  		if s[0] == v {
    32  			return 0
    33  		}
    34  		return -1
    35  	}
    36  	if s[0] == v {
    37  		return 0
    38  	}
    39  	l, r := 0, len(s)-1
    40  	for l < r {
    41  		mid := (l + r) / 2
    42  		if s[mid] >= v {
    43  			r = mid
    44  		} else {
    45  			l = mid + 1
    46  		}
    47  	}
    48  	if s[l] == v {
    49  		return l
    50  	}
    51  	return -1
    52  }
    53  
    54  // FindFirstIndexInSortedSlice finds the first index of v in a sorted slice s
    55  // If v is not found, return -1
    56  // compare is a function to compare two elements in s
    57  func FixedSizeFindFirstIndexInSortedSliceWithCompare[T types.FixedSizeTExceptStrType](
    58  	v T, s []T, compare func(T, T) int,
    59  ) int {
    60  	if len(s) == 0 {
    61  		return -1
    62  	}
    63  	if len(s) == 1 {
    64  		if s[0] == v {
    65  			return 0
    66  		}
    67  		return -1
    68  	}
    69  	if s[0] == v {
    70  		return 0
    71  	}
    72  	l, r := 0, len(s)-1
    73  	for l < r {
    74  		mid := (l + r) / 2
    75  		if compare(s[mid], v) >= 0 {
    76  			r = mid
    77  		} else {
    78  			l = mid + 1
    79  		}
    80  	}
    81  	if s[l] == v {
    82  		return l
    83  	}
    84  	return -1
    85  }
    86  
    87  // FindFirstIndexInSortedSlice finds the first index of v in a sorted varlen vector
    88  func FindFirstIndexInSortedVarlenVector(vec *Vector, v []byte) int {
    89  	length := vec.Length()
    90  	if length == 0 {
    91  		return -1
    92  	}
    93  	if bytes.Equal(vec.GetBytesAt(0), v) {
    94  		return 0
    95  	}
    96  	if length == 1 {
    97  		return -1
    98  	}
    99  	l, r := 0, length-1
   100  	for l < r {
   101  		mid := (l + r) / 2
   102  		if bytes.Compare(vec.GetBytesAt(mid), v) >= 0 {
   103  			r = mid
   104  		} else {
   105  			l = mid + 1
   106  		}
   107  	}
   108  	if bytes.Equal(vec.GetBytesAt(l), v) {
   109  		return l
   110  	}
   111  	return -1
   112  }
   113  
   114  // IntegerGetSum get the sum the vector if the vector type is integer.
   115  func IntegerGetSum[T types.Ints | types.UInts, U int64 | uint64](vec *Vector) (sum U) {
   116  	var ok bool
   117  	col := MustFixedCol[T](vec)
   118  	if vec.HasNull() {
   119  		for i, v := range col {
   120  			if vec.IsNull(uint64(i)) {
   121  				continue
   122  			}
   123  			sum, ok = addInt(sum, U(v))
   124  			if !ok {
   125  				return 0
   126  			}
   127  		}
   128  	} else {
   129  		for _, v := range col {
   130  			sum, ok = addInt(sum, U(v))
   131  			if !ok {
   132  				return 0
   133  			}
   134  		}
   135  	}
   136  	return
   137  }
   138  
   139  func addInt[T int64 | uint64](a, b T) (T, bool) {
   140  	c := a + b
   141  	if (c > a) == (b > 0) {
   142  		return c, true
   143  	}
   144  	return 0, false
   145  }
   146  
   147  // FloatGetSum get the sum the vector if the vector type is float.
   148  func FloatGetSum[T types.Floats](vec *Vector) (sum float64) {
   149  	col := MustFixedCol[T](vec)
   150  	if vec.HasNull() {
   151  		for i, v := range col {
   152  			if vec.IsNull(uint64(i)) {
   153  				continue
   154  			}
   155  			sum += float64(v)
   156  		}
   157  	} else {
   158  		for _, v := range col {
   159  			sum += float64(v)
   160  		}
   161  	}
   162  	return
   163  }
   164  
   165  func Decimal64GetSum(vec *Vector) (sum types.Decimal64) {
   166  	var err error
   167  	col := MustFixedCol[types.Decimal64](vec)
   168  	if vec.HasNull() {
   169  		for i, v := range col {
   170  			if vec.IsNull(uint64(i)) {
   171  				continue
   172  			}
   173  			sum, err = sum.Add64(v)
   174  			if err != nil {
   175  				return 0
   176  			}
   177  		}
   178  	} else {
   179  		for _, dec := range col {
   180  			sum, err = sum.Add64(dec)
   181  			if err != nil {
   182  				return 0
   183  			}
   184  		}
   185  	}
   186  	return
   187  }
   188  
   189  // OrderedGetMinAndMax returns the min and max value of a vector of ordered type
   190  // If the vector has null, the null value will be ignored
   191  func OrderedGetMinAndMax[T types.OrderedT](vec *Vector) (minv, maxv T) {
   192  	col := MustFixedCol[T](vec)
   193  	if vec.HasNull() {
   194  		first := true
   195  		for i, j := 0, vec.Length(); i < j; i++ {
   196  			if vec.IsNull(uint64(i)) {
   197  				continue
   198  			}
   199  			if first {
   200  				minv, maxv = col[i], col[i]
   201  				first = false
   202  			} else {
   203  				if minv > col[i] {
   204  					minv = col[i]
   205  				}
   206  				if maxv < col[i] {
   207  					maxv = col[i]
   208  				}
   209  			}
   210  		}
   211  	} else {
   212  		minv, maxv = col[0], col[0]
   213  		for i, j := 1, vec.Length(); i < j; i++ {
   214  			if minv > col[i] {
   215  				minv = col[i]
   216  			}
   217  			if maxv < col[i] {
   218  				maxv = col[i]
   219  			}
   220  		}
   221  	}
   222  	return
   223  }
   224  
   225  func FixedSizeGetMinMax[T types.OrderedT](
   226  	vec *Vector, comp func(T, T) int64,
   227  ) (minv, maxv T) {
   228  	col := MustFixedCol[T](vec)
   229  	if vec.HasNull() {
   230  		first := true
   231  		for i, j := 0, vec.Length(); i < j; i++ {
   232  			if vec.IsNull(uint64(i)) {
   233  				continue
   234  			}
   235  			if first {
   236  				minv, maxv = col[i], col[i]
   237  				first = false
   238  			} else {
   239  				if comp(minv, col[i]) > 0 {
   240  					minv = col[i]
   241  				}
   242  				if comp(maxv, col[i]) < 0 {
   243  					maxv = col[i]
   244  				}
   245  			}
   246  		}
   247  	} else {
   248  		minv, maxv = col[0], col[0]
   249  		for i, j := 1, vec.Length(); i < j; i++ {
   250  			if comp(minv, col[i]) > 0 {
   251  				minv = col[i]
   252  			}
   253  			if comp(maxv, col[i]) < 0 {
   254  				maxv = col[i]
   255  			}
   256  		}
   257  	}
   258  	return
   259  }
   260  
   261  func VarlenGetMinMax(vec *Vector) (minv, maxv []byte) {
   262  	col, area := MustVarlenaRawData(vec)
   263  	if vec.HasNull() {
   264  		first := true
   265  		for i, j := 0, vec.Length(); i < j; i++ {
   266  			if vec.IsNull(uint64(i)) {
   267  				continue
   268  			}
   269  			val := col[i].GetByteSlice(area)
   270  			if first {
   271  				minv, maxv = val, val
   272  				first = false
   273  			} else {
   274  				if bytes.Compare(minv, val) > 0 {
   275  					minv = val
   276  				}
   277  				if bytes.Compare(maxv, val) < 0 {
   278  					maxv = val
   279  				}
   280  			}
   281  		}
   282  	} else {
   283  		val := col[0].GetByteSlice(area)
   284  		minv, maxv = val, val
   285  		for i, j := 1, vec.Length(); i < j; i++ {
   286  			val := col[i].GetByteSlice(area)
   287  			if bytes.Compare(minv, val) > 0 {
   288  				minv = val
   289  			}
   290  			if bytes.Compare(maxv, val) < 0 {
   291  				maxv = val
   292  			}
   293  		}
   294  	}
   295  	return
   296  }
   297  
   298  func ArrayGetMinMax[T types.RealNumbers](vec *Vector) (minv, maxv []T) {
   299  	col, area := MustVarlenaRawData(vec)
   300  	if vec.HasNull() {
   301  		first := true
   302  		for i, j := 0, vec.Length(); i < j; i++ {
   303  			if vec.IsNull(uint64(i)) {
   304  				continue
   305  			}
   306  			val := types.GetArray[T](&col[i], area)
   307  			if first {
   308  				minv, maxv = val, val
   309  				first = false
   310  			} else {
   311  				if moarray.Compare[T](minv, val) > 0 {
   312  					minv = val
   313  				}
   314  				if moarray.Compare[T](maxv, val) < 0 {
   315  					maxv = val
   316  				}
   317  			}
   318  		}
   319  	} else {
   320  		val := types.GetArray[T](&col[0], area)
   321  		minv, maxv = val, val
   322  		for i, j := 1, vec.Length(); i < j; i++ {
   323  			val := types.GetArray[T](&col[i], area)
   324  			if moarray.Compare[T](minv, val) > 0 {
   325  				minv = val
   326  			}
   327  			if moarray.Compare[T](maxv, val) < 0 {
   328  				maxv = val
   329  			}
   330  		}
   331  	}
   332  	return
   333  }
   334  
   335  func typeCompatible[T any](typ types.Type) bool {
   336  	var t T
   337  	switch (any)(t).(type) {
   338  	case types.Varlena:
   339  		return typ.IsVarlen()
   340  	case bool:
   341  		return typ.IsBoolean()
   342  	case int8:
   343  		return typ.Oid == types.T_int8
   344  	case int16:
   345  		return typ.Oid == types.T_int16
   346  	case int32:
   347  		return typ.Oid == types.T_int32
   348  	case int64:
   349  		return typ.Oid == types.T_int64
   350  	case uint8:
   351  		return typ.Oid == types.T_uint8
   352  	case uint16:
   353  		return typ.Oid == types.T_uint16
   354  	case uint32:
   355  		return typ.Oid == types.T_uint32
   356  	case uint64:
   357  		return typ.Oid == types.T_uint64 || typ.Oid == types.T_bit
   358  	case float32:
   359  		return typ.Oid == types.T_float32
   360  	case float64:
   361  		return typ.Oid == types.T_float64
   362  	case types.Decimal64:
   363  		return typ.Oid == types.T_decimal64
   364  	case types.Decimal128:
   365  		return typ.Oid == types.T_decimal128
   366  	case types.Uuid:
   367  		return typ.Oid == types.T_uuid
   368  	case types.Date:
   369  		return typ.Oid == types.T_date
   370  	case types.Time:
   371  		return typ.Oid == types.T_time
   372  	case types.Datetime:
   373  		return typ.Oid == types.T_datetime
   374  	case types.Timestamp:
   375  		return typ.Oid == types.T_timestamp
   376  	case types.TS:
   377  		return typ.Oid == types.T_TS
   378  	case types.Rowid:
   379  		return typ.Oid == types.T_Rowid
   380  	case types.Blockid:
   381  		return typ.Oid == types.T_Blockid
   382  	case types.Enum:
   383  		return typ.Oid == types.T_enum
   384  	}
   385  	return false
   386  }