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

     1  package roaring
     2  
     3  func equal(a, b []uint16) bool {
     4  	if len(a) != len(b) {
     5  		return false
     6  	}
     7  	for i := range a {
     8  		if a[i] != b[i] {
     9  			return false
    10  		}
    11  	}
    12  	return true
    13  }
    14  
    15  func difference(set1 []uint16, set2 []uint16, buffer []uint16) int {
    16  	if 0 == len(set2) {
    17  		buffer = buffer[:len(set1)]
    18  		for k := 0; k < len(set1); k++ {
    19  			buffer[k] = set1[k]
    20  		}
    21  		return len(set1)
    22  	}
    23  	if 0 == len(set1) {
    24  		return 0
    25  	}
    26  	pos := 0
    27  	k1 := 0
    28  	k2 := 0
    29  	buffer = buffer[:cap(buffer)]
    30  	s1 := set1[k1]
    31  	s2 := set2[k2]
    32  	for {
    33  		if s1 < s2 {
    34  			buffer[pos] = s1
    35  			pos++
    36  			k1++
    37  			if k1 >= len(set1) {
    38  				break
    39  			}
    40  			s1 = set1[k1]
    41  		} else if s1 == s2 {
    42  			k1++
    43  			k2++
    44  			if k1 >= len(set1) {
    45  				break
    46  			}
    47  			s1 = set1[k1]
    48  			if k2 >= len(set2) {
    49  				for ; k1 < len(set1); k1++ {
    50  					buffer[pos] = set1[k1]
    51  					pos++
    52  				}
    53  				break
    54  			}
    55  			s2 = set2[k2]
    56  		} else { // if (val1>val2)
    57  			k2++
    58  			if k2 >= len(set2) {
    59  				for ; k1 < len(set1); k1++ {
    60  					buffer[pos] = set1[k1]
    61  					pos++
    62  				}
    63  				break
    64  			}
    65  			s2 = set2[k2]
    66  		}
    67  	}
    68  	return pos
    69  
    70  }
    71  
    72  func exclusiveUnion2by2(set1 []uint16, set2 []uint16, buffer []uint16) int {
    73  	if 0 == len(set2) {
    74  		buffer = buffer[:len(set1)]
    75  		copy(buffer, set1[:])
    76  		return len(set1)
    77  	}
    78  	if 0 == len(set1) {
    79  		buffer = buffer[:len(set2)]
    80  		copy(buffer, set2[:])
    81  		return len(set2)
    82  	}
    83  	pos := 0
    84  	k1 := 0
    85  	k2 := 0
    86  	s1 := set1[k1]
    87  	s2 := set2[k2]
    88  	buffer = buffer[:cap(buffer)]
    89  	for {
    90  		if s1 < s2 {
    91  			buffer[pos] = s1
    92  			pos++
    93  			k1++
    94  			if k1 >= len(set1) {
    95  				for ; k2 < len(set2); k2++ {
    96  					buffer[pos] = set2[k2]
    97  					pos++
    98  				}
    99  				break
   100  			}
   101  			s1 = set1[k1]
   102  		} else if s1 == s2 {
   103  			k1++
   104  			k2++
   105  			if k1 >= len(set1) {
   106  				for ; k2 < len(set2); k2++ {
   107  					buffer[pos] = set2[k2]
   108  					pos++
   109  				}
   110  				break
   111  			}
   112  			if k2 >= len(set2) {
   113  				for ; k1 < len(set1); k1++ {
   114  					buffer[pos] = set1[k1]
   115  					pos++
   116  				}
   117  				break
   118  			}
   119  			s1 = set1[k1]
   120  			s2 = set2[k2]
   121  		} else { // if (val1>val2)
   122  			buffer[pos] = s2
   123  			pos++
   124  			k2++
   125  			if k2 >= len(set2) {
   126  				for ; k1 < len(set1); k1++ {
   127  					buffer[pos] = set1[k1]
   128  					pos++
   129  				}
   130  				break
   131  			}
   132  			s2 = set2[k2]
   133  		}
   134  	}
   135  	return pos
   136  }
   137  
   138  func union2by2Cardinality(set1 []uint16, set2 []uint16) int {
   139  	pos := 0
   140  	k1 := 0
   141  	k2 := 0
   142  	if 0 == len(set2) {
   143  		return len(set1)
   144  	}
   145  	if 0 == len(set1) {
   146  		return len(set2)
   147  	}
   148  	s1 := set1[k1]
   149  	s2 := set2[k2]
   150  	for {
   151  		if s1 < s2 {
   152  			pos++
   153  			k1++
   154  			if k1 >= len(set1) {
   155  				pos += len(set2) - k2
   156  				break
   157  			}
   158  			s1 = set1[k1]
   159  		} else if s1 == s2 {
   160  			pos++
   161  			k1++
   162  			k2++
   163  			if k1 >= len(set1) {
   164  				pos += len(set2) - k2
   165  				break
   166  			}
   167  			if k2 >= len(set2) {
   168  				pos += len(set1) - k1
   169  				break
   170  			}
   171  			s1 = set1[k1]
   172  			s2 = set2[k2]
   173  		} else { // if (set1[k1]>set2[k2])
   174  			pos++
   175  			k2++
   176  			if k2 >= len(set2) {
   177  				pos += len(set1) - k1
   178  				break
   179  			}
   180  			s2 = set2[k2]
   181  		}
   182  	}
   183  	return pos
   184  }
   185  
   186  func intersection2by2(
   187  	set1 []uint16,
   188  	set2 []uint16,
   189  	buffer []uint16) int {
   190  
   191  	if len(set1)*64 < len(set2) {
   192  		return onesidedgallopingintersect2by2(set1, set2, buffer)
   193  	} else if len(set2)*64 < len(set1) {
   194  		return onesidedgallopingintersect2by2(set2, set1, buffer)
   195  	} else {
   196  		return localintersect2by2(set1, set2, buffer)
   197  	}
   198  }
   199  
   200  func intersection2by2Cardinality(
   201  	set1 []uint16,
   202  	set2 []uint16) int {
   203  
   204  	if len(set1)*64 < len(set2) {
   205  		return onesidedgallopingintersect2by2Cardinality(set1, set2)
   206  	} else if len(set2)*64 < len(set1) {
   207  		return onesidedgallopingintersect2by2Cardinality(set2, set1)
   208  	} else {
   209  		return localintersect2by2Cardinality(set1, set2)
   210  	}
   211  }
   212  
   213  func intersects2by2(
   214  	set1 []uint16,
   215  	set2 []uint16) bool {
   216  	// could be optimized if one set is much larger than the other one
   217  	if (0 == len(set1)) || (0 == len(set2)) {
   218  		return false
   219  	}
   220  	k1 := 0
   221  	k2 := 0
   222  	s1 := set1[k1]
   223  	s2 := set2[k2]
   224  mainwhile:
   225  	for {
   226  
   227  		if s2 < s1 {
   228  			for {
   229  				k2++
   230  				if k2 == len(set2) {
   231  					break mainwhile
   232  				}
   233  				s2 = set2[k2]
   234  				if s2 >= s1 {
   235  					break
   236  				}
   237  			}
   238  		}
   239  		if s1 < s2 {
   240  			for {
   241  				k1++
   242  				if k1 == len(set1) {
   243  					break mainwhile
   244  				}
   245  				s1 = set1[k1]
   246  				if s1 >= s2 {
   247  					break
   248  				}
   249  			}
   250  
   251  		} else {
   252  			// (set2[k2] == set1[k1])
   253  			return true
   254  		}
   255  	}
   256  	return false
   257  }
   258  
   259  func localintersect2by2(
   260  	set1 []uint16,
   261  	set2 []uint16,
   262  	buffer []uint16) int {
   263  
   264  	if (0 == len(set1)) || (0 == len(set2)) {
   265  		return 0
   266  	}
   267  	k1 := 0
   268  	k2 := 0
   269  	pos := 0
   270  	buffer = buffer[:cap(buffer)]
   271  	s1 := set1[k1]
   272  	s2 := set2[k2]
   273  mainwhile:
   274  	for {
   275  		if s2 < s1 {
   276  			for {
   277  				k2++
   278  				if k2 == len(set2) {
   279  					break mainwhile
   280  				}
   281  				s2 = set2[k2]
   282  				if s2 >= s1 {
   283  					break
   284  				}
   285  			}
   286  		}
   287  		if s1 < s2 {
   288  			for {
   289  				k1++
   290  				if k1 == len(set1) {
   291  					break mainwhile
   292  				}
   293  				s1 = set1[k1]
   294  				if s1 >= s2 {
   295  					break
   296  				}
   297  			}
   298  
   299  		} else {
   300  			// (set2[k2] == set1[k1])
   301  			buffer[pos] = s1
   302  			pos++
   303  			k1++
   304  			if k1 == len(set1) {
   305  				break
   306  			}
   307  			s1 = set1[k1]
   308  			k2++
   309  			if k2 == len(set2) {
   310  				break
   311  			}
   312  			s2 = set2[k2]
   313  		}
   314  	}
   315  	return pos
   316  }
   317  
   318  func localintersect2by2Cardinality(
   319  	set1 []uint16,
   320  	set2 []uint16) int {
   321  
   322  	if (0 == len(set1)) || (0 == len(set2)) {
   323  		return 0
   324  	}
   325  	k1 := 0
   326  	k2 := 0
   327  	pos := 0
   328  	s1 := set1[k1]
   329  	s2 := set2[k2]
   330  mainwhile:
   331  	for {
   332  		if s2 < s1 {
   333  			for {
   334  				k2++
   335  				if k2 == len(set2) {
   336  					break mainwhile
   337  				}
   338  				s2 = set2[k2]
   339  				if s2 >= s1 {
   340  					break
   341  				}
   342  			}
   343  		}
   344  		if s1 < s2 {
   345  			for {
   346  				k1++
   347  				if k1 == len(set1) {
   348  					break mainwhile
   349  				}
   350  				s1 = set1[k1]
   351  				if s1 >= s2 {
   352  					break
   353  				}
   354  			}
   355  
   356  		} else {
   357  			// (set2[k2] == set1[k1])
   358  			pos++
   359  			k1++
   360  			if k1 == len(set1) {
   361  				break
   362  			}
   363  			s1 = set1[k1]
   364  			k2++
   365  			if k2 == len(set2) {
   366  				break
   367  			}
   368  			s2 = set2[k2]
   369  		}
   370  	}
   371  	return pos
   372  }
   373  
   374  func advanceUntil(
   375  	array []uint16,
   376  	pos int,
   377  	length int,
   378  	min uint16) int {
   379  	lower := pos + 1
   380  
   381  	if lower >= length || array[lower] >= min {
   382  		return lower
   383  	}
   384  
   385  	spansize := 1
   386  
   387  	for lower+spansize < length && array[lower+spansize] < min {
   388  		spansize *= 2
   389  	}
   390  	var upper int
   391  	if lower+spansize < length {
   392  		upper = lower + spansize
   393  	} else {
   394  		upper = length - 1
   395  	}
   396  
   397  	if array[upper] == min {
   398  		return upper
   399  	}
   400  
   401  	if array[upper] < min {
   402  		// means
   403  		// array
   404  		// has no
   405  		// item
   406  		// >= min
   407  		// pos = array.length;
   408  		return length
   409  	}
   410  
   411  	// we know that the next-smallest span was too small
   412  	lower += (spansize >> 1)
   413  
   414  	mid := 0
   415  	for lower+1 != upper {
   416  		mid = (lower + upper) >> 1
   417  		if array[mid] == min {
   418  			return mid
   419  		} else if array[mid] < min {
   420  			lower = mid
   421  		} else {
   422  			upper = mid
   423  		}
   424  	}
   425  	return upper
   426  
   427  }
   428  
   429  func onesidedgallopingintersect2by2(
   430  	smallset []uint16,
   431  	largeset []uint16,
   432  	buffer []uint16) int {
   433  
   434  	if 0 == len(smallset) {
   435  		return 0
   436  	}
   437  	buffer = buffer[:cap(buffer)]
   438  	k1 := 0
   439  	k2 := 0
   440  	pos := 0
   441  	s1 := largeset[k1]
   442  	s2 := smallset[k2]
   443  mainwhile:
   444  
   445  	for {
   446  		if s1 < s2 {
   447  			k1 = advanceUntil(largeset, k1, len(largeset), s2)
   448  			if k1 == len(largeset) {
   449  				break mainwhile
   450  			}
   451  			s1 = largeset[k1]
   452  		}
   453  		if s2 < s1 {
   454  			k2++
   455  			if k2 == len(smallset) {
   456  				break mainwhile
   457  			}
   458  			s2 = smallset[k2]
   459  		} else {
   460  
   461  			buffer[pos] = s2
   462  			pos++
   463  			k2++
   464  			if k2 == len(smallset) {
   465  				break
   466  			}
   467  			s2 = smallset[k2]
   468  			k1 = advanceUntil(largeset, k1, len(largeset), s2)
   469  			if k1 == len(largeset) {
   470  				break mainwhile
   471  			}
   472  			s1 = largeset[k1]
   473  		}
   474  
   475  	}
   476  	return pos
   477  }
   478  
   479  func onesidedgallopingintersect2by2Cardinality(
   480  	smallset []uint16,
   481  	largeset []uint16) int {
   482  
   483  	if 0 == len(smallset) {
   484  		return 0
   485  	}
   486  	k1 := 0
   487  	k2 := 0
   488  	pos := 0
   489  	s1 := largeset[k1]
   490  	s2 := smallset[k2]
   491  mainwhile:
   492  
   493  	for {
   494  		if s1 < s2 {
   495  			k1 = advanceUntil(largeset, k1, len(largeset), s2)
   496  			if k1 == len(largeset) {
   497  				break mainwhile
   498  			}
   499  			s1 = largeset[k1]
   500  		}
   501  		if s2 < s1 {
   502  			k2++
   503  			if k2 == len(smallset) {
   504  				break mainwhile
   505  			}
   506  			s2 = smallset[k2]
   507  		} else {
   508  
   509  			pos++
   510  			k2++
   511  			if k2 == len(smallset) {
   512  				break
   513  			}
   514  			s2 = smallset[k2]
   515  			k1 = advanceUntil(largeset, k1, len(largeset), s2)
   516  			if k1 == len(largeset) {
   517  				break mainwhile
   518  			}
   519  			s1 = largeset[k1]
   520  		}
   521  
   522  	}
   523  	return pos
   524  }
   525  
   526  func binarySearch(array []uint16, ikey uint16) int {
   527  	low := 0
   528  	high := len(array) - 1
   529  	for low+16 <= high {
   530  		middleIndex := int(uint32(low+high) >> 1)
   531  		middleValue := array[middleIndex]
   532  		if middleValue < ikey {
   533  			low = middleIndex + 1
   534  		} else if middleValue > ikey {
   535  			high = middleIndex - 1
   536  		} else {
   537  			return middleIndex
   538  		}
   539  	}
   540  	for ; low <= high; low++ {
   541  		val := array[low]
   542  		if val >= ikey {
   543  			if val == ikey {
   544  				return low
   545  			}
   546  			break
   547  		}
   548  	}
   549  	return -(low + 1)
   550  }