123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609 |
- 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) {
- 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)
- }
|