github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/containers/vecimpl.go (about)

     1  // Copyright 2022 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 containers
    16  
    17  import (
    18  	"fmt"
    19  
    20  	"github.com/RoaringBitmap/roaring"
    21  	"github.com/RoaringBitmap/roaring/roaring64"
    22  	"github.com/matrixorigin/matrixone/pkg/container/types"
    23  )
    24  
    25  type vecImpl[T any] struct {
    26  	*vecBase[T]
    27  }
    28  
    29  func newVecImpl[T any](derived *vector[T]) *vecImpl[T] {
    30  	return &vecImpl[T]{
    31  		vecBase: newVecBase(derived),
    32  	}
    33  }
    34  
    35  type nullableVecImpl[T any] struct {
    36  	*vecBase[T]
    37  }
    38  
    39  func newNullableVecImpl[T any](derived *vector[T]) *nullableVecImpl[T] {
    40  	return &nullableVecImpl[T]{
    41  		vecBase: newVecBase(derived),
    42  	}
    43  }
    44  func (impl *nullableVecImpl[T]) Nullable() bool { return true }
    45  func (impl *nullableVecImpl[T]) IsNull(i int) bool {
    46  	return impl.derived.nulls != nil && impl.derived.nulls.Contains(uint64(i))
    47  }
    48  
    49  func (impl *nullableVecImpl[T]) HasNull() bool {
    50  	return impl.derived.nulls != nil && !impl.derived.nulls.IsEmpty()
    51  }
    52  
    53  func (impl *nullableVecImpl[T]) Get(i int) (v any) {
    54  	if impl.IsNull(i) {
    55  		return types.Null{}
    56  	}
    57  	return impl.derived.stlvec.Get(i)
    58  }
    59  
    60  // Modification
    61  func (impl *nullableVecImpl[T]) Update(i int, v any) {
    62  	impl.tryCOW()
    63  	_, isNull := v.(types.Null)
    64  	if isNull {
    65  		if impl.derived.nulls == nil {
    66  			impl.derived.nulls = roaring64.BitmapOf(uint64(i))
    67  		} else {
    68  			impl.derived.nulls.Add(uint64(i))
    69  		}
    70  		return
    71  	}
    72  	if impl.IsNull(i) {
    73  		impl.derived.nulls.Remove(uint64(i))
    74  	}
    75  	impl.derived.stlvec.Update(i, v.(T))
    76  }
    77  
    78  func (impl *nullableVecImpl[T]) Delete(i int) {
    79  	impl.tryCOW()
    80  	if !impl.HasNull() {
    81  		impl.vecBase.Delete(i)
    82  		return
    83  	}
    84  	nulls := impl.derived.nulls
    85  	max := nulls.Maximum()
    86  	if max < uint64(i) {
    87  		impl.vecBase.Delete(i)
    88  		return
    89  	} else if max == uint64(i) {
    90  		nulls.Remove(uint64(i))
    91  		impl.vecBase.Delete(i)
    92  		return
    93  	}
    94  	nulls.Remove(uint64(i))
    95  	dels := impl.derived.nulls.ToArray()
    96  	for pos := len(dels) - 1; pos >= 0; pos-- {
    97  		if dels[pos] < uint64(i) {
    98  			break
    99  		}
   100  		nulls.Remove(dels[pos])
   101  		nulls.Add(dels[pos] - 1)
   102  	}
   103  	impl.derived.stlvec.Delete(i)
   104  }
   105  
   106  func (impl *nullableVecImpl[T]) Compact(deletes *roaring.Bitmap) {
   107  	impl.tryCOW()
   108  	if !impl.HasNull() {
   109  		impl.vecBase.Compact(deletes)
   110  		return
   111  	}
   112  	nulls := impl.derived.nulls
   113  	max := nulls.Maximum()
   114  	min := deletes.Minimum()
   115  	if max < uint64(min) {
   116  		impl.vecBase.Compact(deletes)
   117  		return
   118  	} else if max == uint64(min) {
   119  		impl.vecBase.Compact(deletes)
   120  		nulls.Remove(uint64(min))
   121  		return
   122  	}
   123  	nullsIt := nulls.Iterator()
   124  	arr := deletes.ToArray()
   125  	deleted := 0
   126  	arr = append(arr, uint32(impl.Length()))
   127  	newNulls := roaring64.New()
   128  	for _, idx := range arr {
   129  		for nullsIt.HasNext() {
   130  			null := nullsIt.PeekNext()
   131  			if null < uint64(idx) {
   132  				nullsIt.Next()
   133  				newNulls.Add(null - uint64(deleted))
   134  			} else {
   135  				if null == uint64(idx) {
   136  					nullsIt.Next()
   137  				}
   138  				break
   139  			}
   140  		}
   141  		deleted++
   142  	}
   143  	impl.derived.nulls = newNulls
   144  	impl.vecBase.Compact(deletes)
   145  }
   146  
   147  func (impl *nullableVecImpl[T]) Append(v any) {
   148  	impl.tryCOW()
   149  	offset := impl.derived.stlvec.Length()
   150  	_, isNull := v.(types.Null)
   151  	if isNull {
   152  		if impl.derived.nulls == nil {
   153  			impl.derived.nulls = roaring64.BitmapOf(uint64(offset))
   154  		} else {
   155  			impl.derived.nulls.Add(uint64(offset))
   156  		}
   157  		impl.derived.stlvec.Append(types.DefaultVal[T]())
   158  	} else {
   159  		impl.derived.stlvec.Append(v.(T))
   160  	}
   161  }
   162  func (impl *nullableVecImpl[T]) Extend(o Vector) {
   163  	impl.ExtendWithOffset(o, 0, o.Length())
   164  }
   165  
   166  func (impl *nullableVecImpl[T]) ExtendWithOffset(o Vector, srcOff, srcLen int) {
   167  	impl.tryCOW()
   168  	if o.Nullable() {
   169  		if !o.HasNull() {
   170  			impl.extendData(o, srcOff, srcLen)
   171  			return
   172  		} else {
   173  			if impl.derived.nulls == nil {
   174  				impl.derived.nulls = roaring64.New()
   175  			}
   176  			it := o.NullMask().Iterator()
   177  			offset := impl.derived.stlvec.Length()
   178  			for it.HasNext() {
   179  				pos := it.Next()
   180  				if pos < uint64(srcOff) {
   181  					continue
   182  				} else if pos >= uint64(srcOff+srcLen) {
   183  					break
   184  				}
   185  				impl.derived.nulls.Add(uint64(offset) + pos - uint64(srcOff))
   186  			}
   187  			impl.extendData(o, srcOff, srcLen)
   188  			return
   189  		}
   190  	}
   191  	impl.extendData(o, srcOff, srcLen)
   192  }
   193  func (impl *nullableVecImpl[T]) String() string {
   194  	s := impl.derived.stlvec.String()
   195  	if impl.HasNull() {
   196  		s = fmt.Sprintf("%s:Nulls=%s", s, impl.derived.nulls.String())
   197  	}
   198  	return s
   199  }
   200  
   201  func (impl *nullableVecImpl[T]) ForeachWindow(offset, length int, op ItOp, sels *roaring.Bitmap) (err error) {
   202  	return impl.forEachWindowWithBias(offset, length, op, sels, 0)
   203  }
   204  
   205  func (impl *nullableVecImpl[T]) forEachWindowWithBias(offset, length int, op ItOp, sels *roaring.Bitmap, bias int) (err error) {
   206  	if !impl.HasNull() {
   207  		return impl.vecBase.forEachWindowWithBias(offset, length, op, sels, bias)
   208  	}
   209  	var v T
   210  	if _, ok := any(v).([]byte); !ok {
   211  		slice := impl.derived.stlvec.Slice()
   212  		slice = slice[offset+bias : offset+length+bias]
   213  		if sels == nil || sels.IsEmpty() {
   214  			for i, elem := range slice {
   215  				var v any
   216  				if impl.IsNull(i + offset + bias) {
   217  					v = types.Null{}
   218  				} else {
   219  					v = elem
   220  				}
   221  				if err = op(v, i+offset); err != nil {
   222  					break
   223  				}
   224  			}
   225  		} else {
   226  			idxes := sels.ToArray()
   227  			end := offset + length
   228  			for _, idx := range idxes {
   229  				if int(idx) < offset {
   230  					continue
   231  				} else if int(idx) >= end {
   232  					break
   233  				}
   234  				var v any
   235  				if impl.IsNull(int(idx) + bias) {
   236  					v = types.Null{}
   237  				} else {
   238  					v = slice[int(idx)-offset]
   239  				}
   240  				if err = op(v, int(idx)); err != nil {
   241  					break
   242  				}
   243  			}
   244  		}
   245  		return
   246  	}
   247  
   248  	if sels == nil || sels.IsEmpty() {
   249  		for i := offset; i < offset+length; i++ {
   250  			elem := impl.Get(i + bias)
   251  			if err = op(elem, i); err != nil {
   252  				break
   253  			}
   254  		}
   255  		return
   256  	}
   257  
   258  	idxes := sels.ToArray()
   259  	end := offset + length
   260  	for _, idx := range idxes {
   261  		if int(idx) < offset {
   262  			continue
   263  		} else if int(idx) >= end {
   264  			break
   265  		}
   266  		elem := impl.Get(int(idx) + bias)
   267  		if err = op(elem, int(idx)); err != nil {
   268  			break
   269  		}
   270  	}
   271  	return
   272  }