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 }