github.com/matrixorigin/matrixone@v0.7.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  )
    26  
    27  type Nulls struct {
    28  	Np *bitmap.Bitmap
    29  }
    30  
    31  func (n *Nulls) Clone() *Nulls {
    32  	if n == nil {
    33  		return nil
    34  	}
    35  	if n.Np == nil {
    36  		return &Nulls{Np: nil}
    37  	}
    38  	return &Nulls{
    39  		Np: n.Np.Clone(),
    40  	}
    41  }
    42  
    43  // Or performs union operation on Nulls n,m and store the result in r
    44  func Or(n, m, r *Nulls) {
    45  	if Ptr(n) == nil && Ptr(m) == nil {
    46  		r.Np = nil
    47  		return
    48  	}
    49  
    50  	r.Np = bitmap.New(0)
    51  	if Ptr(n) != nil {
    52  		r.Np.Or(n.Np)
    53  	}
    54  	if Ptr(m) != nil {
    55  		r.Np.Or(m.Np)
    56  	}
    57  }
    58  
    59  func Reset(n *Nulls) {
    60  	if n.Np != nil {
    61  		n.Np.Clear()
    62  	}
    63  }
    64  
    65  func NewWithSize(size int) *Nulls {
    66  	return &Nulls{
    67  		Np: bitmap.New(size),
    68  	}
    69  }
    70  
    71  func Build(size int, rows ...uint64) *Nulls {
    72  	n := NewWithSize(size)
    73  	Add(n, rows...)
    74  	return n
    75  }
    76  
    77  // XXX this is so broken,
    78  func New(n *Nulls, size int) {
    79  	n.Np = bitmap.New(size)
    80  }
    81  
    82  // Any returns true if any bit in the Nulls is set, otherwise it will return false.
    83  func Any(n *Nulls) bool {
    84  	if n == nil || n.Np == nil {
    85  		return false
    86  	}
    87  	return !n.Np.IsEmpty()
    88  }
    89  
    90  func Ptr(n *Nulls) *uint64 {
    91  	if n == nil {
    92  		return nil
    93  	}
    94  	return n.Np.Ptr()
    95  }
    96  
    97  // Size estimates the memory usage of the Nulls.
    98  func Size(n *Nulls) int {
    99  	if n.Np == nil {
   100  		return 0
   101  	}
   102  	return int(n.Np.Size())
   103  }
   104  
   105  // Length returns the number of integers contained in the Nulls
   106  func Length(n *Nulls) int {
   107  	if n.Np == nil {
   108  		return 0
   109  	}
   110  	return int(n.Np.Count())
   111  }
   112  
   113  func String(n *Nulls) string {
   114  	if n.Np == nil {
   115  		return "[]"
   116  	}
   117  	return fmt.Sprintf("%v", n.Np.ToArray())
   118  }
   119  
   120  func TryExpand(n *Nulls, size int) {
   121  	if n.Np == nil {
   122  		n.Np = bitmap.New(size)
   123  		return
   124  	}
   125  	n.Np.TryExpandWithSize(size)
   126  }
   127  
   128  // Contains returns true if the integer is contained in the Nulls
   129  func Contains(n *Nulls, row uint64) bool {
   130  	return n != nil && n.Np != nil && n.Np.Contains(row)
   131  }
   132  
   133  func Add(n *Nulls, rows ...uint64) {
   134  	if len(rows) == 0 {
   135  		return
   136  	}
   137  	if n == nil {
   138  		n = &Nulls{}
   139  	}
   140  	TryExpand(n, int(rows[len(rows)-1])+1)
   141  	n.Np.AddMany(rows)
   142  }
   143  
   144  func AddRange(n *Nulls, start, end uint64) {
   145  	TryExpand(n, int(end+1))
   146  	n.Np.AddRange(start, end)
   147  }
   148  
   149  func Del(n *Nulls, rows ...uint64) {
   150  	if n.Np == nil {
   151  		return
   152  	}
   153  	for _, row := range rows {
   154  		n.Np.Remove(row)
   155  	}
   156  }
   157  
   158  // Set performs union operation on Nulls n,m and store the result in n
   159  func Set(n, m *Nulls) {
   160  	if m != nil && m.Np != nil {
   161  		if n.Np == nil {
   162  			n.Np = bitmap.New(0)
   163  		}
   164  		n.Np.Or(m.Np)
   165  	}
   166  }
   167  
   168  // FilterCount returns the number count that appears in both n and sel
   169  func FilterCount(n *Nulls, sels []int64) int {
   170  	var cnt int
   171  
   172  	if n.Np == nil {
   173  		return cnt
   174  	}
   175  	if len(sels) == 0 {
   176  		return cnt
   177  	}
   178  	var sp []uint64
   179  	if len(sels) > 0 {
   180  		sp = unsafe.Slice((*uint64)(unsafe.Pointer(&sels[0])), cap(sels))[:len(sels)]
   181  	}
   182  	for _, sel := range sp {
   183  		if n.Np.Contains(sel) {
   184  			cnt++
   185  		}
   186  	}
   187  	return cnt
   188  }
   189  
   190  func RemoveRange(n *Nulls, start, end uint64) {
   191  	if n.Np != nil {
   192  		n.Np.RemoveRange(start, end)
   193  	}
   194  }
   195  
   196  // Range adds the numbers in n starting at start and ending at end to m.
   197  // `bias` represents the starting offset used for the Range Output
   198  // Return the result
   199  func Range(n *Nulls, start, end, bias uint64, m *Nulls) *Nulls {
   200  	switch {
   201  	case n.Np == nil && m.Np == nil:
   202  	case n.Np != nil && m.Np == nil:
   203  		m.Np = bitmap.New(int(end + 1 - bias))
   204  		for ; start < end; start++ {
   205  			if n.Np.Contains(start) {
   206  				m.Np.Add(start - bias)
   207  			}
   208  		}
   209  	case n.Np != nil && m.Np != nil:
   210  		m.Np = bitmap.New(int(end + 1 - bias))
   211  		for ; start < end; start++ {
   212  			if n.Np.Contains(start) {
   213  				m.Np.Add(start - bias)
   214  			}
   215  		}
   216  	}
   217  	return m
   218  }
   219  
   220  func Filter(n *Nulls, sels []int64) *Nulls {
   221  	if n.Np == nil {
   222  		return n
   223  	}
   224  	if len(sels) == 0 {
   225  		return n
   226  	}
   227  	var sp []uint64
   228  	if len(sels) > 0 {
   229  		sp = unsafe.Slice((*uint64)(unsafe.Pointer(&sels[0])), cap(sels))[:len(sels)]
   230  	}
   231  	np := bitmap.New(len(sels))
   232  	upperLimit := uint64(n.Np.Len())
   233  	for i, sel := range sp {
   234  		if sel >= upperLimit {
   235  			continue
   236  		}
   237  		if n.Np.Contains(sel) {
   238  			np.Add(uint64(i))
   239  		}
   240  	}
   241  	n.Np = np
   242  	return n
   243  }
   244  
   245  func (n *Nulls) Any() bool {
   246  	if n == nil || n.Np == nil {
   247  		return false
   248  	}
   249  	return !n.Np.IsEmpty()
   250  }
   251  
   252  func (n *Nulls) Set(row uint64) {
   253  	TryExpand(n, int(row)+1)
   254  	n.Np.Add(row)
   255  }
   256  
   257  func (n *Nulls) Contains(row uint64) bool {
   258  	return n != nil && n.Np != nil && n.Np.Contains(row)
   259  }
   260  
   261  func (n *Nulls) Show() ([]byte, error) {
   262  	if n.Np == nil {
   263  		return nil, nil
   264  	}
   265  	return n.Np.Marshal(), nil
   266  }
   267  
   268  func (n *Nulls) Read(data []byte) error {
   269  	if len(data) == 0 {
   270  		return nil
   271  	}
   272  	n.Np = bitmap.New(0)
   273  	n.Np.Unmarshal(data)
   274  	return nil
   275  }
   276  
   277  func (n *Nulls) Or(m *Nulls) *Nulls {
   278  	switch {
   279  	case m == nil:
   280  		return n
   281  	case n.Np == nil && m.Np == nil:
   282  		return n
   283  	case n.Np != nil && m.Np == nil:
   284  		return n
   285  	case n.Np == nil && m.Np != nil:
   286  		return m
   287  	default:
   288  		n.Np.Or(m.Np)
   289  		return n
   290  	}
   291  }