github.com/coyove/sdss@v0.0.0-20231129015646-c2ec58cca6a2/contrib/roaring/bitmapcontainer.go (about)

     1  package roaring
     2  
     3  import (
     4  	"fmt"
     5  	"unsafe"
     6  )
     7  
     8  type bitmapContainer struct {
     9  	cardinality int
    10  	bitmap      []uint64
    11  }
    12  
    13  func (bc bitmapContainer) String() string {
    14  	var s string
    15  	for it := bc.getShortIterator(); it.hasNext(); {
    16  		s += fmt.Sprintf("%v, ", it.next())
    17  	}
    18  	return s
    19  }
    20  
    21  func newBitmapContainer() *bitmapContainer {
    22  	p := new(bitmapContainer)
    23  	size := (1 << 16) / 64
    24  	p.bitmap = make([]uint64, size, size)
    25  	return p
    26  }
    27  
    28  func newBitmapContainerwithRange(firstOfRun, lastOfRun int) *bitmapContainer {
    29  	bc := newBitmapContainer()
    30  	bc.cardinality = lastOfRun - firstOfRun + 1
    31  	if bc.cardinality == maxCapacity {
    32  		fill(bc.bitmap, uint64(0xffffffffffffffff))
    33  	} else {
    34  		firstWord := firstOfRun / 64
    35  		lastWord := lastOfRun / 64
    36  		zeroPrefixLength := uint64(firstOfRun & 63)
    37  		zeroSuffixLength := uint64(63 - (lastOfRun & 63))
    38  
    39  		fillRange(bc.bitmap, firstWord, lastWord+1, uint64(0xffffffffffffffff))
    40  		bc.bitmap[firstWord] ^= ((uint64(1) << zeroPrefixLength) - 1)
    41  		blockOfOnes := (uint64(1) << zeroSuffixLength) - 1
    42  		maskOnLeft := blockOfOnes << (uint64(64) - zeroSuffixLength)
    43  		bc.bitmap[lastWord] ^= maskOnLeft
    44  	}
    45  	return bc
    46  }
    47  
    48  func (bc *bitmapContainer) minimum() uint16 {
    49  	for i := 0; i < len(bc.bitmap); i++ {
    50  		w := bc.bitmap[i]
    51  		if w != 0 {
    52  			r := countTrailingZeros(w)
    53  			return uint16(r + i*64)
    54  		}
    55  	}
    56  	return MaxUint16
    57  }
    58  
    59  // i should be non-zero
    60  func clz(i uint64) int {
    61  	n := 1
    62  	x := uint32(i >> 32)
    63  	if x == 0 {
    64  		n += 32
    65  		x = uint32(i)
    66  	}
    67  	if x>>16 == 0 {
    68  		n += 16
    69  		x = x << 16
    70  	}
    71  	if x>>24 == 0 {
    72  		n += 8
    73  		x = x << 8
    74  	}
    75  	if x>>28 == 0 {
    76  		n += 4
    77  		x = x << 4
    78  	}
    79  	if x>>30 == 0 {
    80  		n += 2
    81  		x = x << 2
    82  	}
    83  	return n - int(x>>31)
    84  }
    85  
    86  func (bc *bitmapContainer) maximum() uint16 {
    87  	for i := len(bc.bitmap); i > 0; i-- {
    88  		w := bc.bitmap[i-1]
    89  		if w != 0 {
    90  			r := clz(w)
    91  			return uint16((i-1)*64 + 63 - r)
    92  		}
    93  	}
    94  	return uint16(0)
    95  }
    96  
    97  func (bc *bitmapContainer) iterate(cb func(x uint16) bool) bool {
    98  	iterator := bitmapContainerShortIterator{bc, bc.NextSetBit(0)}
    99  
   100  	for iterator.hasNext() {
   101  		if !cb(iterator.next()) {
   102  			return false
   103  		}
   104  	}
   105  
   106  	return true
   107  }
   108  
   109  type bitmapContainerShortIterator struct {
   110  	ptr *bitmapContainer
   111  	i   int
   112  }
   113  
   114  func (bcsi *bitmapContainerShortIterator) next() uint16 {
   115  	j := bcsi.i
   116  	bcsi.i = bcsi.ptr.NextSetBit(uint(bcsi.i) + 1)
   117  	return uint16(j)
   118  }
   119  func (bcsi *bitmapContainerShortIterator) hasNext() bool {
   120  	return bcsi.i >= 0
   121  }
   122  
   123  func (bcsi *bitmapContainerShortIterator) peekNext() uint16 {
   124  	return uint16(bcsi.i)
   125  }
   126  
   127  func (bcsi *bitmapContainerShortIterator) advanceIfNeeded(minval uint16) {
   128  	if bcsi.hasNext() && bcsi.peekNext() < minval {
   129  		bcsi.i = bcsi.ptr.NextSetBit(uint(minval))
   130  	}
   131  }
   132  
   133  func newBitmapContainerShortIterator(a *bitmapContainer) *bitmapContainerShortIterator {
   134  	return &bitmapContainerShortIterator{a, a.NextSetBit(0)}
   135  }
   136  
   137  func (bc *bitmapContainer) getShortIterator() shortPeekable {
   138  	return newBitmapContainerShortIterator(bc)
   139  }
   140  
   141  type reverseBitmapContainerShortIterator struct {
   142  	ptr *bitmapContainer
   143  	i   int
   144  }
   145  
   146  func (bcsi *reverseBitmapContainerShortIterator) next() uint16 {
   147  	if bcsi.i == -1 {
   148  		panic("reverseBitmapContainerShortIterator.next() going beyond what is available")
   149  	}
   150  
   151  	j := bcsi.i
   152  	bcsi.i = bcsi.ptr.PrevSetBit(bcsi.i - 1)
   153  	return uint16(j)
   154  }
   155  
   156  func (bcsi *reverseBitmapContainerShortIterator) hasNext() bool {
   157  	return bcsi.i >= 0
   158  }
   159  
   160  func newReverseBitmapContainerShortIterator(a *bitmapContainer) *reverseBitmapContainerShortIterator {
   161  	if a.cardinality == 0 {
   162  		return &reverseBitmapContainerShortIterator{a, -1}
   163  	}
   164  	return &reverseBitmapContainerShortIterator{a, int(a.maximum())}
   165  }
   166  
   167  func (bc *bitmapContainer) getReverseIterator() shortIterable {
   168  	return newReverseBitmapContainerShortIterator(bc)
   169  }
   170  
   171  type bitmapContainerManyIterator struct {
   172  	ptr    *bitmapContainer
   173  	base   int
   174  	bitset uint64
   175  }
   176  
   177  func (bcmi *bitmapContainerManyIterator) nextMany(hs uint32, buf []uint32) int {
   178  	n := 0
   179  	base := bcmi.base
   180  	bitset := bcmi.bitset
   181  
   182  	for n < len(buf) {
   183  		if bitset == 0 {
   184  			base++
   185  			if base >= len(bcmi.ptr.bitmap) {
   186  				bcmi.base = base
   187  				bcmi.bitset = bitset
   188  				return n
   189  			}
   190  			bitset = bcmi.ptr.bitmap[base]
   191  			continue
   192  		}
   193  		t := bitset & -bitset
   194  		buf[n] = uint32(((base * 64) + int(popcount(t-1)))) | hs
   195  		n = n + 1
   196  		bitset ^= t
   197  	}
   198  
   199  	bcmi.base = base
   200  	bcmi.bitset = bitset
   201  	return n
   202  }
   203  
   204  func (bcmi *bitmapContainerManyIterator) nextMany64(hs uint64, buf []uint64) int {
   205  	n := 0
   206  	base := bcmi.base
   207  	bitset := bcmi.bitset
   208  
   209  	for n < len(buf) {
   210  		if bitset == 0 {
   211  			base++
   212  			if base >= len(bcmi.ptr.bitmap) {
   213  				bcmi.base = base
   214  				bcmi.bitset = bitset
   215  				return n
   216  			}
   217  			bitset = bcmi.ptr.bitmap[base]
   218  			continue
   219  		}
   220  		t := bitset & -bitset
   221  		buf[n] = uint64(((base * 64) + int(popcount(t-1)))) | hs
   222  		n = n + 1
   223  		bitset ^= t
   224  	}
   225  
   226  	bcmi.base = base
   227  	bcmi.bitset = bitset
   228  	return n
   229  }
   230  
   231  func newBitmapContainerManyIterator(a *bitmapContainer) *bitmapContainerManyIterator {
   232  	return &bitmapContainerManyIterator{a, -1, 0}
   233  }
   234  
   235  func (bc *bitmapContainer) getManyIterator() manyIterable {
   236  	return newBitmapContainerManyIterator(bc)
   237  }
   238  
   239  func (bc *bitmapContainer) getSizeInBytes() int {
   240  	return len(bc.bitmap) * 8 // + bcBaseBytes
   241  }
   242  
   243  func (bc *bitmapContainer) serializedSizeInBytes() int {
   244  	//return bc.Msgsize()// NOO! This breaks GetSerializedSizeInBytes
   245  	return len(bc.bitmap) * 8
   246  }
   247  
   248  const bcBaseBytes = int(unsafe.Sizeof(bitmapContainer{}))
   249  
   250  // bitmapContainer doesn't depend on card, always fully allocated
   251  func bitmapContainerSizeInBytes() int {
   252  	return bcBaseBytes + (1<<16)/8
   253  }
   254  
   255  func bitmapEquals(a, b []uint64) bool {
   256  	if len(a) != len(b) {
   257  		return false
   258  	}
   259  	for i, v := range a {
   260  		if v != b[i] {
   261  			return false
   262  		}
   263  	}
   264  	return true
   265  }
   266  
   267  func (bc *bitmapContainer) fillLeastSignificant16bits(x []uint32, i int, mask uint32) int {
   268  	// TODO: should be written as optimized assembly
   269  	pos := i
   270  	base := mask
   271  	for k := 0; k < len(bc.bitmap); k++ {
   272  		bitset := bc.bitmap[k]
   273  		for bitset != 0 {
   274  			t := bitset & -bitset
   275  			x[pos] = base + uint32(popcount(t-1))
   276  			pos++
   277  			bitset ^= t
   278  		}
   279  		base += 64
   280  	}
   281  	return pos
   282  }
   283  
   284  func (bc *bitmapContainer) equals(o container) bool {
   285  	srb, ok := o.(*bitmapContainer)
   286  	if ok {
   287  		if srb.cardinality != bc.cardinality {
   288  			return false
   289  		}
   290  		return bitmapEquals(bc.bitmap, srb.bitmap)
   291  	}
   292  
   293  	// use generic comparison
   294  	if bc.getCardinality() != o.getCardinality() {
   295  		return false
   296  	}
   297  	ait := o.getShortIterator()
   298  	bit := bc.getShortIterator()
   299  
   300  	for ait.hasNext() {
   301  		if bit.next() != ait.next() {
   302  			return false
   303  		}
   304  	}
   305  	return true
   306  }
   307  
   308  func (bc *bitmapContainer) iaddReturnMinimized(i uint16) container {
   309  	bc.iadd(i)
   310  	if bc.isFull() {
   311  		return newRunContainer16Range(0, MaxUint16)
   312  	}
   313  	return bc
   314  }
   315  
   316  func (bc *bitmapContainer) iadd(i uint16) bool {
   317  	x := int(i)
   318  	previous := bc.bitmap[x/64]
   319  	mask := uint64(1) << (uint(x) % 64)
   320  	newb := previous | mask
   321  	bc.bitmap[x/64] = newb
   322  	bc.cardinality += int((previous ^ newb) >> (uint(x) % 64))
   323  	return newb != previous
   324  }
   325  
   326  func (bc *bitmapContainer) iremoveReturnMinimized(i uint16) container {
   327  	if bc.iremove(i) {
   328  		if bc.cardinality == arrayDefaultMaxSize {
   329  			return bc.toArrayContainer()
   330  		}
   331  	}
   332  	return bc
   333  }
   334  
   335  // iremove returns true if i was found.
   336  func (bc *bitmapContainer) iremove(i uint16) bool {
   337  	if bc.contains(i) {
   338  		bc.cardinality--
   339  		bc.bitmap[i/64] &^= (uint64(1) << (i % 64))
   340  		return true
   341  	}
   342  	return false
   343  }
   344  
   345  func (bc *bitmapContainer) isFull() bool {
   346  	return bc.cardinality == int(MaxUint16)+1
   347  }
   348  
   349  func (bc *bitmapContainer) getCardinality() int {
   350  	return bc.cardinality
   351  }
   352  
   353  func (bc *bitmapContainer) isEmpty() bool {
   354  	return bc.cardinality == 0
   355  }
   356  
   357  func (bc *bitmapContainer) clone() container {
   358  	ptr := bitmapContainer{bc.cardinality, make([]uint64, len(bc.bitmap))}
   359  	copy(ptr.bitmap, bc.bitmap[:])
   360  	return &ptr
   361  }
   362  
   363  // add all values in range [firstOfRange,lastOfRange)
   364  func (bc *bitmapContainer) iaddRange(firstOfRange, lastOfRange int) container {
   365  	bc.cardinality += setBitmapRangeAndCardinalityChange(bc.bitmap, firstOfRange, lastOfRange)
   366  	return bc
   367  }
   368  
   369  // remove all values in range [firstOfRange,lastOfRange)
   370  func (bc *bitmapContainer) iremoveRange(firstOfRange, lastOfRange int) container {
   371  	bc.cardinality += resetBitmapRangeAndCardinalityChange(bc.bitmap, firstOfRange, lastOfRange)
   372  	if bc.getCardinality() <= arrayDefaultMaxSize {
   373  		return bc.toArrayContainer()
   374  	}
   375  	return bc
   376  }
   377  
   378  // flip all values in range [firstOfRange,endx)
   379  func (bc *bitmapContainer) inot(firstOfRange, endx int) container {
   380  	if endx-firstOfRange == maxCapacity {
   381  		flipBitmapRange(bc.bitmap, firstOfRange, endx)
   382  		bc.cardinality = maxCapacity - bc.cardinality
   383  	} else if endx-firstOfRange > maxCapacity/2 {
   384  		flipBitmapRange(bc.bitmap, firstOfRange, endx)
   385  		bc.computeCardinality()
   386  	} else {
   387  		bc.cardinality += flipBitmapRangeAndCardinalityChange(bc.bitmap, firstOfRange, endx)
   388  	}
   389  	if bc.getCardinality() <= arrayDefaultMaxSize {
   390  		return bc.toArrayContainer()
   391  	}
   392  	return bc
   393  }
   394  
   395  // flip all values in range [firstOfRange,endx)
   396  func (bc *bitmapContainer) not(firstOfRange, endx int) container {
   397  	answer := bc.clone()
   398  	return answer.inot(firstOfRange, endx)
   399  }
   400  
   401  func (bc *bitmapContainer) or(a container) container {
   402  	switch x := a.(type) {
   403  	case *arrayContainer:
   404  		return bc.orArray(x)
   405  	case *bitmapContainer:
   406  		return bc.orBitmap(x)
   407  	case *runContainer16:
   408  		if x.isFull() {
   409  			return x.clone()
   410  		}
   411  		return x.orBitmapContainer(bc)
   412  	}
   413  	panic("unsupported container type")
   414  }
   415  
   416  func (bc *bitmapContainer) orCardinality(a container) int {
   417  	switch x := a.(type) {
   418  	case *arrayContainer:
   419  		return bc.orArrayCardinality(x)
   420  	case *bitmapContainer:
   421  		return bc.orBitmapCardinality(x)
   422  	case *runContainer16:
   423  		return x.orBitmapContainerCardinality(bc)
   424  	}
   425  	panic("unsupported container type")
   426  }
   427  
   428  func (bc *bitmapContainer) ior(a container) container {
   429  	switch x := a.(type) {
   430  	case *arrayContainer:
   431  		return bc.iorArray(x)
   432  	case *bitmapContainer:
   433  		return bc.iorBitmap(x)
   434  	case *runContainer16:
   435  		if x.isFull() {
   436  			return x.clone()
   437  		}
   438  		for i := range x.iv {
   439  			bc.iaddRange(int(x.iv[i].start), int(x.iv[i].last())+1)
   440  		}
   441  		if bc.isFull() {
   442  			return newRunContainer16Range(0, MaxUint16)
   443  		}
   444  		//bc.computeCardinality()
   445  		return bc
   446  	}
   447  	panic(fmt.Errorf("unsupported container type %T", a))
   448  }
   449  
   450  func (bc *bitmapContainer) lazyIOR(a container) container {
   451  	switch x := a.(type) {
   452  	case *arrayContainer:
   453  		return bc.lazyIORArray(x)
   454  	case *bitmapContainer:
   455  		return bc.lazyIORBitmap(x)
   456  	case *runContainer16:
   457  		if x.isFull() {
   458  			return x.clone()
   459  		}
   460  
   461  		// Manually inlined setBitmapRange function
   462  		bitmap := bc.bitmap
   463  		for _, iv := range x.iv {
   464  			start := int(iv.start)
   465  			end := int(iv.last()) + 1
   466  			if start >= end {
   467  				continue
   468  			}
   469  			firstword := start / 64
   470  			endword := (end - 1) / 64
   471  			if firstword == endword {
   472  				bitmap[firstword] |= (^uint64(0) << uint(start%64)) & (^uint64(0) >> (uint(-end) % 64))
   473  				continue
   474  			}
   475  			bitmap[firstword] |= ^uint64(0) << uint(start%64)
   476  			for i := firstword + 1; i < endword; i++ {
   477  				bitmap[i] = ^uint64(0)
   478  			}
   479  			bitmap[endword] |= ^uint64(0) >> (uint(-end) % 64)
   480  		}
   481  		bc.cardinality = invalidCardinality
   482  		return bc
   483  	}
   484  	panic("unsupported container type")
   485  }
   486  
   487  func (bc *bitmapContainer) lazyOR(a container) container {
   488  	switch x := a.(type) {
   489  	case *arrayContainer:
   490  		return bc.lazyORArray(x)
   491  	case *bitmapContainer:
   492  		return bc.lazyORBitmap(x)
   493  	case *runContainer16:
   494  		if x.isFull() {
   495  			return x.clone()
   496  		}
   497  		// TODO: implement lazy OR
   498  		return x.orBitmapContainer(bc)
   499  
   500  	}
   501  	panic("unsupported container type")
   502  }
   503  
   504  func (bc *bitmapContainer) orArray(value2 *arrayContainer) container {
   505  	answer := bc.clone().(*bitmapContainer)
   506  	c := value2.getCardinality()
   507  	for k := 0; k < c; k++ {
   508  		v := value2.content[k]
   509  		i := uint(v) >> 6
   510  		bef := answer.bitmap[i]
   511  		aft := bef | (uint64(1) << (v % 64))
   512  		answer.bitmap[i] = aft
   513  		answer.cardinality += int((bef - aft) >> 63)
   514  	}
   515  	return answer
   516  }
   517  
   518  func (bc *bitmapContainer) orArrayCardinality(value2 *arrayContainer) int {
   519  	answer := 0
   520  	c := value2.getCardinality()
   521  	for k := 0; k < c; k++ {
   522  		// branchless:
   523  		v := value2.content[k]
   524  		i := uint(v) >> 6
   525  		bef := bc.bitmap[i]
   526  		aft := bef | (uint64(1) << (v % 64))
   527  		answer += int((bef - aft) >> 63)
   528  	}
   529  	return answer
   530  }
   531  
   532  func (bc *bitmapContainer) orBitmap(value2 *bitmapContainer) container {
   533  	answer := newBitmapContainer()
   534  	for k := 0; k < len(answer.bitmap); k++ {
   535  		answer.bitmap[k] = bc.bitmap[k] | value2.bitmap[k]
   536  	}
   537  	answer.computeCardinality()
   538  	if answer.isFull() {
   539  		return newRunContainer16Range(0, MaxUint16)
   540  	}
   541  	return answer
   542  }
   543  
   544  func (bc *bitmapContainer) orBitmapCardinality(value2 *bitmapContainer) int {
   545  	return int(popcntOrSlice(bc.bitmap, value2.bitmap))
   546  }
   547  
   548  func (bc *bitmapContainer) andBitmapCardinality(value2 *bitmapContainer) int {
   549  	return int(popcntAndSlice(bc.bitmap, value2.bitmap))
   550  }
   551  
   552  func (bc *bitmapContainer) computeCardinality() {
   553  	bc.cardinality = int(popcntSlice(bc.bitmap))
   554  }
   555  
   556  func (bc *bitmapContainer) iorArray(ac *arrayContainer) container {
   557  	for k := range ac.content {
   558  		vc := ac.content[k]
   559  		i := uint(vc) >> 6
   560  		bef := bc.bitmap[i]
   561  		aft := bef | (uint64(1) << (vc % 64))
   562  		bc.bitmap[i] = aft
   563  		bc.cardinality += int((bef - aft) >> 63)
   564  	}
   565  	if bc.isFull() {
   566  		return newRunContainer16Range(0, MaxUint16)
   567  	}
   568  	return bc
   569  }
   570  
   571  func (bc *bitmapContainer) iorBitmap(value2 *bitmapContainer) container {
   572  	answer := bc
   573  	answer.cardinality = 0
   574  	for k := 0; k < len(answer.bitmap); k++ {
   575  		answer.bitmap[k] = bc.bitmap[k] | value2.bitmap[k]
   576  	}
   577  	answer.computeCardinality()
   578  	if bc.isFull() {
   579  		return newRunContainer16Range(0, MaxUint16)
   580  	}
   581  	return answer
   582  }
   583  
   584  func (bc *bitmapContainer) lazyIORArray(value2 *arrayContainer) container {
   585  	answer := bc
   586  	c := value2.getCardinality()
   587  	for k := 0; k+3 < c; k += 4 {
   588  		content := (*[4]uint16)(unsafe.Pointer(&value2.content[k]))
   589  		vc0 := content[0]
   590  		i0 := uint(vc0) >> 6
   591  		answer.bitmap[i0] = answer.bitmap[i0] | (uint64(1) << (vc0 % 64))
   592  
   593  		vc1 := content[1]
   594  		i1 := uint(vc1) >> 6
   595  		answer.bitmap[i1] = answer.bitmap[i1] | (uint64(1) << (vc1 % 64))
   596  
   597  		vc2 := content[2]
   598  		i2 := uint(vc2) >> 6
   599  		answer.bitmap[i2] = answer.bitmap[i2] | (uint64(1) << (vc2 % 64))
   600  
   601  		vc3 := content[3]
   602  		i3 := uint(vc3) >> 6
   603  		answer.bitmap[i3] = answer.bitmap[i3] | (uint64(1) << (vc3 % 64))
   604  	}
   605  
   606  	for k := c &^ 3; k < c; k++ {
   607  		vc := value2.content[k]
   608  		i := uint(vc) >> 6
   609  		answer.bitmap[i] = answer.bitmap[i] | (uint64(1) << (vc % 64))
   610  	}
   611  
   612  	answer.cardinality = invalidCardinality
   613  	return answer
   614  }
   615  
   616  func (bc *bitmapContainer) lazyORArray(value2 *arrayContainer) container {
   617  	answer := bc.clone().(*bitmapContainer)
   618  	return answer.lazyIORArray(value2)
   619  }
   620  
   621  func (bc *bitmapContainer) lazyIORBitmap(value2 *bitmapContainer) container {
   622  	answer := bc
   623  	for k := 0; k < len(answer.bitmap); k++ {
   624  		answer.bitmap[k] = bc.bitmap[k] | value2.bitmap[k]
   625  	}
   626  	bc.cardinality = invalidCardinality
   627  	return answer
   628  }
   629  
   630  func (bc *bitmapContainer) lazyORBitmap(value2 *bitmapContainer) container {
   631  	answer := bc.clone().(*bitmapContainer)
   632  	return answer.lazyIORBitmap(value2)
   633  }
   634  
   635  func (bc *bitmapContainer) xor(a container) container {
   636  	switch x := a.(type) {
   637  	case *arrayContainer:
   638  		return bc.xorArray(x)
   639  	case *bitmapContainer:
   640  		return bc.xorBitmap(x)
   641  	case *runContainer16:
   642  		return x.xorBitmap(bc)
   643  	}
   644  	panic("unsupported container type")
   645  }
   646  
   647  func (bc *bitmapContainer) xorArray(value2 *arrayContainer) container {
   648  	answer := bc.clone().(*bitmapContainer)
   649  	c := value2.getCardinality()
   650  	for k := 0; k < c; k++ {
   651  		vc := value2.content[k]
   652  		index := uint(vc) >> 6
   653  		abi := answer.bitmap[index]
   654  		mask := uint64(1) << (vc % 64)
   655  		answer.cardinality += 1 - 2*int((abi&mask)>>(vc%64))
   656  		answer.bitmap[index] = abi ^ mask
   657  	}
   658  	if answer.cardinality <= arrayDefaultMaxSize {
   659  		return answer.toArrayContainer()
   660  	}
   661  	return answer
   662  }
   663  
   664  func (bc *bitmapContainer) rank(x uint16) int {
   665  	// TODO: rewrite in assembly
   666  	leftover := (uint(x) + 1) & 63
   667  	if leftover == 0 {
   668  		return int(popcntSlice(bc.bitmap[:(uint(x)+1)/64]))
   669  	}
   670  	return int(popcntSlice(bc.bitmap[:(uint(x)+1)/64]) + popcount(bc.bitmap[(uint(x)+1)/64]<<(64-leftover)))
   671  }
   672  
   673  func (bc *bitmapContainer) selectInt(x uint16) int {
   674  	remaining := x
   675  	for k := 0; k < len(bc.bitmap); k++ {
   676  		w := popcount(bc.bitmap[k])
   677  		if uint16(w) > remaining {
   678  			return k*64 + selectBitPosition(bc.bitmap[k], int(remaining))
   679  		}
   680  		remaining -= uint16(w)
   681  	}
   682  	return -1
   683  }
   684  
   685  func (bc *bitmapContainer) xorBitmap(value2 *bitmapContainer) container {
   686  	newCardinality := int(popcntXorSlice(bc.bitmap, value2.bitmap))
   687  
   688  	if newCardinality > arrayDefaultMaxSize {
   689  		answer := newBitmapContainer()
   690  		for k := 0; k < len(answer.bitmap); k++ {
   691  			answer.bitmap[k] = bc.bitmap[k] ^ value2.bitmap[k]
   692  		}
   693  		answer.cardinality = newCardinality
   694  		if answer.isFull() {
   695  			return newRunContainer16Range(0, MaxUint16)
   696  		}
   697  		return answer
   698  	}
   699  	ac := newArrayContainerSize(newCardinality)
   700  	fillArrayXOR(ac.content, bc.bitmap, value2.bitmap)
   701  	ac.content = ac.content[:newCardinality]
   702  	return ac
   703  }
   704  
   705  func (bc *bitmapContainer) and(a container) container {
   706  	switch x := a.(type) {
   707  	case *arrayContainer:
   708  		return bc.andArray(x)
   709  	case *bitmapContainer:
   710  		return bc.andBitmap(x)
   711  	case *runContainer16:
   712  		if x.isFull() {
   713  			return bc.clone()
   714  		}
   715  		return x.andBitmapContainer(bc)
   716  	}
   717  	panic("unsupported container type")
   718  }
   719  
   720  func (bc *bitmapContainer) andCardinality(a container) int {
   721  	switch x := a.(type) {
   722  	case *arrayContainer:
   723  		return bc.andArrayCardinality(x)
   724  	case *bitmapContainer:
   725  		return bc.andBitmapCardinality(x)
   726  	case *runContainer16:
   727  		return x.andBitmapContainerCardinality(bc)
   728  	}
   729  	panic("unsupported container type")
   730  }
   731  
   732  func (bc *bitmapContainer) intersects(a container) bool {
   733  	switch x := a.(type) {
   734  	case *arrayContainer:
   735  		return bc.intersectsArray(x)
   736  	case *bitmapContainer:
   737  		return bc.intersectsBitmap(x)
   738  	case *runContainer16:
   739  		return x.intersects(bc)
   740  
   741  	}
   742  	panic("unsupported container type")
   743  }
   744  
   745  func (bc *bitmapContainer) iand(a container) container {
   746  	switch x := a.(type) {
   747  	case *arrayContainer:
   748  		return bc.iandArray(x)
   749  	case *bitmapContainer:
   750  		return bc.iandBitmap(x)
   751  	case *runContainer16:
   752  		if x.isFull() {
   753  			return bc.clone()
   754  		}
   755  		return bc.iandRun16(x)
   756  	}
   757  	panic("unsupported container type")
   758  }
   759  
   760  func (bc *bitmapContainer) iandRun16(rc *runContainer16) container {
   761  	rcb := newBitmapContainerFromRun(rc)
   762  	return bc.iandBitmap(rcb)
   763  }
   764  
   765  func (bc *bitmapContainer) iandArray(ac *arrayContainer) container {
   766  	acb := ac.toBitmapContainer()
   767  	return bc.iandBitmap(acb)
   768  }
   769  
   770  func (bc *bitmapContainer) andArray(value2 *arrayContainer) *arrayContainer {
   771  	answer := newArrayContainerCapacity(len(value2.content))
   772  	answer.content = answer.content[:cap(answer.content)]
   773  	c := value2.getCardinality()
   774  	pos := 0
   775  	for k := 0; k < c; k++ {
   776  		v := value2.content[k]
   777  		answer.content[pos] = v
   778  		pos += int(bc.bitValue(v))
   779  	}
   780  	answer.content = answer.content[:pos]
   781  	return answer
   782  }
   783  
   784  func (bc *bitmapContainer) andArrayCardinality(value2 *arrayContainer) int {
   785  	c := value2.getCardinality()
   786  	pos := 0
   787  	for k := 0; k < c; k++ {
   788  		v := value2.content[k]
   789  		pos += int(bc.bitValue(v))
   790  	}
   791  	return pos
   792  }
   793  
   794  func (bc *bitmapContainer) getCardinalityInRange(start, end uint) int {
   795  	if start >= end {
   796  		return 0
   797  	}
   798  	firstword := start / 64
   799  	endword := (end - 1) / 64
   800  	const allones = ^uint64(0)
   801  	if firstword == endword {
   802  		return int(popcount(bc.bitmap[firstword] & ((allones << (start % 64)) & (allones >> ((64 - end) & 63)))))
   803  	}
   804  	answer := popcount(bc.bitmap[firstword] & (allones << (start % 64)))
   805  	answer += popcntSlice(bc.bitmap[firstword+1 : endword])
   806  	answer += popcount(bc.bitmap[endword] & (allones >> ((64 - end) & 63)))
   807  	return int(answer)
   808  }
   809  
   810  func (bc *bitmapContainer) andBitmap(value2 *bitmapContainer) container {
   811  	newcardinality := int(popcntAndSlice(bc.bitmap, value2.bitmap))
   812  	if newcardinality > arrayDefaultMaxSize {
   813  		answer := newBitmapContainer()
   814  		for k := 0; k < len(answer.bitmap); k++ {
   815  			answer.bitmap[k] = bc.bitmap[k] & value2.bitmap[k]
   816  		}
   817  		answer.cardinality = newcardinality
   818  		return answer
   819  	}
   820  	ac := newArrayContainerSize(newcardinality)
   821  	fillArrayAND(ac.content, bc.bitmap, value2.bitmap)
   822  	ac.content = ac.content[:newcardinality] //not sure why i need this
   823  	return ac
   824  
   825  }
   826  
   827  func (bc *bitmapContainer) intersectsArray(value2 *arrayContainer) bool {
   828  	c := value2.getCardinality()
   829  	for k := 0; k < c; k++ {
   830  		v := value2.content[k]
   831  		if bc.contains(v) {
   832  			return true
   833  		}
   834  	}
   835  	return false
   836  }
   837  
   838  func (bc *bitmapContainer) intersectsBitmap(value2 *bitmapContainer) bool {
   839  	for k := 0; k < len(bc.bitmap); k++ {
   840  		if (bc.bitmap[k] & value2.bitmap[k]) != 0 {
   841  			return true
   842  		}
   843  	}
   844  	return false
   845  
   846  }
   847  
   848  func (bc *bitmapContainer) iandBitmap(value2 *bitmapContainer) container {
   849  	newcardinality := int(popcntAndSlice(bc.bitmap, value2.bitmap))
   850  	for k := 0; k < len(bc.bitmap); k++ {
   851  		bc.bitmap[k] = bc.bitmap[k] & value2.bitmap[k]
   852  	}
   853  	bc.cardinality = newcardinality
   854  
   855  	if newcardinality <= arrayDefaultMaxSize {
   856  		return newArrayContainerFromBitmap(bc)
   857  	}
   858  	return bc
   859  }
   860  
   861  func (bc *bitmapContainer) andNot(a container) container {
   862  	switch x := a.(type) {
   863  	case *arrayContainer:
   864  		return bc.andNotArray(x)
   865  	case *bitmapContainer:
   866  		return bc.andNotBitmap(x)
   867  	case *runContainer16:
   868  		return bc.andNotRun16(x)
   869  	}
   870  	panic("unsupported container type")
   871  }
   872  
   873  func (bc *bitmapContainer) andNotRun16(rc *runContainer16) container {
   874  	rcb := rc.toBitmapContainer()
   875  	return bc.andNotBitmap(rcb)
   876  }
   877  
   878  func (bc *bitmapContainer) iandNot(a container) container {
   879  	switch x := a.(type) {
   880  	case *arrayContainer:
   881  		return bc.iandNotArray(x)
   882  	case *bitmapContainer:
   883  		return bc.iandNotBitmapSurely(x)
   884  	case *runContainer16:
   885  		return bc.iandNotRun16(x)
   886  	}
   887  	panic("unsupported container type")
   888  }
   889  
   890  func (bc *bitmapContainer) iandNotArray(ac *arrayContainer) container {
   891  	acb := ac.toBitmapContainer()
   892  	return bc.iandNotBitmapSurely(acb)
   893  }
   894  
   895  func (bc *bitmapContainer) iandNotRun16(rc *runContainer16) container {
   896  	rcb := rc.toBitmapContainer()
   897  	return bc.iandNotBitmapSurely(rcb)
   898  }
   899  
   900  func (bc *bitmapContainer) andNotArray(value2 *arrayContainer) container {
   901  	answer := bc.clone().(*bitmapContainer)
   902  	c := value2.getCardinality()
   903  	for k := 0; k < c; k++ {
   904  		vc := value2.content[k]
   905  		i := uint(vc) >> 6
   906  		oldv := answer.bitmap[i]
   907  		newv := oldv &^ (uint64(1) << (vc % 64))
   908  		answer.bitmap[i] = newv
   909  		answer.cardinality -= int((oldv ^ newv) >> (vc % 64))
   910  	}
   911  	if answer.cardinality <= arrayDefaultMaxSize {
   912  		return answer.toArrayContainer()
   913  	}
   914  	return answer
   915  }
   916  
   917  func (bc *bitmapContainer) andNotBitmap(value2 *bitmapContainer) container {
   918  	newCardinality := int(popcntMaskSlice(bc.bitmap, value2.bitmap))
   919  	if newCardinality > arrayDefaultMaxSize {
   920  		answer := newBitmapContainer()
   921  		for k := 0; k < len(answer.bitmap); k++ {
   922  			answer.bitmap[k] = bc.bitmap[k] &^ value2.bitmap[k]
   923  		}
   924  		answer.cardinality = newCardinality
   925  		return answer
   926  	}
   927  	ac := newArrayContainerSize(newCardinality)
   928  	fillArrayANDNOT(ac.content, bc.bitmap, value2.bitmap)
   929  	return ac
   930  }
   931  
   932  func (bc *bitmapContainer) iandNotBitmapSurely(value2 *bitmapContainer) container {
   933  	newCardinality := int(popcntMaskSlice(bc.bitmap, value2.bitmap))
   934  	for k := 0; k < len(bc.bitmap); k++ {
   935  		bc.bitmap[k] = bc.bitmap[k] &^ value2.bitmap[k]
   936  	}
   937  	bc.cardinality = newCardinality
   938  	if bc.getCardinality() <= arrayDefaultMaxSize {
   939  		return bc.toArrayContainer()
   940  	}
   941  	return bc
   942  }
   943  
   944  func (bc *bitmapContainer) contains(i uint16) bool { //testbit
   945  	x := uint(i)
   946  	w := bc.bitmap[x>>6]
   947  	mask := uint64(1) << (x & 63)
   948  	return (w & mask) != 0
   949  }
   950  
   951  func (bc *bitmapContainer) bitValue(i uint16) uint64 {
   952  	x := uint(i)
   953  	w := bc.bitmap[x>>6]
   954  	return (w >> (x & 63)) & 1
   955  }
   956  
   957  func (bc *bitmapContainer) loadData(arrayContainer *arrayContainer) {
   958  	bc.cardinality = arrayContainer.getCardinality()
   959  	c := arrayContainer.getCardinality()
   960  	for k := 0; k < c; k++ {
   961  		x := arrayContainer.content[k]
   962  		i := int(x) / 64
   963  		bc.bitmap[i] |= (uint64(1) << uint(x%64))
   964  	}
   965  }
   966  
   967  func (bc *bitmapContainer) resetTo(a container) {
   968  	switch x := a.(type) {
   969  	case *arrayContainer:
   970  		fill(bc.bitmap, 0)
   971  		bc.loadData(x)
   972  
   973  	case *bitmapContainer:
   974  		bc.cardinality = x.cardinality
   975  		copy(bc.bitmap, x.bitmap)
   976  
   977  	case *runContainer16:
   978  		bc.cardinality = len(x.iv)
   979  		lastEnd := 0
   980  		for _, r := range x.iv {
   981  			bc.cardinality += int(r.length)
   982  			resetBitmapRange(bc.bitmap, lastEnd, int(r.start))
   983  			lastEnd = int(r.start+r.length) + 1
   984  			setBitmapRange(bc.bitmap, int(r.start), lastEnd)
   985  		}
   986  		resetBitmapRange(bc.bitmap, lastEnd, maxCapacity)
   987  
   988  	default:
   989  		panic("unsupported container type")
   990  	}
   991  }
   992  
   993  func (bc *bitmapContainer) toArrayContainer() *arrayContainer {
   994  	ac := &arrayContainer{}
   995  	ac.loadData(bc)
   996  	return ac
   997  }
   998  
   999  func (bc *bitmapContainer) fillArray(container []uint16) {
  1000  	//TODO: rewrite in assembly
  1001  	pos := 0
  1002  	base := 0
  1003  	for k := 0; k < len(bc.bitmap); k++ {
  1004  		bitset := bc.bitmap[k]
  1005  		for bitset != 0 {
  1006  			t := bitset & -bitset
  1007  			container[pos] = uint16((base + int(popcount(t-1))))
  1008  			pos = pos + 1
  1009  			bitset ^= t
  1010  		}
  1011  		base += 64
  1012  	}
  1013  }
  1014  
  1015  func (bc *bitmapContainer) NextSetBit(i uint) int {
  1016  	var (
  1017  		x      = i / 64
  1018  		length = uint(len(bc.bitmap))
  1019  	)
  1020  	if x >= length {
  1021  		return -1
  1022  	}
  1023  	w := bc.bitmap[x]
  1024  	w = w >> uint(i%64)
  1025  	if w != 0 {
  1026  		return int(i) + countTrailingZeros(w)
  1027  	}
  1028  	x++
  1029  	for ; x < length; x++ {
  1030  		if bc.bitmap[x] != 0 {
  1031  			return int(x*64) + countTrailingZeros(bc.bitmap[x])
  1032  		}
  1033  	}
  1034  	return -1
  1035  }
  1036  
  1037  func (bc *bitmapContainer) PrevSetBit(i int) int {
  1038  	if i < 0 {
  1039  		return -1
  1040  	}
  1041  	x := i / 64
  1042  	if x >= len(bc.bitmap) {
  1043  		return -1
  1044  	}
  1045  
  1046  	w := bc.bitmap[x]
  1047  
  1048  	b := i % 64
  1049  
  1050  	w = w << uint(63-b)
  1051  	if w != 0 {
  1052  		return i - countLeadingZeros(w)
  1053  	}
  1054  	x--
  1055  	for ; x >= 0; x-- {
  1056  		if bc.bitmap[x] != 0 {
  1057  			return (x * 64) + 63 - countLeadingZeros(bc.bitmap[x])
  1058  		}
  1059  	}
  1060  	return -1
  1061  }
  1062  
  1063  // reference the java implementation
  1064  // https://github.com/RoaringBitmap/RoaringBitmap/blob/master/src/main/java/org/roaringbitmap/BitmapContainer.java#L875-L892
  1065  //
  1066  func (bc *bitmapContainer) numberOfRuns() int {
  1067  	if bc.cardinality == 0 {
  1068  		return 0
  1069  	}
  1070  
  1071  	var numRuns uint64
  1072  	nextWord := bc.bitmap[0]
  1073  
  1074  	for i := 0; i < len(bc.bitmap)-1; i++ {
  1075  		word := nextWord
  1076  		nextWord = bc.bitmap[i+1]
  1077  		numRuns += popcount((^word)&(word<<1)) + ((word >> 63) &^ nextWord)
  1078  	}
  1079  
  1080  	word := nextWord
  1081  	numRuns += popcount((^word) & (word << 1))
  1082  	if (word & 0x8000000000000000) != 0 {
  1083  		numRuns++
  1084  	}
  1085  
  1086  	return int(numRuns)
  1087  }
  1088  
  1089  // convert to run or array *if needed*
  1090  func (bc *bitmapContainer) toEfficientContainer() container {
  1091  
  1092  	numRuns := bc.numberOfRuns()
  1093  
  1094  	sizeAsRunContainer := runContainer16SerializedSizeInBytes(numRuns)
  1095  	sizeAsBitmapContainer := bitmapContainerSizeInBytes()
  1096  	card := bc.getCardinality()
  1097  	sizeAsArrayContainer := arrayContainerSizeInBytes(card)
  1098  
  1099  	if sizeAsRunContainer <= minOfInt(sizeAsBitmapContainer, sizeAsArrayContainer) {
  1100  		return newRunContainer16FromBitmapContainer(bc)
  1101  	}
  1102  	if card <= arrayDefaultMaxSize {
  1103  		return bc.toArrayContainer()
  1104  	}
  1105  	return bc
  1106  }
  1107  
  1108  func newBitmapContainerFromRun(rc *runContainer16) *bitmapContainer {
  1109  
  1110  	if len(rc.iv) == 1 {
  1111  		return newBitmapContainerwithRange(int(rc.iv[0].start), int(rc.iv[0].last()))
  1112  	}
  1113  
  1114  	bc := newBitmapContainer()
  1115  	for i := range rc.iv {
  1116  		setBitmapRange(bc.bitmap, int(rc.iv[i].start), int(rc.iv[i].last())+1)
  1117  		bc.cardinality += int(rc.iv[i].last()) + 1 - int(rc.iv[i].start)
  1118  	}
  1119  	//bc.computeCardinality()
  1120  	return bc
  1121  }
  1122  
  1123  func (bc *bitmapContainer) containerType() contype {
  1124  	return bitmapContype
  1125  }
  1126  
  1127  func (bc *bitmapContainer) addOffset(x uint16) (container, container) {
  1128  	var low, high *bitmapContainer
  1129  
  1130  	if bc.cardinality == 0 {
  1131  		return nil, nil
  1132  	}
  1133  
  1134  	b := uint32(x) >> 6
  1135  	i := uint32(x) % 64
  1136  	end := uint32(1024) - b
  1137  
  1138  	low = newBitmapContainer()
  1139  	if i == 0 {
  1140  		copy(low.bitmap[b:], bc.bitmap[:end])
  1141  	} else {
  1142  		low.bitmap[b] = bc.bitmap[0] << i
  1143  		for k := uint32(1); k < end; k++ {
  1144  			newval := bc.bitmap[k] << i
  1145  			newval |= bc.bitmap[k-1] >> (64 - i)
  1146  			low.bitmap[b+k] = newval
  1147  		}
  1148  	}
  1149  	low.computeCardinality()
  1150  
  1151  	if low.cardinality == bc.cardinality {
  1152  		// All elements from bc ended up in low, meaning high will be empty.
  1153  		return low, nil
  1154  	}
  1155  
  1156  	if low.cardinality == 0 {
  1157  		// low is empty, let's reuse the container for high.
  1158  		high = low
  1159  		low = nil
  1160  	} else {
  1161  		// None of the containers will be empty, so allocate both.
  1162  		high = newBitmapContainer()
  1163  	}
  1164  
  1165  	if i == 0 {
  1166  		copy(high.bitmap[:b], bc.bitmap[end:])
  1167  	} else {
  1168  		for k := end; k < 1024; k++ {
  1169  			newval := bc.bitmap[k] << i
  1170  			newval |= bc.bitmap[k-1] >> (64 - i)
  1171  			high.bitmap[k-end] = newval
  1172  		}
  1173  		high.bitmap[b] = bc.bitmap[1023] >> (64 - i)
  1174  	}
  1175  	high.computeCardinality()
  1176  
  1177  	// Ensure proper nil interface.
  1178  	if low == nil {
  1179  		return nil, high
  1180  	}
  1181  
  1182  	return low, high
  1183  }