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 }