package roaring func equal(a, b []uint16) bool { if len(a) != len(b) { return false } for i := range a { if a[i] != b[i] { return false } } return true } func difference(set1 []uint16, set2 []uint16, buffer []uint16) int { if 0 == len(set2) { buffer = buffer[:len(set1)] for k := 0; k < len(set1); k++ { buffer[k] = set1[k] } return len(set1) } if 0 == len(set1) { return 0 } pos := 0 k1 := 0 k2 := 0 buffer = buffer[:cap(buffer)] s1 := set1[k1] s2 := set2[k2] for { if s1 < s2 { buffer[pos] = s1 pos++ k1++ if k1 >= len(set1) { break } s1 = set1[k1] } else if s1 == s2 { k1++ k2++ if k1 >= len(set1) { break } s1 = set1[k1] if k2 >= len(set2) { for ; k1 < len(set1); k1++ { buffer[pos] = set1[k1] pos++ } break } s2 = set2[k2] } else { // if (val1>val2) k2++ if k2 >= len(set2) { for ; k1 < len(set1); k1++ { buffer[pos] = set1[k1] pos++ } break } s2 = set2[k2] } } return pos } func exclusiveUnion2by2(set1 []uint16, set2 []uint16, buffer []uint16) int { if 0 == len(set2) { buffer = buffer[:len(set1)] copy(buffer, set1[:]) return len(set1) } if 0 == len(set1) { buffer = buffer[:len(set2)] copy(buffer, set2[:]) return len(set2) } pos := 0 k1 := 0 k2 := 0 s1 := set1[k1] s2 := set2[k2] buffer = buffer[:cap(buffer)] for { if s1 < s2 { buffer[pos] = s1 pos++ k1++ if k1 >= len(set1) { for ; k2 < len(set2); k2++ { buffer[pos] = set2[k2] pos++ } break } s1 = set1[k1] } else if s1 == s2 { k1++ k2++ if k1 >= len(set1) { for ; k2 < len(set2); k2++ { buffer[pos] = set2[k2] pos++ } break } if k2 >= len(set2) { for ; k1 < len(set1); k1++ { buffer[pos] = set1[k1] pos++ } break } s1 = set1[k1] s2 = set2[k2] } else { // if (val1>val2) buffer[pos] = s2 pos++ k2++ if k2 >= len(set2) { for ; k1 < len(set1); k1++ { buffer[pos] = set1[k1] pos++ } break } s2 = set2[k2] } } return pos } func union2by2(set1 []uint16, set2 []uint16, buffer []uint16) int { pos := 0 k1 := 0 k2 := 0 if 0 == len(set2) { buffer = buffer[:len(set1)] copy(buffer, set1[:]) return len(set1) } if 0 == len(set1) { buffer = buffer[:len(set2)] copy(buffer, set2[:]) return len(set2) } s1 := set1[k1] s2 := set2[k2] buffer = buffer[:cap(buffer)] for { if s1 < s2 { buffer[pos] = s1 pos++ k1++ if k1 >= len(set1) { copy(buffer[pos:], set2[k2:]) pos += len(set2) - k2 break } s1 = set1[k1] } else if s1 == s2 { buffer[pos] = s1 pos++ k1++ k2++ if k1 >= len(set1) { copy(buffer[pos:], set2[k2:]) pos += len(set2) - k2 break } if k2 >= len(set2) { copy(buffer[pos:], set1[k1:]) pos += len(set1) - k1 break } s1 = set1[k1] s2 = set2[k2] } else { // if (set1[k1]>set2[k2]) buffer[pos] = s2 pos++ k2++ if k2 >= len(set2) { copy(buffer[pos:], set1[k1:]) pos += len(set1) - k1 break } s2 = set2[k2] } } return pos } func union2by2Cardinality(set1 []uint16, set2 []uint16) int { pos := 0 k1 := 0 k2 := 0 if 0 == len(set2) { return len(set1) } if 0 == len(set1) { return len(set2) } s1 := set1[k1] s2 := set2[k2] for { if s1 < s2 { pos++ k1++ if k1 >= len(set1) { pos += len(set2) - k2 break } s1 = set1[k1] } else if s1 == s2 { pos++ k1++ k2++ if k1 >= len(set1) { pos += len(set2) - k2 break } if k2 >= len(set2) { pos += len(set1) - k1 break } s1 = set1[k1] s2 = set2[k2] } else { // if (set1[k1]>set2[k2]) pos++ k2++ if k2 >= len(set2) { pos += len(set1) - k1 break } s2 = set2[k2] } } return pos } func intersection2by2( set1 []uint16, set2 []uint16, buffer []uint16) int { if len(set1)*64 < len(set2) { return onesidedgallopingintersect2by2(set1, set2, buffer) } else if len(set2)*64 < len(set1) { return onesidedgallopingintersect2by2(set2, set1, buffer) } else { return localintersect2by2(set1, set2, buffer) } } func intersection2by2Cardinality( set1 []uint16, set2 []uint16) int { if len(set1)*64 < len(set2) { return onesidedgallopingintersect2by2Cardinality(set1, set2) } else if len(set2)*64 < len(set1) { return onesidedgallopingintersect2by2Cardinality(set2, set1) } else { return localintersect2by2Cardinality(set1, set2) } } func intersects2by2( set1 []uint16, set2 []uint16) bool { // could be optimized if one set is much larger than the other one if (0 == len(set1)) || (0 == len(set2)) { return false } k1 := 0 k2 := 0 s1 := set1[k1] s2 := set2[k2] mainwhile: for { if s2 < s1 { for { k2++ if k2 == len(set2) { break mainwhile } s2 = set2[k2] if s2 >= s1 { break } } } if s1 < s2 { for { k1++ if k1 == len(set1) { break mainwhile } s1 = set1[k1] if s1 >= s2 { break } } } else { // (set2[k2] == set1[k1]) return true } } return false } func localintersect2by2( set1 []uint16, set2 []uint16, buffer []uint16) int { if (0 == len(set1)) || (0 == len(set2)) { return 0 } k1 := 0 k2 := 0 pos := 0 buffer = buffer[:cap(buffer)] s1 := set1[k1] s2 := set2[k2] mainwhile: for { if s2 < s1 { for { k2++ if k2 == len(set2) { break mainwhile } s2 = set2[k2] if s2 >= s1 { break } } } if s1 < s2 { for { k1++ if k1 == len(set1) { break mainwhile } s1 = set1[k1] if s1 >= s2 { break } } } else { // (set2[k2] == set1[k1]) buffer[pos] = s1 pos++ k1++ if k1 == len(set1) { break } s1 = set1[k1] k2++ if k2 == len(set2) { break } s2 = set2[k2] } } return pos } func localintersect2by2Cardinality( set1 []uint16, set2 []uint16) int { if (0 == len(set1)) || (0 == len(set2)) { return 0 } k1 := 0 k2 := 0 pos := 0 s1 := set1[k1] s2 := set2[k2] mainwhile: for { if s2 < s1 { for { k2++ if k2 == len(set2) { break mainwhile } s2 = set2[k2] if s2 >= s1 { break } } } if s1 < s2 { for { k1++ if k1 == len(set1) { break mainwhile } s1 = set1[k1] if s1 >= s2 { break } } } else { // (set2[k2] == set1[k1]) pos++ k1++ if k1 == len(set1) { break } s1 = set1[k1] k2++ if k2 == len(set2) { break } s2 = set2[k2] } } return pos } func advanceUntil( array []uint16, pos int, length int, min uint16) int { lower := pos + 1 if lower >= length || array[lower] >= min { return lower } spansize := 1 for lower+spansize < length && array[lower+spansize] < min { spansize *= 2 } var upper int if lower+spansize < length { upper = lower + spansize } else { upper = length - 1 } if array[upper] == min { return upper } if array[upper] < min { // means // array // has no // item // >= min // pos = array.length; return length } // we know that the next-smallest span was too small lower += (spansize >> 1) mid := 0 for lower+1 != upper { mid = (lower + upper) >> 1 if array[mid] == min { return mid } else if array[mid] < min { lower = mid } else { upper = mid } } return upper } func onesidedgallopingintersect2by2( smallset []uint16, largeset []uint16, buffer []uint16) int { if 0 == len(smallset) { return 0 } buffer = buffer[:cap(buffer)] k1 := 0 k2 := 0 pos := 0 s1 := largeset[k1] s2 := smallset[k2] mainwhile: for { if s1 < s2 { k1 = advanceUntil(largeset, k1, len(largeset), s2) if k1 == len(largeset) { break mainwhile } s1 = largeset[k1] } if s2 < s1 { k2++ if k2 == len(smallset) { break mainwhile } s2 = smallset[k2] } else { buffer[pos] = s2 pos++ k2++ if k2 == len(smallset) { break } s2 = smallset[k2] k1 = advanceUntil(largeset, k1, len(largeset), s2) if k1 == len(largeset) { break mainwhile } s1 = largeset[k1] } } return pos } func onesidedgallopingintersect2by2Cardinality( smallset []uint16, largeset []uint16) int { if 0 == len(smallset) { return 0 } k1 := 0 k2 := 0 pos := 0 s1 := largeset[k1] s2 := smallset[k2] mainwhile: for { if s1 < s2 { k1 = advanceUntil(largeset, k1, len(largeset), s2) if k1 == len(largeset) { break mainwhile } s1 = largeset[k1] } if s2 < s1 { k2++ if k2 == len(smallset) { break mainwhile } s2 = smallset[k2] } else { pos++ k2++ if k2 == len(smallset) { break } s2 = smallset[k2] k1 = advanceUntil(largeset, k1, len(largeset), s2) if k1 == len(largeset) { break mainwhile } s1 = largeset[k1] } } return pos } func binarySearch(array []uint16, ikey uint16) int { low := 0 high := len(array) - 1 for low+16 <= high { middleIndex := int(uint32(low+high) >> 1) middleValue := array[middleIndex] if middleValue < ikey { low = middleIndex + 1 } else if middleValue > ikey { high = middleIndex - 1 } else { return middleIndex } } for ; low <= high; low++ { val := array[low] if val >= ikey { if val == ikey { return low } break } } return -(low + 1) }