github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/compute/compute.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 compute 16 17 import ( 18 "bytes" 19 20 "github.com/RoaringBitmap/roaring" 21 "github.com/matrixorigin/matrixone/pkg/container/types" 22 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/containers" 23 24 "golang.org/x/exp/constraints" 25 ) 26 27 // unused 28 // type deleteRange struct { 29 // pos uint32 30 // deleted uint32 31 // } 32 33 // unused 34 // func findDeleteRange(pos uint32, ranges []*deleteRange) *deleteRange { 35 // left, right := 0, len(ranges)-1 36 // var mid int 37 // for left <= right { 38 // mid = (left + right) / 2 39 // if ranges[mid].pos < pos { 40 // left = mid + 1 41 // } else if ranges[mid].pos > pos { 42 // right = mid - 1 43 // } else { 44 // break 45 // } 46 // } 47 // if mid == 0 && ranges[mid].pos < pos { 48 // mid = mid + 1 49 // } 50 // // logutil.Infof("pos=%d, mid=%d, range.pos=%d,range.deleted=%d", pos, mid, ranges[mid].pos, ranges[mid].deleted) 51 // return ranges[mid] 52 // } 53 54 func ShuffleByDeletes(deleteMask, deletes *roaring.Bitmap) (destDelets *roaring.Bitmap) { 55 if deletes == nil || deletes.IsEmpty() { 56 return deleteMask 57 } 58 if deleteMask != nil && !deleteMask.IsEmpty() { 59 delIt := deleteMask.Iterator() 60 destDelets = roaring.New() 61 deleteIt := deletes.Iterator() 62 deleteCnt := uint32(0) 63 for deleteIt.HasNext() { 64 del := deleteIt.Next() 65 for delIt.HasNext() { 66 row := delIt.PeekNext() 67 if row < del { 68 destDelets.Add(row - deleteCnt) 69 delIt.Next() 70 } else if row == del { 71 delIt.Next() 72 } else { 73 break 74 } 75 } 76 deleteCnt++ 77 } 78 for delIt.HasNext() { 79 row := delIt.Next() 80 destDelets.Add(row - deleteCnt) 81 } 82 } 83 return destDelets 84 } 85 86 func ShuffleOffset(offset uint32, deletes *roaring.Bitmap) uint32 { 87 if deletes == nil || deletes.IsEmpty() { 88 return offset 89 } 90 end := offset 91 deleteCnt := deletes.Rank(end) 92 for offset+uint32(deleteCnt) > end { 93 end = offset + uint32(deleteCnt) 94 deleteCnt = deletes.Rank(end) 95 } 96 return end 97 } 98 99 func GetOffsetMapBeforeApplyDeletes(deletes *roaring.Bitmap) []uint32 { 100 if deletes == nil || deletes.IsEmpty() { 101 return nil 102 } 103 prev := -1 104 mapping := make([]uint32, 0) 105 it := deletes.Iterator() 106 for it.HasNext() { 107 delete := it.Next() 108 for i := uint32(prev + 1); i < delete; i++ { 109 mapping = append(mapping, i) 110 } 111 prev = int(delete) 112 } 113 mapping = append(mapping, uint32(prev)+1) 114 return mapping 115 } 116 117 func GetOffsetWithFunc[T any]( 118 vals []T, 119 val T, 120 compare func(a, b T) int64, 121 skipmask *roaring.Bitmap, 122 ) (offset int, exist bool) { 123 start, end := 0, len(vals)-1 124 var mid int 125 for start <= end { 126 mid = (start + end) / 2 127 res := compare(vals[mid], val) 128 if res > 0 { 129 end = mid - 1 130 } else if res < 0 { 131 start = mid + 1 132 } else { 133 if skipmask != nil && skipmask.Contains(uint32(mid)) { 134 return 135 } 136 offset = mid 137 exist = true 138 return 139 } 140 } 141 return 142 } 143 144 func GetOffsetOfOrdered[T types.OrderedT](vs, v any, skipmask *roaring.Bitmap) (offset int, exist bool) { 145 column := vs.([]T) 146 val := v.(T) 147 start, end := 0, len(column)-1 148 var mid int 149 for start <= end { 150 mid = (start + end) / 2 151 if column[mid] > val { 152 end = mid - 1 153 } else if column[mid] < val { 154 start = mid + 1 155 } else { 156 if skipmask != nil && skipmask.Contains(uint32(mid)) { 157 return 158 } 159 offset = mid 160 exist = true 161 return 162 } 163 } 164 return 165 } 166 167 func EstimateSize(bat *containers.Batch, offset, length uint32) uint64 { 168 size := uint64(0) 169 for _, vec := range bat.Vecs { 170 colSize := length * uint32(vec.GetType().Size) 171 size += uint64(colSize) 172 } 173 return size 174 } 175 176 func GetOffsetByVal(data containers.Vector, v any, skipmask *roaring.Bitmap) (offset int, exist bool) { 177 switch data.GetType().Oid { 178 case types.T_bool: 179 return GetOffsetWithFunc(data.Slice().([]bool), v.(bool), CompareBool, skipmask) 180 case types.T_int8: 181 return GetOffsetOfOrdered[int8](data.Slice(), v, skipmask) 182 case types.T_int16: 183 return GetOffsetOfOrdered[int16](data.Slice(), v, skipmask) 184 case types.T_int32: 185 return GetOffsetOfOrdered[int32](data.Slice(), v, skipmask) 186 case types.T_int64: 187 return GetOffsetOfOrdered[int64](data.Slice(), v, skipmask) 188 case types.T_uint8: 189 return GetOffsetOfOrdered[uint8](data.Slice(), v, skipmask) 190 case types.T_uint16: 191 return GetOffsetOfOrdered[uint16](data.Slice(), v, skipmask) 192 case types.T_uint32: 193 return GetOffsetOfOrdered[uint32](data.Slice(), v, skipmask) 194 case types.T_uint64: 195 return GetOffsetOfOrdered[uint64](data.Slice(), v, skipmask) 196 case types.T_float32: 197 return GetOffsetOfOrdered[float32](data.Slice(), v, skipmask) 198 case types.T_float64: 199 return GetOffsetOfOrdered[float64](data.Slice(), v, skipmask) 200 case types.T_date: 201 return GetOffsetOfOrdered[types.Date](data.Slice(), v, skipmask) 202 case types.T_time: 203 return GetOffsetOfOrdered[types.Time](data.Slice(), v, skipmask) 204 case types.T_datetime: 205 return GetOffsetOfOrdered[types.Datetime](data.Slice(), v, skipmask) 206 case types.T_timestamp: 207 return GetOffsetOfOrdered[types.Timestamp](data.Slice(), v, skipmask) 208 case types.T_decimal64: 209 return GetOffsetWithFunc( 210 data.Slice().([]types.Decimal64), 211 v.(types.Decimal64), 212 types.CompareDecimal64Decimal64Aligned, 213 skipmask) 214 case types.T_decimal128: 215 return GetOffsetWithFunc( 216 data.Slice().([]types.Decimal128), 217 v.(types.Decimal128), 218 types.CompareDecimal128Decimal128Aligned, 219 skipmask) 220 case types.T_TS: 221 return GetOffsetWithFunc( 222 data.Slice().([]types.TS), 223 v.(types.TS), 224 types.CompareTSTSAligned, 225 skipmask) 226 case types.T_Rowid: 227 return GetOffsetWithFunc( 228 data.Slice().([]types.Rowid), 229 v.(types.Rowid), 230 types.CompareRowidRowidAligned, 231 skipmask) 232 case types.T_uuid: 233 return GetOffsetWithFunc( 234 data.Slice().([]types.Uuid), 235 v.(types.Uuid), 236 types.CompareUuid, 237 skipmask) 238 case types.T_char, types.T_varchar, types.T_blob, types.T_json, types.T_text: 239 // column := data.Slice().(*containers.Bytes) 240 val := v.([]byte) 241 start, end := 0, data.Length()-1 242 var mid int 243 for start <= end { 244 mid = (start + end) / 2 245 res := bytes.Compare(data.Get(mid).([]byte), val) 246 if res > 0 { 247 end = mid - 1 248 } else if res < 0 { 249 start = mid + 1 250 } else { 251 if skipmask != nil && skipmask.Contains(uint32(mid)) { 252 return 253 } 254 offset = mid 255 exist = true 256 return 257 } 258 } 259 return 260 default: 261 panic("unsupported type") 262 } 263 } 264 265 func BinarySearchTs(a []types.TS, x types.TS) int { 266 start, mid, end := 0, 0, len(a)-1 267 for start <= end { 268 mid = (start + end) >> 1 269 switch { 270 case a[mid].Greater(x): 271 end = mid - 1 272 case a[mid].Less(x): 273 start = mid + 1 274 default: 275 return mid 276 } 277 } 278 return -1 279 } 280 281 func BinarySearch[T constraints.Ordered](a []T, x T) int { 282 start, mid, end := 0, 0, len(a)-1 283 for start <= end { 284 mid = (start + end) >> 1 285 switch { 286 case a[mid] > x: 287 end = mid - 1 288 case a[mid] < x: 289 start = mid + 1 290 default: 291 return mid 292 } 293 } 294 return -1 295 }