github.com/coyove/sdss@v0.0.0-20231129015646-c2ec58cca6a2/contrib/roaring/bitmapcontainer.go (about) 1 package roaring 2 3 import ( 4 "fmt" 5 "unsafe" 6 ) 7 8 type bitmapContainer struct { 9 cardinality int 10 bitmap []uint64 11 } 12 13 func (bc bitmapContainer) String() string { 14 var s string 15 for it := bc.getShortIterator(); it.hasNext(); { 16 s += fmt.Sprintf("%v, ", it.next()) 17 } 18 return s 19 } 20 21 func newBitmapContainer() *bitmapContainer { 22 p := new(bitmapContainer) 23 size := (1 << 16) / 64 24 p.bitmap = make([]uint64, size, size) 25 return p 26 } 27 28 func newBitmapContainerwithRange(firstOfRun, lastOfRun int) *bitmapContainer { 29 bc := newBitmapContainer() 30 bc.cardinality = lastOfRun - firstOfRun + 1 31 if bc.cardinality == maxCapacity { 32 fill(bc.bitmap, uint64(0xffffffffffffffff)) 33 } else { 34 firstWord := firstOfRun / 64 35 lastWord := lastOfRun / 64 36 zeroPrefixLength := uint64(firstOfRun & 63) 37 zeroSuffixLength := uint64(63 - (lastOfRun & 63)) 38 39 fillRange(bc.bitmap, firstWord, lastWord+1, uint64(0xffffffffffffffff)) 40 bc.bitmap[firstWord] ^= ((uint64(1) << zeroPrefixLength) - 1) 41 blockOfOnes := (uint64(1) << zeroSuffixLength) - 1 42 maskOnLeft := blockOfOnes << (uint64(64) - zeroSuffixLength) 43 bc.bitmap[lastWord] ^= maskOnLeft 44 } 45 return bc 46 } 47 48 func (bc *bitmapContainer) minimum() uint16 { 49 for i := 0; i < len(bc.bitmap); i++ { 50 w := bc.bitmap[i] 51 if w != 0 { 52 r := countTrailingZeros(w) 53 return uint16(r + i*64) 54 } 55 } 56 return MaxUint16 57 } 58 59 // i should be non-zero 60 func clz(i uint64) int { 61 n := 1 62 x := uint32(i >> 32) 63 if x == 0 { 64 n += 32 65 x = uint32(i) 66 } 67 if x>>16 == 0 { 68 n += 16 69 x = x << 16 70 } 71 if x>>24 == 0 { 72 n += 8 73 x = x << 8 74 } 75 if x>>28 == 0 { 76 n += 4 77 x = x << 4 78 } 79 if x>>30 == 0 { 80 n += 2 81 x = x << 2 82 } 83 return n - int(x>>31) 84 } 85 86 func (bc *bitmapContainer) maximum() uint16 { 87 for i := len(bc.bitmap); i > 0; i-- { 88 w := bc.bitmap[i-1] 89 if w != 0 { 90 r := clz(w) 91 return uint16((i-1)*64 + 63 - r) 92 } 93 } 94 return uint16(0) 95 } 96 97 func (bc *bitmapContainer) iterate(cb func(x uint16) bool) bool { 98 iterator := bitmapContainerShortIterator{bc, bc.NextSetBit(0)} 99 100 for iterator.hasNext() { 101 if !cb(iterator.next()) { 102 return false 103 } 104 } 105 106 return true 107 } 108 109 type bitmapContainerShortIterator struct { 110 ptr *bitmapContainer 111 i int 112 } 113 114 func (bcsi *bitmapContainerShortIterator) next() uint16 { 115 j := bcsi.i 116 bcsi.i = bcsi.ptr.NextSetBit(uint(bcsi.i) + 1) 117 return uint16(j) 118 } 119 func (bcsi *bitmapContainerShortIterator) hasNext() bool { 120 return bcsi.i >= 0 121 } 122 123 func (bcsi *bitmapContainerShortIterator) peekNext() uint16 { 124 return uint16(bcsi.i) 125 } 126 127 func (bcsi *bitmapContainerShortIterator) advanceIfNeeded(minval uint16) { 128 if bcsi.hasNext() && bcsi.peekNext() < minval { 129 bcsi.i = bcsi.ptr.NextSetBit(uint(minval)) 130 } 131 } 132 133 func newBitmapContainerShortIterator(a *bitmapContainer) *bitmapContainerShortIterator { 134 return &bitmapContainerShortIterator{a, a.NextSetBit(0)} 135 } 136 137 func (bc *bitmapContainer) getShortIterator() shortPeekable { 138 return newBitmapContainerShortIterator(bc) 139 } 140 141 type reverseBitmapContainerShortIterator struct { 142 ptr *bitmapContainer 143 i int 144 } 145 146 func (bcsi *reverseBitmapContainerShortIterator) next() uint16 { 147 if bcsi.i == -1 { 148 panic("reverseBitmapContainerShortIterator.next() going beyond what is available") 149 } 150 151 j := bcsi.i 152 bcsi.i = bcsi.ptr.PrevSetBit(bcsi.i - 1) 153 return uint16(j) 154 } 155 156 func (bcsi *reverseBitmapContainerShortIterator) hasNext() bool { 157 return bcsi.i >= 0 158 } 159 160 func newReverseBitmapContainerShortIterator(a *bitmapContainer) *reverseBitmapContainerShortIterator { 161 if a.cardinality == 0 { 162 return &reverseBitmapContainerShortIterator{a, -1} 163 } 164 return &reverseBitmapContainerShortIterator{a, int(a.maximum())} 165 } 166 167 func (bc *bitmapContainer) getReverseIterator() shortIterable { 168 return newReverseBitmapContainerShortIterator(bc) 169 } 170 171 type bitmapContainerManyIterator struct { 172 ptr *bitmapContainer 173 base int 174 bitset uint64 175 } 176 177 func (bcmi *bitmapContainerManyIterator) nextMany(hs uint32, buf []uint32) int { 178 n := 0 179 base := bcmi.base 180 bitset := bcmi.bitset 181 182 for n < len(buf) { 183 if bitset == 0 { 184 base++ 185 if base >= len(bcmi.ptr.bitmap) { 186 bcmi.base = base 187 bcmi.bitset = bitset 188 return n 189 } 190 bitset = bcmi.ptr.bitmap[base] 191 continue 192 } 193 t := bitset & -bitset 194 buf[n] = uint32(((base * 64) + int(popcount(t-1)))) | hs 195 n = n + 1 196 bitset ^= t 197 } 198 199 bcmi.base = base 200 bcmi.bitset = bitset 201 return n 202 } 203 204 func (bcmi *bitmapContainerManyIterator) nextMany64(hs uint64, buf []uint64) int { 205 n := 0 206 base := bcmi.base 207 bitset := bcmi.bitset 208 209 for n < len(buf) { 210 if bitset == 0 { 211 base++ 212 if base >= len(bcmi.ptr.bitmap) { 213 bcmi.base = base 214 bcmi.bitset = bitset 215 return n 216 } 217 bitset = bcmi.ptr.bitmap[base] 218 continue 219 } 220 t := bitset & -bitset 221 buf[n] = uint64(((base * 64) + int(popcount(t-1)))) | hs 222 n = n + 1 223 bitset ^= t 224 } 225 226 bcmi.base = base 227 bcmi.bitset = bitset 228 return n 229 } 230 231 func newBitmapContainerManyIterator(a *bitmapContainer) *bitmapContainerManyIterator { 232 return &bitmapContainerManyIterator{a, -1, 0} 233 } 234 235 func (bc *bitmapContainer) getManyIterator() manyIterable { 236 return newBitmapContainerManyIterator(bc) 237 } 238 239 func (bc *bitmapContainer) getSizeInBytes() int { 240 return len(bc.bitmap) * 8 // + bcBaseBytes 241 } 242 243 func (bc *bitmapContainer) serializedSizeInBytes() int { 244 //return bc.Msgsize()// NOO! This breaks GetSerializedSizeInBytes 245 return len(bc.bitmap) * 8 246 } 247 248 const bcBaseBytes = int(unsafe.Sizeof(bitmapContainer{})) 249 250 // bitmapContainer doesn't depend on card, always fully allocated 251 func bitmapContainerSizeInBytes() int { 252 return bcBaseBytes + (1<<16)/8 253 } 254 255 func bitmapEquals(a, b []uint64) bool { 256 if len(a) != len(b) { 257 return false 258 } 259 for i, v := range a { 260 if v != b[i] { 261 return false 262 } 263 } 264 return true 265 } 266 267 func (bc *bitmapContainer) fillLeastSignificant16bits(x []uint32, i int, mask uint32) int { 268 // TODO: should be written as optimized assembly 269 pos := i 270 base := mask 271 for k := 0; k < len(bc.bitmap); k++ { 272 bitset := bc.bitmap[k] 273 for bitset != 0 { 274 t := bitset & -bitset 275 x[pos] = base + uint32(popcount(t-1)) 276 pos++ 277 bitset ^= t 278 } 279 base += 64 280 } 281 return pos 282 } 283 284 func (bc *bitmapContainer) equals(o container) bool { 285 srb, ok := o.(*bitmapContainer) 286 if ok { 287 if srb.cardinality != bc.cardinality { 288 return false 289 } 290 return bitmapEquals(bc.bitmap, srb.bitmap) 291 } 292 293 // use generic comparison 294 if bc.getCardinality() != o.getCardinality() { 295 return false 296 } 297 ait := o.getShortIterator() 298 bit := bc.getShortIterator() 299 300 for ait.hasNext() { 301 if bit.next() != ait.next() { 302 return false 303 } 304 } 305 return true 306 } 307 308 func (bc *bitmapContainer) iaddReturnMinimized(i uint16) container { 309 bc.iadd(i) 310 if bc.isFull() { 311 return newRunContainer16Range(0, MaxUint16) 312 } 313 return bc 314 } 315 316 func (bc *bitmapContainer) iadd(i uint16) bool { 317 x := int(i) 318 previous := bc.bitmap[x/64] 319 mask := uint64(1) << (uint(x) % 64) 320 newb := previous | mask 321 bc.bitmap[x/64] = newb 322 bc.cardinality += int((previous ^ newb) >> (uint(x) % 64)) 323 return newb != previous 324 } 325 326 func (bc *bitmapContainer) iremoveReturnMinimized(i uint16) container { 327 if bc.iremove(i) { 328 if bc.cardinality == arrayDefaultMaxSize { 329 return bc.toArrayContainer() 330 } 331 } 332 return bc 333 } 334 335 // iremove returns true if i was found. 336 func (bc *bitmapContainer) iremove(i uint16) bool { 337 if bc.contains(i) { 338 bc.cardinality-- 339 bc.bitmap[i/64] &^= (uint64(1) << (i % 64)) 340 return true 341 } 342 return false 343 } 344 345 func (bc *bitmapContainer) isFull() bool { 346 return bc.cardinality == int(MaxUint16)+1 347 } 348 349 func (bc *bitmapContainer) getCardinality() int { 350 return bc.cardinality 351 } 352 353 func (bc *bitmapContainer) isEmpty() bool { 354 return bc.cardinality == 0 355 } 356 357 func (bc *bitmapContainer) clone() container { 358 ptr := bitmapContainer{bc.cardinality, make([]uint64, len(bc.bitmap))} 359 copy(ptr.bitmap, bc.bitmap[:]) 360 return &ptr 361 } 362 363 // add all values in range [firstOfRange,lastOfRange) 364 func (bc *bitmapContainer) iaddRange(firstOfRange, lastOfRange int) container { 365 bc.cardinality += setBitmapRangeAndCardinalityChange(bc.bitmap, firstOfRange, lastOfRange) 366 return bc 367 } 368 369 // remove all values in range [firstOfRange,lastOfRange) 370 func (bc *bitmapContainer) iremoveRange(firstOfRange, lastOfRange int) container { 371 bc.cardinality += resetBitmapRangeAndCardinalityChange(bc.bitmap, firstOfRange, lastOfRange) 372 if bc.getCardinality() <= arrayDefaultMaxSize { 373 return bc.toArrayContainer() 374 } 375 return bc 376 } 377 378 // flip all values in range [firstOfRange,endx) 379 func (bc *bitmapContainer) inot(firstOfRange, endx int) container { 380 if endx-firstOfRange == maxCapacity { 381 flipBitmapRange(bc.bitmap, firstOfRange, endx) 382 bc.cardinality = maxCapacity - bc.cardinality 383 } else if endx-firstOfRange > maxCapacity/2 { 384 flipBitmapRange(bc.bitmap, firstOfRange, endx) 385 bc.computeCardinality() 386 } else { 387 bc.cardinality += flipBitmapRangeAndCardinalityChange(bc.bitmap, firstOfRange, endx) 388 } 389 if bc.getCardinality() <= arrayDefaultMaxSize { 390 return bc.toArrayContainer() 391 } 392 return bc 393 } 394 395 // flip all values in range [firstOfRange,endx) 396 func (bc *bitmapContainer) not(firstOfRange, endx int) container { 397 answer := bc.clone() 398 return answer.inot(firstOfRange, endx) 399 } 400 401 func (bc *bitmapContainer) or(a container) container { 402 switch x := a.(type) { 403 case *arrayContainer: 404 return bc.orArray(x) 405 case *bitmapContainer: 406 return bc.orBitmap(x) 407 case *runContainer16: 408 if x.isFull() { 409 return x.clone() 410 } 411 return x.orBitmapContainer(bc) 412 } 413 panic("unsupported container type") 414 } 415 416 func (bc *bitmapContainer) orCardinality(a container) int { 417 switch x := a.(type) { 418 case *arrayContainer: 419 return bc.orArrayCardinality(x) 420 case *bitmapContainer: 421 return bc.orBitmapCardinality(x) 422 case *runContainer16: 423 return x.orBitmapContainerCardinality(bc) 424 } 425 panic("unsupported container type") 426 } 427 428 func (bc *bitmapContainer) ior(a container) container { 429 switch x := a.(type) { 430 case *arrayContainer: 431 return bc.iorArray(x) 432 case *bitmapContainer: 433 return bc.iorBitmap(x) 434 case *runContainer16: 435 if x.isFull() { 436 return x.clone() 437 } 438 for i := range x.iv { 439 bc.iaddRange(int(x.iv[i].start), int(x.iv[i].last())+1) 440 } 441 if bc.isFull() { 442 return newRunContainer16Range(0, MaxUint16) 443 } 444 //bc.computeCardinality() 445 return bc 446 } 447 panic(fmt.Errorf("unsupported container type %T", a)) 448 } 449 450 func (bc *bitmapContainer) lazyIOR(a container) container { 451 switch x := a.(type) { 452 case *arrayContainer: 453 return bc.lazyIORArray(x) 454 case *bitmapContainer: 455 return bc.lazyIORBitmap(x) 456 case *runContainer16: 457 if x.isFull() { 458 return x.clone() 459 } 460 461 // Manually inlined setBitmapRange function 462 bitmap := bc.bitmap 463 for _, iv := range x.iv { 464 start := int(iv.start) 465 end := int(iv.last()) + 1 466 if start >= end { 467 continue 468 } 469 firstword := start / 64 470 endword := (end - 1) / 64 471 if firstword == endword { 472 bitmap[firstword] |= (^uint64(0) << uint(start%64)) & (^uint64(0) >> (uint(-end) % 64)) 473 continue 474 } 475 bitmap[firstword] |= ^uint64(0) << uint(start%64) 476 for i := firstword + 1; i < endword; i++ { 477 bitmap[i] = ^uint64(0) 478 } 479 bitmap[endword] |= ^uint64(0) >> (uint(-end) % 64) 480 } 481 bc.cardinality = invalidCardinality 482 return bc 483 } 484 panic("unsupported container type") 485 } 486 487 func (bc *bitmapContainer) lazyOR(a container) container { 488 switch x := a.(type) { 489 case *arrayContainer: 490 return bc.lazyORArray(x) 491 case *bitmapContainer: 492 return bc.lazyORBitmap(x) 493 case *runContainer16: 494 if x.isFull() { 495 return x.clone() 496 } 497 // TODO: implement lazy OR 498 return x.orBitmapContainer(bc) 499 500 } 501 panic("unsupported container type") 502 } 503 504 func (bc *bitmapContainer) orArray(value2 *arrayContainer) container { 505 answer := bc.clone().(*bitmapContainer) 506 c := value2.getCardinality() 507 for k := 0; k < c; k++ { 508 v := value2.content[k] 509 i := uint(v) >> 6 510 bef := answer.bitmap[i] 511 aft := bef | (uint64(1) << (v % 64)) 512 answer.bitmap[i] = aft 513 answer.cardinality += int((bef - aft) >> 63) 514 } 515 return answer 516 } 517 518 func (bc *bitmapContainer) orArrayCardinality(value2 *arrayContainer) int { 519 answer := 0 520 c := value2.getCardinality() 521 for k := 0; k < c; k++ { 522 // branchless: 523 v := value2.content[k] 524 i := uint(v) >> 6 525 bef := bc.bitmap[i] 526 aft := bef | (uint64(1) << (v % 64)) 527 answer += int((bef - aft) >> 63) 528 } 529 return answer 530 } 531 532 func (bc *bitmapContainer) orBitmap(value2 *bitmapContainer) container { 533 answer := newBitmapContainer() 534 for k := 0; k < len(answer.bitmap); k++ { 535 answer.bitmap[k] = bc.bitmap[k] | value2.bitmap[k] 536 } 537 answer.computeCardinality() 538 if answer.isFull() { 539 return newRunContainer16Range(0, MaxUint16) 540 } 541 return answer 542 } 543 544 func (bc *bitmapContainer) orBitmapCardinality(value2 *bitmapContainer) int { 545 return int(popcntOrSlice(bc.bitmap, value2.bitmap)) 546 } 547 548 func (bc *bitmapContainer) andBitmapCardinality(value2 *bitmapContainer) int { 549 return int(popcntAndSlice(bc.bitmap, value2.bitmap)) 550 } 551 552 func (bc *bitmapContainer) computeCardinality() { 553 bc.cardinality = int(popcntSlice(bc.bitmap)) 554 } 555 556 func (bc *bitmapContainer) iorArray(ac *arrayContainer) container { 557 for k := range ac.content { 558 vc := ac.content[k] 559 i := uint(vc) >> 6 560 bef := bc.bitmap[i] 561 aft := bef | (uint64(1) << (vc % 64)) 562 bc.bitmap[i] = aft 563 bc.cardinality += int((bef - aft) >> 63) 564 } 565 if bc.isFull() { 566 return newRunContainer16Range(0, MaxUint16) 567 } 568 return bc 569 } 570 571 func (bc *bitmapContainer) iorBitmap(value2 *bitmapContainer) container { 572 answer := bc 573 answer.cardinality = 0 574 for k := 0; k < len(answer.bitmap); k++ { 575 answer.bitmap[k] = bc.bitmap[k] | value2.bitmap[k] 576 } 577 answer.computeCardinality() 578 if bc.isFull() { 579 return newRunContainer16Range(0, MaxUint16) 580 } 581 return answer 582 } 583 584 func (bc *bitmapContainer) lazyIORArray(value2 *arrayContainer) container { 585 answer := bc 586 c := value2.getCardinality() 587 for k := 0; k+3 < c; k += 4 { 588 content := (*[4]uint16)(unsafe.Pointer(&value2.content[k])) 589 vc0 := content[0] 590 i0 := uint(vc0) >> 6 591 answer.bitmap[i0] = answer.bitmap[i0] | (uint64(1) << (vc0 % 64)) 592 593 vc1 := content[1] 594 i1 := uint(vc1) >> 6 595 answer.bitmap[i1] = answer.bitmap[i1] | (uint64(1) << (vc1 % 64)) 596 597 vc2 := content[2] 598 i2 := uint(vc2) >> 6 599 answer.bitmap[i2] = answer.bitmap[i2] | (uint64(1) << (vc2 % 64)) 600 601 vc3 := content[3] 602 i3 := uint(vc3) >> 6 603 answer.bitmap[i3] = answer.bitmap[i3] | (uint64(1) << (vc3 % 64)) 604 } 605 606 for k := c &^ 3; k < c; k++ { 607 vc := value2.content[k] 608 i := uint(vc) >> 6 609 answer.bitmap[i] = answer.bitmap[i] | (uint64(1) << (vc % 64)) 610 } 611 612 answer.cardinality = invalidCardinality 613 return answer 614 } 615 616 func (bc *bitmapContainer) lazyORArray(value2 *arrayContainer) container { 617 answer := bc.clone().(*bitmapContainer) 618 return answer.lazyIORArray(value2) 619 } 620 621 func (bc *bitmapContainer) lazyIORBitmap(value2 *bitmapContainer) container { 622 answer := bc 623 for k := 0; k < len(answer.bitmap); k++ { 624 answer.bitmap[k] = bc.bitmap[k] | value2.bitmap[k] 625 } 626 bc.cardinality = invalidCardinality 627 return answer 628 } 629 630 func (bc *bitmapContainer) lazyORBitmap(value2 *bitmapContainer) container { 631 answer := bc.clone().(*bitmapContainer) 632 return answer.lazyIORBitmap(value2) 633 } 634 635 func (bc *bitmapContainer) xor(a container) container { 636 switch x := a.(type) { 637 case *arrayContainer: 638 return bc.xorArray(x) 639 case *bitmapContainer: 640 return bc.xorBitmap(x) 641 case *runContainer16: 642 return x.xorBitmap(bc) 643 } 644 panic("unsupported container type") 645 } 646 647 func (bc *bitmapContainer) xorArray(value2 *arrayContainer) container { 648 answer := bc.clone().(*bitmapContainer) 649 c := value2.getCardinality() 650 for k := 0; k < c; k++ { 651 vc := value2.content[k] 652 index := uint(vc) >> 6 653 abi := answer.bitmap[index] 654 mask := uint64(1) << (vc % 64) 655 answer.cardinality += 1 - 2*int((abi&mask)>>(vc%64)) 656 answer.bitmap[index] = abi ^ mask 657 } 658 if answer.cardinality <= arrayDefaultMaxSize { 659 return answer.toArrayContainer() 660 } 661 return answer 662 } 663 664 func (bc *bitmapContainer) rank(x uint16) int { 665 // TODO: rewrite in assembly 666 leftover := (uint(x) + 1) & 63 667 if leftover == 0 { 668 return int(popcntSlice(bc.bitmap[:(uint(x)+1)/64])) 669 } 670 return int(popcntSlice(bc.bitmap[:(uint(x)+1)/64]) + popcount(bc.bitmap[(uint(x)+1)/64]<<(64-leftover))) 671 } 672 673 func (bc *bitmapContainer) selectInt(x uint16) int { 674 remaining := x 675 for k := 0; k < len(bc.bitmap); k++ { 676 w := popcount(bc.bitmap[k]) 677 if uint16(w) > remaining { 678 return k*64 + selectBitPosition(bc.bitmap[k], int(remaining)) 679 } 680 remaining -= uint16(w) 681 } 682 return -1 683 } 684 685 func (bc *bitmapContainer) xorBitmap(value2 *bitmapContainer) container { 686 newCardinality := int(popcntXorSlice(bc.bitmap, value2.bitmap)) 687 688 if newCardinality > arrayDefaultMaxSize { 689 answer := newBitmapContainer() 690 for k := 0; k < len(answer.bitmap); k++ { 691 answer.bitmap[k] = bc.bitmap[k] ^ value2.bitmap[k] 692 } 693 answer.cardinality = newCardinality 694 if answer.isFull() { 695 return newRunContainer16Range(0, MaxUint16) 696 } 697 return answer 698 } 699 ac := newArrayContainerSize(newCardinality) 700 fillArrayXOR(ac.content, bc.bitmap, value2.bitmap) 701 ac.content = ac.content[:newCardinality] 702 return ac 703 } 704 705 func (bc *bitmapContainer) and(a container) container { 706 switch x := a.(type) { 707 case *arrayContainer: 708 return bc.andArray(x) 709 case *bitmapContainer: 710 return bc.andBitmap(x) 711 case *runContainer16: 712 if x.isFull() { 713 return bc.clone() 714 } 715 return x.andBitmapContainer(bc) 716 } 717 panic("unsupported container type") 718 } 719 720 func (bc *bitmapContainer) andCardinality(a container) int { 721 switch x := a.(type) { 722 case *arrayContainer: 723 return bc.andArrayCardinality(x) 724 case *bitmapContainer: 725 return bc.andBitmapCardinality(x) 726 case *runContainer16: 727 return x.andBitmapContainerCardinality(bc) 728 } 729 panic("unsupported container type") 730 } 731 732 func (bc *bitmapContainer) intersects(a container) bool { 733 switch x := a.(type) { 734 case *arrayContainer: 735 return bc.intersectsArray(x) 736 case *bitmapContainer: 737 return bc.intersectsBitmap(x) 738 case *runContainer16: 739 return x.intersects(bc) 740 741 } 742 panic("unsupported container type") 743 } 744 745 func (bc *bitmapContainer) iand(a container) container { 746 switch x := a.(type) { 747 case *arrayContainer: 748 return bc.iandArray(x) 749 case *bitmapContainer: 750 return bc.iandBitmap(x) 751 case *runContainer16: 752 if x.isFull() { 753 return bc.clone() 754 } 755 return bc.iandRun16(x) 756 } 757 panic("unsupported container type") 758 } 759 760 func (bc *bitmapContainer) iandRun16(rc *runContainer16) container { 761 rcb := newBitmapContainerFromRun(rc) 762 return bc.iandBitmap(rcb) 763 } 764 765 func (bc *bitmapContainer) iandArray(ac *arrayContainer) container { 766 acb := ac.toBitmapContainer() 767 return bc.iandBitmap(acb) 768 } 769 770 func (bc *bitmapContainer) andArray(value2 *arrayContainer) *arrayContainer { 771 answer := newArrayContainerCapacity(len(value2.content)) 772 answer.content = answer.content[:cap(answer.content)] 773 c := value2.getCardinality() 774 pos := 0 775 for k := 0; k < c; k++ { 776 v := value2.content[k] 777 answer.content[pos] = v 778 pos += int(bc.bitValue(v)) 779 } 780 answer.content = answer.content[:pos] 781 return answer 782 } 783 784 func (bc *bitmapContainer) andArrayCardinality(value2 *arrayContainer) int { 785 c := value2.getCardinality() 786 pos := 0 787 for k := 0; k < c; k++ { 788 v := value2.content[k] 789 pos += int(bc.bitValue(v)) 790 } 791 return pos 792 } 793 794 func (bc *bitmapContainer) getCardinalityInRange(start, end uint) int { 795 if start >= end { 796 return 0 797 } 798 firstword := start / 64 799 endword := (end - 1) / 64 800 const allones = ^uint64(0) 801 if firstword == endword { 802 return int(popcount(bc.bitmap[firstword] & ((allones << (start % 64)) & (allones >> ((64 - end) & 63))))) 803 } 804 answer := popcount(bc.bitmap[firstword] & (allones << (start % 64))) 805 answer += popcntSlice(bc.bitmap[firstword+1 : endword]) 806 answer += popcount(bc.bitmap[endword] & (allones >> ((64 - end) & 63))) 807 return int(answer) 808 } 809 810 func (bc *bitmapContainer) andBitmap(value2 *bitmapContainer) container { 811 newcardinality := int(popcntAndSlice(bc.bitmap, value2.bitmap)) 812 if newcardinality > arrayDefaultMaxSize { 813 answer := newBitmapContainer() 814 for k := 0; k < len(answer.bitmap); k++ { 815 answer.bitmap[k] = bc.bitmap[k] & value2.bitmap[k] 816 } 817 answer.cardinality = newcardinality 818 return answer 819 } 820 ac := newArrayContainerSize(newcardinality) 821 fillArrayAND(ac.content, bc.bitmap, value2.bitmap) 822 ac.content = ac.content[:newcardinality] //not sure why i need this 823 return ac 824 825 } 826 827 func (bc *bitmapContainer) intersectsArray(value2 *arrayContainer) bool { 828 c := value2.getCardinality() 829 for k := 0; k < c; k++ { 830 v := value2.content[k] 831 if bc.contains(v) { 832 return true 833 } 834 } 835 return false 836 } 837 838 func (bc *bitmapContainer) intersectsBitmap(value2 *bitmapContainer) bool { 839 for k := 0; k < len(bc.bitmap); k++ { 840 if (bc.bitmap[k] & value2.bitmap[k]) != 0 { 841 return true 842 } 843 } 844 return false 845 846 } 847 848 func (bc *bitmapContainer) iandBitmap(value2 *bitmapContainer) container { 849 newcardinality := int(popcntAndSlice(bc.bitmap, value2.bitmap)) 850 for k := 0; k < len(bc.bitmap); k++ { 851 bc.bitmap[k] = bc.bitmap[k] & value2.bitmap[k] 852 } 853 bc.cardinality = newcardinality 854 855 if newcardinality <= arrayDefaultMaxSize { 856 return newArrayContainerFromBitmap(bc) 857 } 858 return bc 859 } 860 861 func (bc *bitmapContainer) andNot(a container) container { 862 switch x := a.(type) { 863 case *arrayContainer: 864 return bc.andNotArray(x) 865 case *bitmapContainer: 866 return bc.andNotBitmap(x) 867 case *runContainer16: 868 return bc.andNotRun16(x) 869 } 870 panic("unsupported container type") 871 } 872 873 func (bc *bitmapContainer) andNotRun16(rc *runContainer16) container { 874 rcb := rc.toBitmapContainer() 875 return bc.andNotBitmap(rcb) 876 } 877 878 func (bc *bitmapContainer) iandNot(a container) container { 879 switch x := a.(type) { 880 case *arrayContainer: 881 return bc.iandNotArray(x) 882 case *bitmapContainer: 883 return bc.iandNotBitmapSurely(x) 884 case *runContainer16: 885 return bc.iandNotRun16(x) 886 } 887 panic("unsupported container type") 888 } 889 890 func (bc *bitmapContainer) iandNotArray(ac *arrayContainer) container { 891 acb := ac.toBitmapContainer() 892 return bc.iandNotBitmapSurely(acb) 893 } 894 895 func (bc *bitmapContainer) iandNotRun16(rc *runContainer16) container { 896 rcb := rc.toBitmapContainer() 897 return bc.iandNotBitmapSurely(rcb) 898 } 899 900 func (bc *bitmapContainer) andNotArray(value2 *arrayContainer) container { 901 answer := bc.clone().(*bitmapContainer) 902 c := value2.getCardinality() 903 for k := 0; k < c; k++ { 904 vc := value2.content[k] 905 i := uint(vc) >> 6 906 oldv := answer.bitmap[i] 907 newv := oldv &^ (uint64(1) << (vc % 64)) 908 answer.bitmap[i] = newv 909 answer.cardinality -= int((oldv ^ newv) >> (vc % 64)) 910 } 911 if answer.cardinality <= arrayDefaultMaxSize { 912 return answer.toArrayContainer() 913 } 914 return answer 915 } 916 917 func (bc *bitmapContainer) andNotBitmap(value2 *bitmapContainer) container { 918 newCardinality := int(popcntMaskSlice(bc.bitmap, value2.bitmap)) 919 if newCardinality > arrayDefaultMaxSize { 920 answer := newBitmapContainer() 921 for k := 0; k < len(answer.bitmap); k++ { 922 answer.bitmap[k] = bc.bitmap[k] &^ value2.bitmap[k] 923 } 924 answer.cardinality = newCardinality 925 return answer 926 } 927 ac := newArrayContainerSize(newCardinality) 928 fillArrayANDNOT(ac.content, bc.bitmap, value2.bitmap) 929 return ac 930 } 931 932 func (bc *bitmapContainer) iandNotBitmapSurely(value2 *bitmapContainer) container { 933 newCardinality := int(popcntMaskSlice(bc.bitmap, value2.bitmap)) 934 for k := 0; k < len(bc.bitmap); k++ { 935 bc.bitmap[k] = bc.bitmap[k] &^ value2.bitmap[k] 936 } 937 bc.cardinality = newCardinality 938 if bc.getCardinality() <= arrayDefaultMaxSize { 939 return bc.toArrayContainer() 940 } 941 return bc 942 } 943 944 func (bc *bitmapContainer) contains(i uint16) bool { //testbit 945 x := uint(i) 946 w := bc.bitmap[x>>6] 947 mask := uint64(1) << (x & 63) 948 return (w & mask) != 0 949 } 950 951 func (bc *bitmapContainer) bitValue(i uint16) uint64 { 952 x := uint(i) 953 w := bc.bitmap[x>>6] 954 return (w >> (x & 63)) & 1 955 } 956 957 func (bc *bitmapContainer) loadData(arrayContainer *arrayContainer) { 958 bc.cardinality = arrayContainer.getCardinality() 959 c := arrayContainer.getCardinality() 960 for k := 0; k < c; k++ { 961 x := arrayContainer.content[k] 962 i := int(x) / 64 963 bc.bitmap[i] |= (uint64(1) << uint(x%64)) 964 } 965 } 966 967 func (bc *bitmapContainer) resetTo(a container) { 968 switch x := a.(type) { 969 case *arrayContainer: 970 fill(bc.bitmap, 0) 971 bc.loadData(x) 972 973 case *bitmapContainer: 974 bc.cardinality = x.cardinality 975 copy(bc.bitmap, x.bitmap) 976 977 case *runContainer16: 978 bc.cardinality = len(x.iv) 979 lastEnd := 0 980 for _, r := range x.iv { 981 bc.cardinality += int(r.length) 982 resetBitmapRange(bc.bitmap, lastEnd, int(r.start)) 983 lastEnd = int(r.start+r.length) + 1 984 setBitmapRange(bc.bitmap, int(r.start), lastEnd) 985 } 986 resetBitmapRange(bc.bitmap, lastEnd, maxCapacity) 987 988 default: 989 panic("unsupported container type") 990 } 991 } 992 993 func (bc *bitmapContainer) toArrayContainer() *arrayContainer { 994 ac := &arrayContainer{} 995 ac.loadData(bc) 996 return ac 997 } 998 999 func (bc *bitmapContainer) fillArray(container []uint16) { 1000 //TODO: rewrite in assembly 1001 pos := 0 1002 base := 0 1003 for k := 0; k < len(bc.bitmap); k++ { 1004 bitset := bc.bitmap[k] 1005 for bitset != 0 { 1006 t := bitset & -bitset 1007 container[pos] = uint16((base + int(popcount(t-1)))) 1008 pos = pos + 1 1009 bitset ^= t 1010 } 1011 base += 64 1012 } 1013 } 1014 1015 func (bc *bitmapContainer) NextSetBit(i uint) int { 1016 var ( 1017 x = i / 64 1018 length = uint(len(bc.bitmap)) 1019 ) 1020 if x >= length { 1021 return -1 1022 } 1023 w := bc.bitmap[x] 1024 w = w >> uint(i%64) 1025 if w != 0 { 1026 return int(i) + countTrailingZeros(w) 1027 } 1028 x++ 1029 for ; x < length; x++ { 1030 if bc.bitmap[x] != 0 { 1031 return int(x*64) + countTrailingZeros(bc.bitmap[x]) 1032 } 1033 } 1034 return -1 1035 } 1036 1037 func (bc *bitmapContainer) PrevSetBit(i int) int { 1038 if i < 0 { 1039 return -1 1040 } 1041 x := i / 64 1042 if x >= len(bc.bitmap) { 1043 return -1 1044 } 1045 1046 w := bc.bitmap[x] 1047 1048 b := i % 64 1049 1050 w = w << uint(63-b) 1051 if w != 0 { 1052 return i - countLeadingZeros(w) 1053 } 1054 x-- 1055 for ; x >= 0; x-- { 1056 if bc.bitmap[x] != 0 { 1057 return (x * 64) + 63 - countLeadingZeros(bc.bitmap[x]) 1058 } 1059 } 1060 return -1 1061 } 1062 1063 // reference the java implementation 1064 // https://github.com/RoaringBitmap/RoaringBitmap/blob/master/src/main/java/org/roaringbitmap/BitmapContainer.java#L875-L892 1065 // 1066 func (bc *bitmapContainer) numberOfRuns() int { 1067 if bc.cardinality == 0 { 1068 return 0 1069 } 1070 1071 var numRuns uint64 1072 nextWord := bc.bitmap[0] 1073 1074 for i := 0; i < len(bc.bitmap)-1; i++ { 1075 word := nextWord 1076 nextWord = bc.bitmap[i+1] 1077 numRuns += popcount((^word)&(word<<1)) + ((word >> 63) &^ nextWord) 1078 } 1079 1080 word := nextWord 1081 numRuns += popcount((^word) & (word << 1)) 1082 if (word & 0x8000000000000000) != 0 { 1083 numRuns++ 1084 } 1085 1086 return int(numRuns) 1087 } 1088 1089 // convert to run or array *if needed* 1090 func (bc *bitmapContainer) toEfficientContainer() container { 1091 1092 numRuns := bc.numberOfRuns() 1093 1094 sizeAsRunContainer := runContainer16SerializedSizeInBytes(numRuns) 1095 sizeAsBitmapContainer := bitmapContainerSizeInBytes() 1096 card := bc.getCardinality() 1097 sizeAsArrayContainer := arrayContainerSizeInBytes(card) 1098 1099 if sizeAsRunContainer <= minOfInt(sizeAsBitmapContainer, sizeAsArrayContainer) { 1100 return newRunContainer16FromBitmapContainer(bc) 1101 } 1102 if card <= arrayDefaultMaxSize { 1103 return bc.toArrayContainer() 1104 } 1105 return bc 1106 } 1107 1108 func newBitmapContainerFromRun(rc *runContainer16) *bitmapContainer { 1109 1110 if len(rc.iv) == 1 { 1111 return newBitmapContainerwithRange(int(rc.iv[0].start), int(rc.iv[0].last())) 1112 } 1113 1114 bc := newBitmapContainer() 1115 for i := range rc.iv { 1116 setBitmapRange(bc.bitmap, int(rc.iv[i].start), int(rc.iv[i].last())+1) 1117 bc.cardinality += int(rc.iv[i].last()) + 1 - int(rc.iv[i].start) 1118 } 1119 //bc.computeCardinality() 1120 return bc 1121 } 1122 1123 func (bc *bitmapContainer) containerType() contype { 1124 return bitmapContype 1125 } 1126 1127 func (bc *bitmapContainer) addOffset(x uint16) (container, container) { 1128 var low, high *bitmapContainer 1129 1130 if bc.cardinality == 0 { 1131 return nil, nil 1132 } 1133 1134 b := uint32(x) >> 6 1135 i := uint32(x) % 64 1136 end := uint32(1024) - b 1137 1138 low = newBitmapContainer() 1139 if i == 0 { 1140 copy(low.bitmap[b:], bc.bitmap[:end]) 1141 } else { 1142 low.bitmap[b] = bc.bitmap[0] << i 1143 for k := uint32(1); k < end; k++ { 1144 newval := bc.bitmap[k] << i 1145 newval |= bc.bitmap[k-1] >> (64 - i) 1146 low.bitmap[b+k] = newval 1147 } 1148 } 1149 low.computeCardinality() 1150 1151 if low.cardinality == bc.cardinality { 1152 // All elements from bc ended up in low, meaning high will be empty. 1153 return low, nil 1154 } 1155 1156 if low.cardinality == 0 { 1157 // low is empty, let's reuse the container for high. 1158 high = low 1159 low = nil 1160 } else { 1161 // None of the containers will be empty, so allocate both. 1162 high = newBitmapContainer() 1163 } 1164 1165 if i == 0 { 1166 copy(high.bitmap[:b], bc.bitmap[end:]) 1167 } else { 1168 for k := end; k < 1024; k++ { 1169 newval := bc.bitmap[k] << i 1170 newval |= bc.bitmap[k-1] >> (64 - i) 1171 high.bitmap[k-end] = newval 1172 } 1173 high.bitmap[b] = bc.bitmap[1023] >> (64 - i) 1174 } 1175 high.computeCardinality() 1176 1177 // Ensure proper nil interface. 1178 if low == nil { 1179 return nil, high 1180 } 1181 1182 return low, high 1183 }