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

     1  package roaring
     2  
     3  import (
     4  	"fmt"
     5  )
     6  
     7  type arrayContainer struct {
     8  	content []uint16
     9  }
    10  
    11  func (ac *arrayContainer) String() string {
    12  	s := "{"
    13  	for it := ac.getShortIterator(); it.hasNext(); {
    14  		s += fmt.Sprintf("%v, ", it.next())
    15  	}
    16  	return s + "}"
    17  }
    18  
    19  func (ac *arrayContainer) fillLeastSignificant16bits(x []uint32, i int, mask uint32) int {
    20  	for k := 0; k < len(ac.content); k++ {
    21  		x[k+i] = uint32(ac.content[k]) | mask
    22  	}
    23  	return i + len(ac.content)
    24  }
    25  
    26  func (ac *arrayContainer) iterate(cb func(x uint16) bool) bool {
    27  	iterator := shortIterator{ac.content, 0}
    28  
    29  	for iterator.hasNext() {
    30  		if !cb(iterator.next()) {
    31  			return false
    32  		}
    33  	}
    34  
    35  	return true
    36  }
    37  
    38  func (ac *arrayContainer) getShortIterator() shortPeekable {
    39  	return &shortIterator{ac.content, 0}
    40  }
    41  
    42  func (ac *arrayContainer) getReverseIterator() shortIterable {
    43  	return &reverseIterator{ac.content, len(ac.content) - 1}
    44  }
    45  
    46  func (ac *arrayContainer) getManyIterator() manyIterable {
    47  	return &shortIterator{ac.content, 0}
    48  }
    49  
    50  func (ac *arrayContainer) minimum() uint16 {
    51  	return ac.content[0] // assume not empty
    52  }
    53  
    54  func (ac *arrayContainer) maximum() uint16 {
    55  	return ac.content[len(ac.content)-1] // assume not empty
    56  }
    57  
    58  func (ac *arrayContainer) getSizeInBytes() int {
    59  	return ac.getCardinality() * 2
    60  }
    61  
    62  func (ac *arrayContainer) serializedSizeInBytes() int {
    63  	return ac.getCardinality() * 2
    64  }
    65  
    66  func arrayContainerSizeInBytes(card int) int {
    67  	return card * 2
    68  }
    69  
    70  // add the values in the range [firstOfRange,endx)
    71  func (ac *arrayContainer) iaddRange(firstOfRange, endx int) container {
    72  	if firstOfRange >= endx {
    73  		return ac
    74  	}
    75  	indexstart := binarySearch(ac.content, uint16(firstOfRange))
    76  	if indexstart < 0 {
    77  		indexstart = -indexstart - 1
    78  	}
    79  	indexend := binarySearch(ac.content, uint16(endx-1))
    80  	if indexend < 0 {
    81  		indexend = -indexend - 1
    82  	} else {
    83  		indexend++
    84  	}
    85  	rangelength := endx - firstOfRange
    86  	newcardinality := indexstart + (ac.getCardinality() - indexend) + rangelength
    87  	if newcardinality > arrayDefaultMaxSize {
    88  		a := ac.toBitmapContainer()
    89  		return a.iaddRange(firstOfRange, endx)
    90  	}
    91  	if cap(ac.content) < newcardinality {
    92  		tmp := make([]uint16, newcardinality, newcardinality)
    93  		copy(tmp[:indexstart], ac.content[:indexstart])
    94  		copy(tmp[indexstart+rangelength:], ac.content[indexend:])
    95  
    96  		ac.content = tmp
    97  	} else {
    98  		ac.content = ac.content[:newcardinality]
    99  		copy(ac.content[indexstart+rangelength:], ac.content[indexend:])
   100  
   101  	}
   102  	for k := 0; k < rangelength; k++ {
   103  		ac.content[k+indexstart] = uint16(firstOfRange + k)
   104  	}
   105  	return ac
   106  }
   107  
   108  // remove the values in the range [firstOfRange,endx)
   109  func (ac *arrayContainer) iremoveRange(firstOfRange, endx int) container {
   110  	if firstOfRange >= endx {
   111  		return ac
   112  	}
   113  	indexstart := binarySearch(ac.content, uint16(firstOfRange))
   114  	if indexstart < 0 {
   115  		indexstart = -indexstart - 1
   116  	}
   117  	indexend := binarySearch(ac.content, uint16(endx-1))
   118  	if indexend < 0 {
   119  		indexend = -indexend - 1
   120  	} else {
   121  		indexend++
   122  	}
   123  	rangelength := indexend - indexstart
   124  	answer := ac
   125  	copy(answer.content[indexstart:], ac.content[indexstart+rangelength:])
   126  	answer.content = answer.content[:ac.getCardinality()-rangelength]
   127  	return answer
   128  }
   129  
   130  // flip the values in the range [firstOfRange,endx)
   131  func (ac *arrayContainer) not(firstOfRange, endx int) container {
   132  	if firstOfRange >= endx {
   133  		return ac.clone()
   134  	}
   135  	return ac.notClose(firstOfRange, endx-1) // remove everything in [firstOfRange,endx-1]
   136  }
   137  
   138  // flip the values in the range [firstOfRange,lastOfRange]
   139  func (ac *arrayContainer) notClose(firstOfRange, lastOfRange int) container {
   140  	if firstOfRange > lastOfRange { // unlike add and remove, not uses an inclusive range [firstOfRange,lastOfRange]
   141  		return ac.clone()
   142  	}
   143  
   144  	// determine the span of array indices to be affected^M
   145  	startIndex := binarySearch(ac.content, uint16(firstOfRange))
   146  	if startIndex < 0 {
   147  		startIndex = -startIndex - 1
   148  	}
   149  	lastIndex := binarySearch(ac.content, uint16(lastOfRange))
   150  	if lastIndex < 0 {
   151  		lastIndex = -lastIndex - 2
   152  	}
   153  	currentValuesInRange := lastIndex - startIndex + 1
   154  	spanToBeFlipped := lastOfRange - firstOfRange + 1
   155  	newValuesInRange := spanToBeFlipped - currentValuesInRange
   156  	cardinalityChange := newValuesInRange - currentValuesInRange
   157  	newCardinality := len(ac.content) + cardinalityChange
   158  	if newCardinality > arrayDefaultMaxSize {
   159  		return ac.toBitmapContainer().not(firstOfRange, lastOfRange+1)
   160  	}
   161  	answer := newArrayContainer()
   162  	answer.content = make([]uint16, newCardinality, newCardinality) //a hack for sure
   163  
   164  	copy(answer.content, ac.content[:startIndex])
   165  	outPos := startIndex
   166  	inPos := startIndex
   167  	valInRange := firstOfRange
   168  	for ; valInRange <= lastOfRange && inPos <= lastIndex; valInRange++ {
   169  		if uint16(valInRange) != ac.content[inPos] {
   170  			answer.content[outPos] = uint16(valInRange)
   171  			outPos++
   172  		} else {
   173  			inPos++
   174  		}
   175  	}
   176  
   177  	for ; valInRange <= lastOfRange; valInRange++ {
   178  		answer.content[outPos] = uint16(valInRange)
   179  		outPos++
   180  	}
   181  
   182  	for i := lastIndex + 1; i < len(ac.content); i++ {
   183  		answer.content[outPos] = ac.content[i]
   184  		outPos++
   185  	}
   186  	answer.content = answer.content[:newCardinality]
   187  	return answer
   188  
   189  }
   190  
   191  func (ac *arrayContainer) equals(o container) bool {
   192  
   193  	srb, ok := o.(*arrayContainer)
   194  	if ok {
   195  		// Check if the containers are the same object.
   196  		if ac == srb {
   197  			return true
   198  		}
   199  
   200  		if len(srb.content) != len(ac.content) {
   201  			return false
   202  		}
   203  
   204  		for i, v := range ac.content {
   205  			if v != srb.content[i] {
   206  				return false
   207  			}
   208  		}
   209  		return true
   210  	}
   211  
   212  	// use generic comparison
   213  	bCard := o.getCardinality()
   214  	aCard := ac.getCardinality()
   215  	if bCard != aCard {
   216  		return false
   217  	}
   218  
   219  	ait := ac.getShortIterator()
   220  	bit := o.getShortIterator()
   221  	for ait.hasNext() {
   222  		if bit.next() != ait.next() {
   223  			return false
   224  		}
   225  	}
   226  	return true
   227  }
   228  
   229  func (ac *arrayContainer) toBitmapContainer() *bitmapContainer {
   230  	bc := newBitmapContainer()
   231  	bc.loadData(ac)
   232  	return bc
   233  
   234  }
   235  func (ac *arrayContainer) iadd(x uint16) (wasNew bool) {
   236  	// Special case adding to the end of the container.
   237  	l := len(ac.content)
   238  	if l > 0 && l < arrayDefaultMaxSize && ac.content[l-1] < x {
   239  		ac.content = append(ac.content, x)
   240  		return true
   241  	}
   242  
   243  	loc := binarySearch(ac.content, x)
   244  
   245  	if loc < 0 {
   246  		s := ac.content
   247  		i := -loc - 1
   248  		s = append(s, 0)
   249  		copy(s[i+1:], s[i:])
   250  		s[i] = x
   251  		ac.content = s
   252  		return true
   253  	}
   254  	return false
   255  }
   256  
   257  func (ac *arrayContainer) iaddReturnMinimized(x uint16) container {
   258  	// Special case adding to the end of the container.
   259  	l := len(ac.content)
   260  	if l > 0 && l < arrayDefaultMaxSize && ac.content[l-1] < x {
   261  		ac.content = append(ac.content, x)
   262  		return ac
   263  	}
   264  
   265  	loc := binarySearch(ac.content, x)
   266  
   267  	if loc < 0 {
   268  		if len(ac.content) >= arrayDefaultMaxSize {
   269  			a := ac.toBitmapContainer()
   270  			a.iadd(x)
   271  			return a
   272  		}
   273  		s := ac.content
   274  		i := -loc - 1
   275  		s = append(s, 0)
   276  		copy(s[i+1:], s[i:])
   277  		s[i] = x
   278  		ac.content = s
   279  	}
   280  	return ac
   281  }
   282  
   283  // iremoveReturnMinimized is allowed to change the return type to minimize storage.
   284  func (ac *arrayContainer) iremoveReturnMinimized(x uint16) container {
   285  	ac.iremove(x)
   286  	return ac
   287  }
   288  
   289  func (ac *arrayContainer) iremove(x uint16) bool {
   290  	loc := binarySearch(ac.content, x)
   291  	if loc >= 0 {
   292  		s := ac.content
   293  		s = append(s[:loc], s[loc+1:]...)
   294  		ac.content = s
   295  		return true
   296  	}
   297  	return false
   298  }
   299  
   300  func (ac *arrayContainer) remove(x uint16) container {
   301  	out := &arrayContainer{make([]uint16, len(ac.content))}
   302  	copy(out.content, ac.content[:])
   303  
   304  	loc := binarySearch(out.content, x)
   305  	if loc >= 0 {
   306  		s := out.content
   307  		s = append(s[:loc], s[loc+1:]...)
   308  		out.content = s
   309  	}
   310  	return out
   311  }
   312  
   313  func (ac *arrayContainer) or(a container) container {
   314  	switch x := a.(type) {
   315  	case *arrayContainer:
   316  		return ac.orArray(x)
   317  	case *bitmapContainer:
   318  		return x.orArray(ac)
   319  	case *runContainer16:
   320  		if x.isFull() {
   321  			return x.clone()
   322  		}
   323  		return x.orArray(ac)
   324  	}
   325  	panic("unsupported container type")
   326  }
   327  
   328  func (ac *arrayContainer) orCardinality(a container) int {
   329  	switch x := a.(type) {
   330  	case *arrayContainer:
   331  		return ac.orArrayCardinality(x)
   332  	case *bitmapContainer:
   333  		return x.orArrayCardinality(ac)
   334  	case *runContainer16:
   335  		return x.orArrayCardinality(ac)
   336  	}
   337  	panic("unsupported container type")
   338  }
   339  
   340  func (ac *arrayContainer) ior(a container) container {
   341  	switch x := a.(type) {
   342  	case *arrayContainer:
   343  		return ac.iorArray(x)
   344  	case *bitmapContainer:
   345  		return a.(*bitmapContainer).orArray(ac)
   346  		//return ac.iorBitmap(x) // note: this does not make sense
   347  	case *runContainer16:
   348  		if x.isFull() {
   349  			return x.clone()
   350  		}
   351  		return ac.iorRun16(x)
   352  	}
   353  	panic("unsupported container type")
   354  }
   355  
   356  func (ac *arrayContainer) iorArray(value2 *arrayContainer) container {
   357  	value1 := ac
   358  	len1 := value1.getCardinality()
   359  	len2 := value2.getCardinality()
   360  	maxPossibleCardinality := len1 + len2
   361  	if maxPossibleCardinality > cap(value1.content) {
   362  		// doubling the capacity reduces new slice allocations in the case of
   363  		// repeated calls to iorArray().
   364  		newSize := 2 * maxPossibleCardinality
   365  		// the second check is to handle overly large array containers
   366  		// and should not occur in normal usage,
   367  		// as all array containers should be at most arrayDefaultMaxSize
   368  		if newSize > 2*arrayDefaultMaxSize && maxPossibleCardinality <= 2*arrayDefaultMaxSize {
   369  			newSize = 2 * arrayDefaultMaxSize
   370  		}
   371  		newcontent := make([]uint16, 0, newSize)
   372  		copy(newcontent[len2:maxPossibleCardinality], ac.content[0:len1])
   373  		ac.content = newcontent
   374  	} else {
   375  		copy(ac.content[len2:maxPossibleCardinality], ac.content[0:len1])
   376  	}
   377  	nl := union2by2(value1.content[len2:maxPossibleCardinality], value2.content, ac.content)
   378  	ac.content = ac.content[:nl] // reslice to match actual used capacity
   379  
   380  	if nl > arrayDefaultMaxSize {
   381  		// Only converting to a bitmap when arrayDefaultMaxSize
   382  		// is actually exceeded minimizes conversions in the case of repeated
   383  		// calls to iorArray().
   384  		return ac.toBitmapContainer()
   385  	}
   386  	return ac
   387  }
   388  
   389  // Note: such code does not make practical sense, except for lazy evaluations
   390  func (ac *arrayContainer) iorBitmap(bc2 *bitmapContainer) container {
   391  	bc1 := ac.toBitmapContainer()
   392  	bc1.iorBitmap(bc2)
   393  	*ac = *newArrayContainerFromBitmap(bc1)
   394  	return ac
   395  }
   396  
   397  func (ac *arrayContainer) iorRun16(rc *runContainer16) container {
   398  	runCardinality := rc.getCardinality()
   399  	// heuristic for if the container should maybe be an
   400  	// array container.
   401  	if runCardinality < ac.getCardinality() &&
   402  		runCardinality+ac.getCardinality() < arrayDefaultMaxSize {
   403  		var result container
   404  		result = ac
   405  		for _, run := range rc.iv {
   406  			result = result.iaddRange(int(run.start), int(run.start)+int(run.length)+1)
   407  		}
   408  		return result
   409  	}
   410  	return rc.orArray(ac)
   411  }
   412  
   413  func (ac *arrayContainer) lazyIOR(a container) container {
   414  	switch x := a.(type) {
   415  	case *arrayContainer:
   416  		return ac.lazyIorArray(x)
   417  	case *bitmapContainer:
   418  		return ac.lazyIorBitmap(x)
   419  	case *runContainer16:
   420  		if x.isFull() {
   421  			return x.clone()
   422  		}
   423  		return ac.lazyIorRun16(x)
   424  
   425  	}
   426  	panic("unsupported container type")
   427  }
   428  
   429  func (ac *arrayContainer) lazyIorArray(ac2 *arrayContainer) container {
   430  	// TODO actually make this lazy
   431  	return ac.iorArray(ac2)
   432  }
   433  
   434  func (ac *arrayContainer) lazyIorBitmap(bc *bitmapContainer) container {
   435  	// TODO actually make this lazy
   436  	return ac.iorBitmap(bc)
   437  }
   438  
   439  func (ac *arrayContainer) lazyIorRun16(rc *runContainer16) container {
   440  	// TODO actually make this lazy
   441  	return ac.iorRun16(rc)
   442  }
   443  
   444  func (ac *arrayContainer) lazyOR(a container) container {
   445  	switch x := a.(type) {
   446  	case *arrayContainer:
   447  		return ac.lazyorArray(x)
   448  	case *bitmapContainer:
   449  		return a.lazyOR(ac)
   450  	case *runContainer16:
   451  		if x.isFull() {
   452  			return x.clone()
   453  		}
   454  		return x.orArray(ac)
   455  	}
   456  	panic("unsupported container type")
   457  }
   458  
   459  func (ac *arrayContainer) orArray(value2 *arrayContainer) container {
   460  	value1 := ac
   461  	maxPossibleCardinality := value1.getCardinality() + value2.getCardinality()
   462  	if maxPossibleCardinality > arrayDefaultMaxSize { // it could be a bitmap!
   463  		bc := newBitmapContainer()
   464  		for k := 0; k < len(value2.content); k++ {
   465  			v := value2.content[k]
   466  			i := uint(v) >> 6
   467  			mask := uint64(1) << (v % 64)
   468  			bc.bitmap[i] |= mask
   469  		}
   470  		for k := 0; k < len(ac.content); k++ {
   471  			v := ac.content[k]
   472  			i := uint(v) >> 6
   473  			mask := uint64(1) << (v % 64)
   474  			bc.bitmap[i] |= mask
   475  		}
   476  		bc.cardinality = int(popcntSlice(bc.bitmap))
   477  		if bc.cardinality <= arrayDefaultMaxSize {
   478  			return bc.toArrayContainer()
   479  		}
   480  		return bc
   481  	}
   482  	answer := newArrayContainerCapacity(maxPossibleCardinality)
   483  	nl := union2by2(value1.content, value2.content, answer.content)
   484  	answer.content = answer.content[:nl] // reslice to match actual used capacity
   485  	return answer
   486  }
   487  
   488  func (ac *arrayContainer) orArrayCardinality(value2 *arrayContainer) int {
   489  	return union2by2Cardinality(ac.content, value2.content)
   490  }
   491  
   492  func (ac *arrayContainer) lazyorArray(value2 *arrayContainer) container {
   493  	value1 := ac
   494  	maxPossibleCardinality := value1.getCardinality() + value2.getCardinality()
   495  	if maxPossibleCardinality > arrayLazyLowerBound { // it could be a bitmap!
   496  		bc := newBitmapContainer()
   497  		for k := 0; k < len(value2.content); k++ {
   498  			v := value2.content[k]
   499  			i := uint(v) >> 6
   500  			mask := uint64(1) << (v % 64)
   501  			bc.bitmap[i] |= mask
   502  		}
   503  		for k := 0; k < len(ac.content); k++ {
   504  			v := ac.content[k]
   505  			i := uint(v) >> 6
   506  			mask := uint64(1) << (v % 64)
   507  			bc.bitmap[i] |= mask
   508  		}
   509  		bc.cardinality = invalidCardinality
   510  		return bc
   511  	}
   512  	answer := newArrayContainerCapacity(maxPossibleCardinality)
   513  	nl := union2by2(value1.content, value2.content, answer.content)
   514  	answer.content = answer.content[:nl] // reslice to match actual used capacity
   515  	return answer
   516  }
   517  
   518  func (ac *arrayContainer) and(a container) container {
   519  	switch x := a.(type) {
   520  	case *arrayContainer:
   521  		return ac.andArray(x)
   522  	case *bitmapContainer:
   523  		return x.and(ac)
   524  	case *runContainer16:
   525  		if x.isFull() {
   526  			return ac.clone()
   527  		}
   528  		return x.andArray(ac)
   529  	}
   530  	panic("unsupported container type")
   531  }
   532  
   533  func (ac *arrayContainer) andCardinality(a container) int {
   534  	switch x := a.(type) {
   535  	case *arrayContainer:
   536  		return ac.andArrayCardinality(x)
   537  	case *bitmapContainer:
   538  		return x.andCardinality(ac)
   539  	case *runContainer16:
   540  		return x.andArrayCardinality(ac)
   541  	}
   542  	panic("unsupported container type")
   543  }
   544  
   545  func (ac *arrayContainer) intersects(a container) bool {
   546  	switch x := a.(type) {
   547  	case *arrayContainer:
   548  		return ac.intersectsArray(x)
   549  	case *bitmapContainer:
   550  		return x.intersects(ac)
   551  	case *runContainer16:
   552  		return x.intersects(ac)
   553  	}
   554  	panic("unsupported container type")
   555  }
   556  
   557  func (ac *arrayContainer) iand(a container) container {
   558  	switch x := a.(type) {
   559  	case *arrayContainer:
   560  		return ac.iandArray(x)
   561  	case *bitmapContainer:
   562  		return ac.iandBitmap(x)
   563  	case *runContainer16:
   564  		if x.isFull() {
   565  			return ac
   566  		}
   567  		return x.andArray(ac)
   568  	}
   569  	panic("unsupported container type")
   570  }
   571  
   572  func (ac *arrayContainer) iandBitmap(bc *bitmapContainer) container {
   573  	pos := 0
   574  	c := ac.getCardinality()
   575  	for k := 0; k < c; k++ {
   576  		// branchless
   577  		v := ac.content[k]
   578  		ac.content[pos] = v
   579  		pos += int(bc.bitValue(v))
   580  	}
   581  	ac.content = ac.content[:pos]
   582  	return ac
   583  
   584  }
   585  
   586  func (ac *arrayContainer) xor(a container) container {
   587  	switch x := a.(type) {
   588  	case *arrayContainer:
   589  		return ac.xorArray(x)
   590  	case *bitmapContainer:
   591  		return a.xor(ac)
   592  	case *runContainer16:
   593  		return x.xorArray(ac)
   594  	}
   595  	panic("unsupported container type")
   596  }
   597  
   598  func (ac *arrayContainer) xorArray(value2 *arrayContainer) container {
   599  	value1 := ac
   600  	totalCardinality := value1.getCardinality() + value2.getCardinality()
   601  	if totalCardinality > arrayDefaultMaxSize { // it could be a bitmap!
   602  		bc := newBitmapContainer()
   603  		for k := 0; k < len(value2.content); k++ {
   604  			v := value2.content[k]
   605  			i := uint(v) >> 6
   606  			bc.bitmap[i] ^= (uint64(1) << (v % 64))
   607  		}
   608  		for k := 0; k < len(ac.content); k++ {
   609  			v := ac.content[k]
   610  			i := uint(v) >> 6
   611  			bc.bitmap[i] ^= (uint64(1) << (v % 64))
   612  		}
   613  		bc.computeCardinality()
   614  		if bc.cardinality <= arrayDefaultMaxSize {
   615  			return bc.toArrayContainer()
   616  		}
   617  		return bc
   618  	}
   619  	desiredCapacity := totalCardinality
   620  	answer := newArrayContainerCapacity(desiredCapacity)
   621  	length := exclusiveUnion2by2(value1.content, value2.content, answer.content)
   622  	answer.content = answer.content[:length]
   623  	return answer
   624  
   625  }
   626  
   627  func (ac *arrayContainer) andNot(a container) container {
   628  	switch x := a.(type) {
   629  	case *arrayContainer:
   630  		return ac.andNotArray(x)
   631  	case *bitmapContainer:
   632  		return ac.andNotBitmap(x)
   633  	case *runContainer16:
   634  		return ac.andNotRun16(x)
   635  	}
   636  	panic("unsupported container type")
   637  }
   638  
   639  func (ac *arrayContainer) andNotRun16(rc *runContainer16) container {
   640  	acb := ac.toBitmapContainer()
   641  	rcb := rc.toBitmapContainer()
   642  	return acb.andNotBitmap(rcb)
   643  }
   644  
   645  func (ac *arrayContainer) iandNot(a container) container {
   646  	switch x := a.(type) {
   647  	case *arrayContainer:
   648  		return ac.iandNotArray(x)
   649  	case *bitmapContainer:
   650  		return ac.iandNotBitmap(x)
   651  	case *runContainer16:
   652  		return ac.iandNotRun16(x)
   653  	}
   654  	panic("unsupported container type")
   655  }
   656  
   657  func (ac *arrayContainer) iandNotRun16(rc *runContainer16) container {
   658  	rcb := rc.toBitmapContainer()
   659  	acb := ac.toBitmapContainer()
   660  	acb.iandNotBitmapSurely(rcb)
   661  	*ac = *(acb.toArrayContainer())
   662  	return ac
   663  }
   664  
   665  func (ac *arrayContainer) andNotArray(value2 *arrayContainer) container {
   666  	value1 := ac
   667  	desiredcapacity := value1.getCardinality()
   668  	answer := newArrayContainerCapacity(desiredcapacity)
   669  	length := difference(value1.content, value2.content, answer.content)
   670  	answer.content = answer.content[:length]
   671  	return answer
   672  }
   673  
   674  func (ac *arrayContainer) iandNotArray(value2 *arrayContainer) container {
   675  	length := difference(ac.content, value2.content, ac.content)
   676  	ac.content = ac.content[:length]
   677  	return ac
   678  }
   679  
   680  func (ac *arrayContainer) andNotBitmap(value2 *bitmapContainer) container {
   681  	desiredcapacity := ac.getCardinality()
   682  	answer := newArrayContainerCapacity(desiredcapacity)
   683  	answer.content = answer.content[:desiredcapacity]
   684  	pos := 0
   685  	for _, v := range ac.content {
   686  		answer.content[pos] = v
   687  		pos += 1 - int(value2.bitValue(v))
   688  	}
   689  	answer.content = answer.content[:pos]
   690  	return answer
   691  }
   692  
   693  func (ac *arrayContainer) andBitmap(value2 *bitmapContainer) container {
   694  	desiredcapacity := ac.getCardinality()
   695  	answer := newArrayContainerCapacity(desiredcapacity)
   696  	answer.content = answer.content[:desiredcapacity]
   697  	pos := 0
   698  	for _, v := range ac.content {
   699  		answer.content[pos] = v
   700  		pos += int(value2.bitValue(v))
   701  	}
   702  	answer.content = answer.content[:pos]
   703  	return answer
   704  }
   705  
   706  func (ac *arrayContainer) iandNotBitmap(value2 *bitmapContainer) container {
   707  	pos := 0
   708  	for _, v := range ac.content {
   709  		ac.content[pos] = v
   710  		pos += 1 - int(value2.bitValue(v))
   711  	}
   712  	ac.content = ac.content[:pos]
   713  	return ac
   714  }
   715  
   716  func copyOf(array []uint16, size int) []uint16 {
   717  	result := make([]uint16, size)
   718  	for i, x := range array {
   719  		if i == size {
   720  			break
   721  		}
   722  		result[i] = x
   723  	}
   724  	return result
   725  }
   726  
   727  // flip the values in the range [firstOfRange,endx)
   728  func (ac *arrayContainer) inot(firstOfRange, endx int) container {
   729  	if firstOfRange >= endx {
   730  		return ac
   731  	}
   732  	return ac.inotClose(firstOfRange, endx-1) // remove everything in [firstOfRange,endx-1]
   733  }
   734  
   735  // flip the values in the range [firstOfRange,lastOfRange]
   736  func (ac *arrayContainer) inotClose(firstOfRange, lastOfRange int) container {
   737  	if firstOfRange > lastOfRange { // unlike add and remove, not uses an inclusive range [firstOfRange,lastOfRange]
   738  		return ac
   739  	}
   740  	// determine the span of array indices to be affected
   741  	startIndex := binarySearch(ac.content, uint16(firstOfRange))
   742  	if startIndex < 0 {
   743  		startIndex = -startIndex - 1
   744  	}
   745  	lastIndex := binarySearch(ac.content, uint16(lastOfRange))
   746  	if lastIndex < 0 {
   747  		lastIndex = -lastIndex - 1 - 1
   748  	}
   749  	currentValuesInRange := lastIndex - startIndex + 1
   750  	spanToBeFlipped := lastOfRange - firstOfRange + 1
   751  
   752  	newValuesInRange := spanToBeFlipped - currentValuesInRange
   753  	buffer := make([]uint16, newValuesInRange)
   754  	cardinalityChange := newValuesInRange - currentValuesInRange
   755  	newCardinality := len(ac.content) + cardinalityChange
   756  	if cardinalityChange > 0 {
   757  		if newCardinality > len(ac.content) {
   758  			if newCardinality > arrayDefaultMaxSize {
   759  				bcRet := ac.toBitmapContainer()
   760  				bcRet.inot(firstOfRange, lastOfRange+1)
   761  				*ac = *bcRet.toArrayContainer()
   762  				return bcRet
   763  			}
   764  			ac.content = copyOf(ac.content, newCardinality)
   765  		}
   766  		base := lastIndex + 1
   767  		copy(ac.content[lastIndex+1+cardinalityChange:], ac.content[base:base+len(ac.content)-1-lastIndex])
   768  		ac.negateRange(buffer, startIndex, lastIndex, firstOfRange, lastOfRange+1)
   769  	} else { // no expansion needed
   770  		ac.negateRange(buffer, startIndex, lastIndex, firstOfRange, lastOfRange+1)
   771  		if cardinalityChange < 0 {
   772  
   773  			for i := startIndex + newValuesInRange; i < newCardinality; i++ {
   774  				ac.content[i] = ac.content[i-cardinalityChange]
   775  			}
   776  		}
   777  	}
   778  	ac.content = ac.content[:newCardinality]
   779  	return ac
   780  }
   781  
   782  func (ac *arrayContainer) negateRange(buffer []uint16, startIndex, lastIndex, startRange, lastRange int) {
   783  	// compute the negation into buffer
   784  	outPos := 0
   785  	inPos := startIndex // value here always >= valInRange,
   786  	// until it is exhausted
   787  	// n.b., we can start initially exhausted.
   788  
   789  	valInRange := startRange
   790  	for ; valInRange < lastRange && inPos <= lastIndex; valInRange++ {
   791  		if uint16(valInRange) != ac.content[inPos] {
   792  			buffer[outPos] = uint16(valInRange)
   793  			outPos++
   794  		} else {
   795  			inPos++
   796  		}
   797  	}
   798  
   799  	// if there are extra items (greater than the biggest
   800  	// pre-existing one in range), buffer them
   801  	for ; valInRange < lastRange; valInRange++ {
   802  		buffer[outPos] = uint16(valInRange)
   803  		outPos++
   804  	}
   805  
   806  	if outPos != len(buffer) {
   807  		panic("negateRange: internal bug")
   808  	}
   809  
   810  	for i, item := range buffer {
   811  		ac.content[i+startIndex] = item
   812  	}
   813  }
   814  
   815  func (ac *arrayContainer) isFull() bool {
   816  	return false
   817  }
   818  
   819  func (ac *arrayContainer) andArray(value2 *arrayContainer) container {
   820  	desiredcapacity := minOfInt(ac.getCardinality(), value2.getCardinality())
   821  	answer := newArrayContainerCapacity(desiredcapacity)
   822  	length := intersection2by2(
   823  		ac.content,
   824  		value2.content,
   825  		answer.content)
   826  	answer.content = answer.content[:length]
   827  	return answer
   828  }
   829  
   830  func (ac *arrayContainer) andArrayCardinality(value2 *arrayContainer) int {
   831  	return intersection2by2Cardinality(
   832  		ac.content,
   833  		value2.content)
   834  }
   835  
   836  func (ac *arrayContainer) intersectsArray(value2 *arrayContainer) bool {
   837  	return intersects2by2(
   838  		ac.content,
   839  		value2.content)
   840  }
   841  
   842  func (ac *arrayContainer) iandArray(value2 *arrayContainer) container {
   843  	length := intersection2by2(
   844  		ac.content,
   845  		value2.content,
   846  		ac.content)
   847  	ac.content = ac.content[:length]
   848  	return ac
   849  }
   850  
   851  func (ac *arrayContainer) getCardinality() int {
   852  	return len(ac.content)
   853  }
   854  
   855  func (ac *arrayContainer) isEmpty() bool {
   856  	return len(ac.content) == 0
   857  }
   858  
   859  func (ac *arrayContainer) rank(x uint16) int {
   860  	answer := binarySearch(ac.content, x)
   861  	if answer >= 0 {
   862  		return answer + 1
   863  	}
   864  	return -answer - 1
   865  
   866  }
   867  
   868  func (ac *arrayContainer) selectInt(x uint16) int {
   869  	return int(ac.content[x])
   870  }
   871  
   872  func (ac *arrayContainer) clone() container {
   873  	ptr := arrayContainer{make([]uint16, len(ac.content))}
   874  	copy(ptr.content, ac.content[:])
   875  	return &ptr
   876  }
   877  
   878  func (ac *arrayContainer) contains(x uint16) bool {
   879  	return binarySearch(ac.content, x) >= 0
   880  }
   881  
   882  func (ac *arrayContainer) loadData(bitmapContainer *bitmapContainer) {
   883  	ac.content = make([]uint16, bitmapContainer.cardinality, bitmapContainer.cardinality)
   884  	bitmapContainer.fillArray(ac.content)
   885  }
   886  
   887  func (ac *arrayContainer) resetTo(a container) {
   888  	switch x := a.(type) {
   889  	case *arrayContainer:
   890  		ac.realloc(len(x.content))
   891  		copy(ac.content, x.content)
   892  
   893  	case *bitmapContainer:
   894  		ac.realloc(x.cardinality)
   895  		x.fillArray(ac.content)
   896  
   897  	case *runContainer16:
   898  		card := int(x.getCardinality())
   899  		ac.realloc(card)
   900  		cur := 0
   901  		for _, r := range x.iv {
   902  			for val := r.start; val <= r.last(); val++ {
   903  				ac.content[cur] = val
   904  				cur++
   905  			}
   906  		}
   907  
   908  	default:
   909  		panic("unsupported container type")
   910  	}
   911  }
   912  
   913  func (ac *arrayContainer) realloc(size int) {
   914  	if cap(ac.content) < size {
   915  		ac.content = make([]uint16, size)
   916  	} else {
   917  		ac.content = ac.content[:size]
   918  	}
   919  }
   920  
   921  func newArrayContainer() *arrayContainer {
   922  	p := new(arrayContainer)
   923  	return p
   924  }
   925  
   926  func newArrayContainerFromBitmap(bc *bitmapContainer) *arrayContainer {
   927  	ac := &arrayContainer{}
   928  	ac.loadData(bc)
   929  	return ac
   930  }
   931  
   932  func newArrayContainerCapacity(size int) *arrayContainer {
   933  	p := new(arrayContainer)
   934  	p.content = make([]uint16, 0, size)
   935  	return p
   936  }
   937  
   938  func newArrayContainerSize(size int) *arrayContainer {
   939  	p := new(arrayContainer)
   940  	p.content = make([]uint16, size, size)
   941  	return p
   942  }
   943  
   944  func newArrayContainerRange(firstOfRun, lastOfRun int) *arrayContainer {
   945  	valuesInRange := lastOfRun - firstOfRun + 1
   946  	this := newArrayContainerCapacity(valuesInRange)
   947  	for i := 0; i < valuesInRange; i++ {
   948  		this.content = append(this.content, uint16(firstOfRun+i))
   949  	}
   950  	return this
   951  }
   952  
   953  func (ac *arrayContainer) numberOfRuns() (nr int) {
   954  	n := len(ac.content)
   955  	var runlen uint16
   956  	var cur, prev uint16
   957  
   958  	switch n {
   959  	case 0:
   960  		return 0
   961  	case 1:
   962  		return 1
   963  	default:
   964  		for i := 1; i < n; i++ {
   965  			prev = ac.content[i-1]
   966  			cur = ac.content[i]
   967  
   968  			if cur == prev+1 {
   969  				runlen++
   970  			} else {
   971  				if cur < prev {
   972  					panic("the fundamental arrayContainer assumption of sorted ac.content was broken")
   973  				}
   974  				if cur == prev {
   975  					panic("the fundamental arrayContainer assumption of deduplicated content was broken")
   976  				} else {
   977  					nr++
   978  					runlen = 0
   979  				}
   980  			}
   981  		}
   982  		nr++
   983  	}
   984  	return
   985  }
   986  
   987  // convert to run or array *if needed*
   988  func (ac *arrayContainer) toEfficientContainer() container {
   989  
   990  	numRuns := ac.numberOfRuns()
   991  
   992  	sizeAsRunContainer := runContainer16SerializedSizeInBytes(numRuns)
   993  	sizeAsBitmapContainer := bitmapContainerSizeInBytes()
   994  	card := ac.getCardinality()
   995  	sizeAsArrayContainer := arrayContainerSizeInBytes(card)
   996  
   997  	if sizeAsRunContainer <= minOfInt(sizeAsBitmapContainer, sizeAsArrayContainer) {
   998  		return newRunContainer16FromArray(ac)
   999  	}
  1000  	if card <= arrayDefaultMaxSize {
  1001  		return ac
  1002  	}
  1003  	return ac.toBitmapContainer()
  1004  }
  1005  
  1006  func (ac *arrayContainer) containerType() contype {
  1007  	return arrayContype
  1008  }
  1009  
  1010  func (ac *arrayContainer) addOffset(x uint16) (container, container) {
  1011  	var low, high *arrayContainer
  1012  
  1013  	if len(ac.content) == 0 {
  1014  		return nil, nil
  1015  	}
  1016  
  1017  	if y := uint32(ac.content[0]) + uint32(x); highbits(y) == 0 {
  1018  		// Some elements will fall into low part, allocate a container.
  1019  		// Checking the first one is enough because they are ordered.
  1020  		low = &arrayContainer{}
  1021  	}
  1022  	if y := uint32(ac.content[len(ac.content)-1]) + uint32(x); highbits(y) > 0 {
  1023  		// Some elements will fall into high part, allocate a container.
  1024  		// Checking the last one is enough because they are ordered.
  1025  		high = &arrayContainer{}
  1026  	}
  1027  
  1028  	for _, val := range ac.content {
  1029  		y := uint32(val) + uint32(x)
  1030  		if highbits(y) > 0 {
  1031  			// OK, if high == nil then highbits(y) == 0 for all y.
  1032  			high.content = append(high.content, lowbits(y))
  1033  		} else {
  1034  			// OK, if low == nil then highbits(y) > 0 for all y.
  1035  			low.content = append(low.content, lowbits(y))
  1036  		}
  1037  	}
  1038  
  1039  	// Ensure proper nil interface.
  1040  	if low == nil {
  1041  		return nil, high
  1042  	}
  1043  	if high == nil {
  1044  		return low, nil
  1045  	}
  1046  
  1047  	return low, high
  1048  }