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  }