github.com/matrixorigin/matrixone@v1.2.0/pkg/container/nulls/nulls.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 nulls wrap up functions for the manipulation of bitmap library roaring. 16 // MatrixOne uses nulls to store all NULL values in a column. 17 // You can think of Nulls as a bitmap. 18 package nulls 19 20 import ( 21 "fmt" 22 "unsafe" 23 24 "github.com/matrixorigin/matrixone/pkg/common/bitmap" 25 "golang.org/x/exp/constraints" 26 ) 27 28 type Bitmap = Nulls 29 30 type Nulls struct { 31 np bitmap.Bitmap 32 } 33 34 func (nsp *Nulls) Clone() *Nulls { 35 if nsp == nil { 36 return nil 37 } 38 var n Nulls 39 n.InitWith(nsp) 40 return &n 41 } 42 43 func (nsp *Nulls) InitWith(n *Nulls) { 44 nsp.np.InitWith(&n.np) 45 } 46 47 func (nsp *Nulls) InitWithSize(size int) { 48 nsp.np.InitWithSize(int64(size)) 49 } 50 51 func NewWithSize(size int) *Nulls { 52 var n Nulls 53 n.InitWithSize(size) 54 return &n 55 } 56 57 func (nsp *Nulls) Reset() { 58 nsp.np.Reset() 59 } 60 61 func (nsp *Nulls) GetBitmap() *bitmap.Bitmap { 62 return &nsp.np 63 } 64 65 // Or performs union operation on Nulls nsp,m and store the result in r 66 func Or(nsp, m, r *Nulls) { 67 if nsp.EmptyByFlag() && m.EmptyByFlag() { 68 r.Reset() 69 } 70 71 if !nsp.EmptyByFlag() { 72 r.np.Or(&nsp.np) 73 } 74 75 if !m.EmptyByFlag() { 76 r.np.Or(&m.np) 77 } 78 } 79 80 func (nsp *Nulls) Build(size int, rows ...uint64) { 81 nsp.InitWithSize(size) 82 Add(nsp, rows...) 83 } 84 func Build(size int, rows ...uint64) *Nulls { 85 var n Nulls 86 n.Build(size, rows...) 87 return &n 88 } 89 90 // Any returns true if any bit in the Nulls is set, otherwise it will return false. 91 func Any(nsp *Nulls) bool { 92 if nsp == nil { 93 return false 94 } 95 return !nsp.np.IsEmpty() 96 } 97 98 func Ptr(nsp *Nulls) *uint64 { 99 if nsp == nil { 100 return nil 101 } 102 return nsp.np.Ptr() 103 } 104 105 // Size estimates the memory usage of the Nulls. 106 func Size(nsp *Nulls) int { 107 if nsp == nil { 108 return 0 109 } 110 return int(nsp.np.Size()) 111 } 112 113 func String(nsp *Nulls) string { 114 if nsp == nil || nsp.np.EmptyByFlag() { 115 return "[]" 116 } 117 return fmt.Sprintf("%v", nsp.np.ToArray()) 118 } 119 120 func TryExpand(nsp *Nulls, size int) { 121 nsp.np.TryExpandWithSize(size) 122 } 123 124 // Contains returns true if the integer is contained in the Nulls 125 func (nsp *Nulls) Contains(row uint64) bool { 126 return nsp != nil && !nsp.np.EmptyByFlag() && nsp.np.Contains(row) 127 } 128 129 func Contains(nsp *Nulls, row uint64) bool { 130 return nsp.Contains(row) 131 } 132 133 func (nsp *Nulls) Add(rows ...uint64) { 134 if nsp == nil || len(rows) == 0 { 135 return 136 } 137 TryExpand(nsp, int(rows[len(rows)-1])+1) 138 nsp.np.AddMany(rows) 139 } 140 141 func Add(nsp *Nulls, rows ...uint64) { 142 nsp.Add(rows...) 143 } 144 145 func (nsp *Nulls) AddRange(start, end uint64) { 146 if nsp != nil { 147 TryExpand(nsp, int(end+1)) 148 nsp.np.AddRange(start, end) 149 } 150 } 151 152 func AddRange(nsp *Nulls, start, end uint64) { 153 nsp.AddRange(start, end) 154 } 155 156 func (nsp *Nulls) Del(rows ...uint64) { 157 if nsp != nil { 158 for _, row := range rows { 159 nsp.np.Remove(row) 160 } 161 } 162 } 163 164 func (nsp *Nulls) DelI64(rows ...int64) { 165 if nsp != nil { 166 for _, row := range rows { 167 nsp.np.Remove(uint64(row)) 168 } 169 } 170 } 171 172 func Del(nsp *Nulls, rows ...uint64) { 173 nsp.Del(rows...) 174 } 175 176 // Set performs union operation on Nulls nsp,m and store the result in nsp 177 func Set(nsp, m *Nulls) { 178 if !m.np.EmptyByFlag() { 179 nsp.np.Or(&m.np) 180 } 181 } 182 183 // FilterCount returns the number count that appears in both nsp and sel 184 func FilterCount(nsp *Nulls, sels []int64) int { 185 var cnt int 186 if nsp.np.EmptyByFlag() || len(sels) == 0 { 187 return 0 188 } 189 190 // XXX WTF is this? convert int64 to uint64? 191 var sp []uint64 192 if len(sels) > 0 { 193 sp = unsafe.Slice((*uint64)(unsafe.Pointer(&sels[0])), cap(sels))[:len(sels)] 194 } 195 196 for _, sel := range sp { 197 if nsp.np.Contains(sel) { 198 cnt++ 199 } 200 } 201 return cnt 202 } 203 204 func RemoveRange(nsp *Nulls, start, end uint64) { 205 if !nsp.np.EmptyByFlag() { 206 nsp.np.RemoveRange(start, end) 207 } 208 } 209 210 // Range adds the numbers in nsp starting at start and ending at end to m. 211 // `bias` represents the starting offset used for the Range Output 212 // Always update in place. 213 func Range(nsp *Nulls, start, end, bias uint64, m *Nulls) { 214 if nsp.np.EmptyByFlag() { 215 return 216 } 217 218 m.np.InitWithSize(int64(end + 1 - bias)) 219 for ; start < end; start++ { 220 if nsp.np.Contains(start) { 221 m.np.Add(start - bias) 222 } 223 } 224 } 225 226 // XXX old API returns nsp, which is broken -- we update in place. 227 func Filter(nsp *Nulls, sels []int64, negate bool) { 228 if nsp.np.EmptyByFlag() { 229 return 230 } 231 232 if negate { 233 oldLen := nsp.np.Len() 234 var bm bitmap.Bitmap 235 bm.InitWithSize(oldLen) 236 for oldIdx, newIdx, selIdx, sel := int64(0), 0, 0, sels[0]; oldIdx < oldLen; oldIdx++ { 237 if oldIdx != sel { 238 if nsp.np.Contains(uint64(oldIdx)) { 239 bm.Add(uint64(newIdx)) 240 } 241 newIdx++ 242 } else { 243 selIdx++ 244 if selIdx >= len(sels) { 245 for idx := oldIdx + 1; idx < oldLen; idx++ { 246 if nsp.np.Contains(uint64(idx)) { 247 bm.Add(uint64(newIdx)) 248 } 249 newIdx++ 250 } 251 break 252 } 253 sel = sels[selIdx] 254 } 255 } 256 nsp.np.InitWith(&bm) 257 } else { 258 var bm bitmap.Bitmap 259 bm.InitWithSize(int64(len(sels))) 260 upperLimit := int64(nsp.np.Len()) 261 for i, sel := range sels { 262 if sel >= upperLimit { 263 continue 264 } 265 if nsp.np.Contains(uint64(sel)) { 266 bm.Add(uint64(i)) 267 } 268 } 269 nsp.np.InitWith(&bm) 270 } 271 } 272 273 // XXX This emptyFlag thing is broken -- it simply cannot be used concurrently. 274 // Make any an alias of EmptyByFlag, otherwise there will be hell lots of race conditions. 275 func (nsp *Nulls) Any() bool { 276 return nsp != nil && !nsp.np.EmptyByFlag() 277 } 278 279 func (nsp *Nulls) IsEmpty() bool { 280 return nsp == nil || nsp.np.IsEmpty() 281 } 282 283 func (nsp *Nulls) EmptyByFlag() bool { 284 return nsp == nil || nsp.np.EmptyByFlag() 285 } 286 287 func (nsp *Nulls) Set(row uint64) { 288 TryExpand(nsp, int(row)+1) 289 nsp.np.Add(row) 290 } 291 292 // Call it unset to match set. Clear or reset are taken. 293 func (nsp *Nulls) Unset(row uint64) { 294 if nsp != nil { 295 nsp.np.Remove(row) 296 } 297 } 298 299 // pop count 300 func (nsp *Nulls) Count() int { 301 if nsp == nil { 302 return 0 303 } 304 return nsp.np.Count() 305 } 306 307 func (nsp *Nulls) Show() ([]byte, error) { 308 if nsp.np.EmptyByFlag() { 309 return nil, nil 310 } 311 return nsp.np.Marshal(), nil 312 } 313 314 func (nsp *Nulls) Read(data []byte) error { 315 if len(data) == 0 { 316 // don't we need to reset? Or we always, Read into a blank Nulls? 317 // nsp.np.Reset() 318 return nil 319 } 320 nsp.np.Unmarshal(data) 321 return nil 322 } 323 324 func (nsp *Nulls) ReadNoCopy(data []byte) error { 325 if len(data) == 0 { 326 return nil 327 } 328 nsp.np.UnmarshalNoCopy(data) 329 return nil 330 } 331 332 // XXX This API is foundementally broken. Depends on empty or not 333 // this shit may or may not modify nsp. 334 func (nsp *Nulls) Or(m *Nulls) *Nulls { 335 if m.np.EmptyByFlag() { 336 return nsp 337 } 338 if nsp.np.EmptyByFlag() { 339 return m 340 } 341 342 nsp.np.Or(&m.np) 343 return nsp 344 } 345 346 func (nsp *Nulls) IsSame(m *Nulls) bool { 347 if nsp == m { 348 return true 349 } 350 if nsp == nil || m == nil { 351 return false 352 } 353 354 return nsp.np.IsSame(&m.np) 355 } 356 357 func (nsp *Nulls) ToArray() []uint64 { 358 if nsp == nil || nsp.np.EmptyByFlag() { 359 return []uint64{} 360 } 361 return nsp.np.ToArray() 362 } 363 364 func (nsp *Nulls) ToI64Arrary() []int64 { 365 if nsp == nil || nsp.np.EmptyByFlag() { 366 return []int64{} 367 } 368 return nsp.np.ToI64Arrary() 369 } 370 371 func (nsp *Nulls) GetCardinality() int { 372 return nsp.Count() 373 } 374 375 func (nsp *Nulls) Foreach(fn func(uint64) bool) { 376 if nsp.IsEmpty() { 377 return 378 } 379 itr := nsp.np.Iterator() 380 for itr.HasNext() { 381 row := itr.Next() 382 if !fn(row) { 383 break 384 } 385 } 386 } 387 388 func (nsp *Nulls) Merge(o *Nulls) { 389 if o.Count() == 0 { 390 return 391 } 392 itr := o.np.Iterator() 393 for itr.HasNext() { 394 r := itr.Next() 395 nsp.Add(r) 396 } 397 } 398 399 func (nsp *Nulls) String() string { 400 if nsp.IsEmpty() { 401 return fmt.Sprintf("%v", []uint64{}) 402 } 403 return nsp.np.String() 404 } 405 406 func ToArray[T constraints.Integer](nsp *Nulls) []T { 407 if nsp.IsEmpty() { 408 return []T{} 409 } 410 ret := make([]T, 0, nsp.Count()) 411 it := nsp.np.Iterator() 412 for it.HasNext() { 413 r := it.Next() 414 ret = append(ret, T(r)) 415 } 416 return ret 417 }