github.com/matrixorigin/matrixone@v1.2.0/pkg/common/bitmap/bitmap.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 bitmap
    16  
    17  import (
    18  	"bytes"
    19  	"encoding"
    20  	"fmt"
    21  	"math/bits"
    22  	"unsafe"
    23  
    24  	"github.com/matrixorigin/matrixone/pkg/container/types"
    25  )
    26  
    27  //
    28  // In case len is not multiple of 64, many of these code following assumes the trailing
    29  // bits of last uint64 are zero.   This may well be true in all our usage.  So let's
    30  // leave as it is for now.
    31  //
    32  
    33  type bitmask = uint64
    34  
    35  /*
    36   * Array giving the position of the right-most set bit for each possible
    37   * byte value. count the right-most position as the 0th bit, and the
    38   * left-most the 7th bit.  The 0th entry of the array should not be used.
    39   * e.g. 2 = 0x10 ==> rightmost_one_pos_8[2] = 1, 3 = 0x11 ==> rightmost_one_pos_8[3] = 0
    40   */
    41  var rightmost_one_pos_8 = [256]uint8{
    42  	0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    43  	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    44  	5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    45  	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    46  	6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    47  	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    48  	5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    49  	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    50  	7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    51  	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    52  	5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    53  	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    54  	6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    55  	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    56  	5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    57  	4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
    58  }
    59  
    60  func (n *Bitmap) InitWith(other *Bitmap) {
    61  	n.len = other.len
    62  	n.emptyFlag.Store(other.emptyFlag.Load())
    63  	n.data = append([]uint64(nil), other.data...)
    64  }
    65  
    66  func (n *Bitmap) InitWithSize(len int64) {
    67  	n.len = len
    68  	n.emptyFlag.Store(kEmptyFlagEmpty)
    69  	n.data = make([]uint64, (len+63)/64)
    70  }
    71  
    72  func (n *Bitmap) Clone() *Bitmap {
    73  	if n == nil {
    74  		return nil
    75  	}
    76  	var ret Bitmap
    77  	ret.InitWith(n)
    78  	return &ret
    79  }
    80  
    81  func (n *Bitmap) Iterator() Iterator {
    82  	// When initialization, the itr.i is set to the first rightmost_one position.
    83  	itr := BitmapIterator{i: 0, bm: n}
    84  	if first_1_pos, has_next := itr.hasNext(0); has_next {
    85  		itr.i = first_1_pos
    86  		itr.has_next = true
    87  		return &itr
    88  	}
    89  	itr.has_next = false
    90  	return &itr
    91  }
    92  
    93  func rightmost_one_pos_64(word uint64) uint64 {
    94  	// find out the rightmost_one position.
    95  	// Firstly, use eight bits as a group to quickly determine whether there is a 1 in it.
    96  	// if not, then rightmost_one exists in next group, add up the distance with result and shift the word
    97  	// if rightmost_one exists in this group, get the distance directly from a pre-made hash table
    98  	var result uint64
    99  	for {
   100  		if (word & 0xFF) == 0 {
   101  			word >>= 8
   102  			result += 8
   103  		} else {
   104  			break
   105  		}
   106  	}
   107  	result += uint64(rightmost_one_pos_8[word&255])
   108  	return result
   109  }
   110  
   111  func (itr *BitmapIterator) hasNext(i uint64) (uint64, bool) {
   112  	// if the uint64 is 0, move forward to next word
   113  	// if the uint64 is not 0, then calculate the rightest_one position in a word, add up prev result and return.
   114  	// when there is 1 in bitmap, return true, otherwise bitmap is empty and return false.
   115  	// either case loop over words not bits
   116  	nwords := (itr.bm.len + 63) / 64
   117  	current_word := i >> 6
   118  	mask := (^(bitmask)(0)) << (i & 0x3F) // ignore bits check before
   119  	var result uint64
   120  
   121  	for ; current_word < uint64(nwords); current_word++ {
   122  		word := itr.bm.data[current_word]
   123  		word &= mask
   124  
   125  		if word != 0 {
   126  			result = rightmost_one_pos_64(word) + current_word*64
   127  			return result, true
   128  		}
   129  		mask = (^(bitmask)(0)) // in subsequent words, consider all bits
   130  	}
   131  	return result, false
   132  }
   133  
   134  func (itr *BitmapIterator) HasNext() bool {
   135  	// maintain a bool var to avoid unnecessary calculations.
   136  	return itr.has_next
   137  }
   138  
   139  func (itr *BitmapIterator) PeekNext() uint64 {
   140  	if itr.has_next {
   141  		return itr.i
   142  	}
   143  	return 0
   144  }
   145  
   146  func (itr *BitmapIterator) Next() uint64 {
   147  	// When a iterator is initialized, the itr.i is set to the first rightmost_one pos.
   148  	// so current itr.i is a rightmost_one pos, cal the next one pos and return current pos.
   149  	pos := itr.i
   150  	if next, has_next := itr.hasNext(itr.i + 1); has_next { // itr.i + 1 to ignore bits check before
   151  		itr.i = next
   152  		itr.has_next = true
   153  		return pos
   154  	}
   155  	itr.has_next = false
   156  	return pos
   157  }
   158  
   159  // Reset set n.data to nil
   160  func (n *Bitmap) Reset() {
   161  	n.len = 0
   162  	n.emptyFlag.Store(kEmptyFlagEmpty)
   163  	n.data = nil
   164  }
   165  
   166  // Len returns the number of bits in the Bitmap.
   167  func (n *Bitmap) Len() int64 {
   168  	return n.len
   169  }
   170  
   171  // Size return number of bytes in n.data
   172  // XXX WTF Note that this size is not the same as InitWithSize.
   173  func (n *Bitmap) Size() int {
   174  	return len(n.data) * 8
   175  }
   176  
   177  func (n *Bitmap) Ptr() *uint64 {
   178  	if n == nil || len(n.data) == 0 {
   179  		return nil
   180  	}
   181  	return &n.data[0]
   182  }
   183  
   184  // EmptyByFlag is a quick and dirty way to check if the bitmap is empty.
   185  // If it retruns true, the bitmap is empty.  Otherwise, it may or may not be empty.
   186  func (n *Bitmap) EmptyByFlag() bool {
   187  	return n == nil || n.emptyFlag.Load() == kEmptyFlagEmpty || len(n.data) == 0
   188  }
   189  
   190  // IsEmpty returns true if no bit in the Bitmap is set, otherwise it will return false.
   191  func (n *Bitmap) IsEmpty() bool {
   192  	flag := n.emptyFlag.Load()
   193  	if flag == kEmptyFlagEmpty {
   194  		return true
   195  	} else if flag == kEmptyFlagNotEmpty {
   196  		return false
   197  	}
   198  	for i := 0; i < len(n.data); i++ {
   199  		if n.data[i] != 0 {
   200  			n.emptyFlag.Store(kEmptyFlagNotEmpty)
   201  			return false
   202  		}
   203  	}
   204  	n.emptyFlag.Store(kEmptyFlagEmpty)
   205  	return true
   206  }
   207  
   208  // We always assume that bitmap has been extended to at least row.
   209  func (n *Bitmap) Add(row uint64) {
   210  	n.data[row>>6] |= 1 << (row & 0x3F)
   211  	n.emptyFlag.Store(kEmptyFlagNotEmpty)
   212  }
   213  
   214  func (n *Bitmap) AddMany(rows []uint64) {
   215  	for _, row := range rows {
   216  		n.data[row>>6] |= 1 << (row & 0x3F)
   217  	}
   218  	n.emptyFlag.Store(kEmptyFlagNotEmpty)
   219  }
   220  
   221  func (n *Bitmap) Remove(row uint64) {
   222  	if row >= uint64(n.len) {
   223  		return
   224  	}
   225  	n.data[row>>6] &^= (uint64(1) << (row & 0x3F))
   226  	n.emptyFlag.CompareAndSwap(kEmptyFlagNotEmpty, kEmptyFlagUnknown)
   227  }
   228  
   229  // Contains returns true if the row is contained in the Bitmap
   230  func (n *Bitmap) Contains(row uint64) bool {
   231  	if row >= uint64(n.len) {
   232  		return false
   233  	}
   234  	idx := row >> 6
   235  	return (n.data[idx] & (1 << (row & 0x3F))) != 0
   236  }
   237  
   238  func (n *Bitmap) AddRange(start, end uint64) {
   239  	if start >= end {
   240  		return
   241  	}
   242  	i, j := start>>6, (end-1)>>6
   243  	if i == j {
   244  		n.data[i] |= (^uint64(0) << uint(start&0x3F)) & (^uint64(0) >> (uint(-end) & 0x3F))
   245  		n.emptyFlag.Store(kEmptyFlagNotEmpty)
   246  		return
   247  	}
   248  	n.data[i] |= (^uint64(0) << uint(start&0x3F))
   249  	for k := i + 1; k < j; k++ {
   250  		n.data[k] = ^uint64(0)
   251  	}
   252  	n.data[j] |= (^uint64(0) >> (uint(-end) & 0x3F))
   253  
   254  	n.emptyFlag.Store(kEmptyFlagNotEmpty)
   255  }
   256  
   257  func (n *Bitmap) RemoveRange(start, end uint64) {
   258  	if end > uint64(n.len) {
   259  		end = uint64(n.len)
   260  	}
   261  	if start >= end {
   262  		return
   263  	}
   264  	i, j := start>>6, (end-1)>>6
   265  	if i == j {
   266  		n.data[i] &= ^((^uint64(0) << uint(start&0x3F)) & (^uint64(0) >> (uint(-end) % 0x3F)))
   267  		n.emptyFlag.CompareAndSwap(kEmptyFlagNotEmpty, kEmptyFlagUnknown)
   268  		return
   269  	}
   270  	n.data[i] &= ^(^uint64(0) << uint(start&0x3F))
   271  	for k := i + 1; k < j; k++ {
   272  		n.data[k] = 0
   273  	}
   274  	n.data[j] &= ^(^uint64(0) >> (uint(-end) & 0x3F))
   275  	n.emptyFlag.CompareAndSwap(kEmptyFlagNotEmpty, kEmptyFlagUnknown)
   276  }
   277  
   278  func (n *Bitmap) IsSame(m *Bitmap) bool {
   279  	//if n.len != m.len ||
   280  	if len(m.data) != len(n.data) {
   281  		return false
   282  	}
   283  	for i := 0; i < len(n.data); i++ {
   284  		if n.data[i] != m.data[i] {
   285  			return false
   286  		}
   287  	}
   288  	return true
   289  }
   290  
   291  func (n *Bitmap) Or(m *Bitmap) {
   292  	n.TryExpand(m)
   293  	size := (int(m.len) + 63) / 64
   294  	for i := 0; i < size; i++ {
   295  		n.data[i] |= m.data[i]
   296  	}
   297  	n.emptyFlag.CompareAndSwap(kEmptyFlagEmpty, kEmptyFlagUnknown)
   298  }
   299  
   300  func (n *Bitmap) And(m *Bitmap) {
   301  	n.TryExpand(m)
   302  	size := (int(m.len) + 63) / 64
   303  	for i := 0; i < size; i++ {
   304  		n.data[i] &= m.data[i]
   305  	}
   306  	for i := size; i < len(n.data); i++ {
   307  		n.data[i] = 0
   308  	}
   309  	n.emptyFlag.CompareAndSwap(kEmptyFlagNotEmpty, kEmptyFlagUnknown)
   310  }
   311  
   312  func (n *Bitmap) Negate() {
   313  	nBlock, nTail := int(n.len)/64, int(n.len)%64
   314  	for i := 0; i < nBlock; i++ {
   315  		n.data[i] = ^n.data[i]
   316  	}
   317  	if nTail > 0 {
   318  		mask := (uint64(1) << nTail) - 1
   319  		n.data[nBlock] ^= mask
   320  	}
   321  }
   322  
   323  func (n *Bitmap) TryExpand(m *Bitmap) {
   324  	n.TryExpandWithSize(int(m.len))
   325  }
   326  
   327  func (n *Bitmap) TryExpandWithSize(size int) {
   328  	if int(n.len) >= size {
   329  		return
   330  	}
   331  	newCap := (size + 63) / 64
   332  	n.len = int64(size)
   333  	if newCap > cap(n.data) {
   334  		data := make([]uint64, newCap)
   335  		copy(data, n.data)
   336  		n.data = data
   337  		return
   338  	}
   339  	if len(n.data) < newCap {
   340  		n.data = n.data[:newCap]
   341  	}
   342  }
   343  
   344  func (n *Bitmap) Filter(sels []int64) *Bitmap {
   345  	var m Bitmap
   346  	m.InitWithSize(n.len)
   347  	for i, sel := range sels {
   348  		if n.Contains(uint64(sel)) {
   349  			m.Add(uint64(i))
   350  		}
   351  	}
   352  	return &m
   353  }
   354  
   355  func (n *Bitmap) Count() int {
   356  	var cnt int
   357  	if n.emptyFlag.Load() == kEmptyFlagEmpty { //must be empty
   358  		return 0
   359  	}
   360  	for i := int64(0); i < n.len/64; i++ {
   361  		cnt += bits.OnesCount64(n.data[i])
   362  	}
   363  	if offset := n.len % 64; offset > 0 {
   364  		start := (n.len / 64) * 64
   365  		for i, j := start, start+offset; i < j; i++ {
   366  			if n.Contains(uint64(i)) {
   367  				cnt++
   368  			}
   369  		}
   370  	}
   371  	if cnt > 0 {
   372  		n.emptyFlag.Store(kEmptyFlagNotEmpty)
   373  	} else {
   374  		n.emptyFlag.Store(kEmptyFlagEmpty)
   375  	}
   376  	return cnt
   377  }
   378  
   379  func (n *Bitmap) ToArray() []uint64 {
   380  	var rows []uint64
   381  	if n.EmptyByFlag() {
   382  		return rows
   383  	}
   384  
   385  	itr := n.Iterator()
   386  	for itr.HasNext() {
   387  		r := itr.Next()
   388  		rows = append(rows, r)
   389  	}
   390  	return rows
   391  }
   392  
   393  func (n *Bitmap) ToI64Arrary() []int64 {
   394  	var rows []int64
   395  	if n.EmptyByFlag() {
   396  		return rows
   397  	}
   398  
   399  	itr := n.Iterator()
   400  	for itr.HasNext() {
   401  		r := itr.Next()
   402  		rows = append(rows, int64(r))
   403  	}
   404  	return rows
   405  }
   406  
   407  func (n *Bitmap) Marshal() []byte {
   408  	var buf bytes.Buffer
   409  	flag := n.emptyFlag.Load()
   410  	u1 := uint64(n.len)
   411  	u2 := uint64(len(n.data) * 8)
   412  	buf.Write(types.EncodeInt32(&flag))
   413  	buf.Write(types.EncodeUint64(&u1))
   414  	buf.Write(types.EncodeUint64(&u2))
   415  	buf.Write(types.EncodeSlice(n.data))
   416  	return buf.Bytes()
   417  }
   418  
   419  func (n *Bitmap) Unmarshal(data []byte) {
   420  	n.emptyFlag.Store(types.DecodeInt32(data[:4]))
   421  	data = data[4:]
   422  	n.len = int64(types.DecodeUint64(data[:8]))
   423  	data = data[8:]
   424  	size := int(types.DecodeUint64(data[:8]))
   425  	data = data[8:]
   426  	if size == 0 {
   427  		n.data = nil
   428  	} else {
   429  		n.data = types.DecodeSlice[uint64](data[:size])
   430  	}
   431  }
   432  
   433  func (n *Bitmap) UnmarshalNoCopy(data []byte) {
   434  	n.emptyFlag.Store(types.DecodeInt32(data[:4]))
   435  	data = data[4:]
   436  	n.len = int64(types.DecodeUint64(data[:8]))
   437  	data = data[8:]
   438  	size := int(types.DecodeUint64(data[:8]))
   439  	data = data[8:]
   440  	if size == 0 {
   441  		n.data = nil
   442  	} else {
   443  		n.data = unsafe.Slice((*uint64)(unsafe.Pointer(&data[0])), size/8)
   444  	}
   445  }
   446  
   447  func (n *Bitmap) String() string {
   448  	return fmt.Sprintf("%v", n.ToArray())
   449  }
   450  
   451  var _ encoding.BinaryMarshaler = new(Bitmap)
   452  
   453  func (n *Bitmap) MarshalBinary() ([]byte, error) {
   454  	return n.Marshal(), nil
   455  }
   456  
   457  var _ encoding.BinaryUnmarshaler = new(Bitmap)
   458  
   459  func (n *Bitmap) UnmarshalBinary(data []byte) error {
   460  	n.Unmarshal(data)
   461  	return nil
   462  }