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 }