github.com/coyove/sdss@v0.0.0-20231129015646-c2ec58cca6a2/contrib/roaring/arraycontainer.go (about) 1 package roaring 2 3 import ( 4 "fmt" 5 ) 6 7 type arrayContainer struct { 8 content []uint16 9 } 10 11 func (ac *arrayContainer) String() string { 12 s := "{" 13 for it := ac.getShortIterator(); it.hasNext(); { 14 s += fmt.Sprintf("%v, ", it.next()) 15 } 16 return s + "}" 17 } 18 19 func (ac *arrayContainer) fillLeastSignificant16bits(x []uint32, i int, mask uint32) int { 20 for k := 0; k < len(ac.content); k++ { 21 x[k+i] = uint32(ac.content[k]) | mask 22 } 23 return i + len(ac.content) 24 } 25 26 func (ac *arrayContainer) iterate(cb func(x uint16) bool) bool { 27 iterator := shortIterator{ac.content, 0} 28 29 for iterator.hasNext() { 30 if !cb(iterator.next()) { 31 return false 32 } 33 } 34 35 return true 36 } 37 38 func (ac *arrayContainer) getShortIterator() shortPeekable { 39 return &shortIterator{ac.content, 0} 40 } 41 42 func (ac *arrayContainer) getReverseIterator() shortIterable { 43 return &reverseIterator{ac.content, len(ac.content) - 1} 44 } 45 46 func (ac *arrayContainer) getManyIterator() manyIterable { 47 return &shortIterator{ac.content, 0} 48 } 49 50 func (ac *arrayContainer) minimum() uint16 { 51 return ac.content[0] // assume not empty 52 } 53 54 func (ac *arrayContainer) maximum() uint16 { 55 return ac.content[len(ac.content)-1] // assume not empty 56 } 57 58 func (ac *arrayContainer) getSizeInBytes() int { 59 return ac.getCardinality() * 2 60 } 61 62 func (ac *arrayContainer) serializedSizeInBytes() int { 63 return ac.getCardinality() * 2 64 } 65 66 func arrayContainerSizeInBytes(card int) int { 67 return card * 2 68 } 69 70 // add the values in the range [firstOfRange,endx) 71 func (ac *arrayContainer) iaddRange(firstOfRange, endx int) container { 72 if firstOfRange >= endx { 73 return ac 74 } 75 indexstart := binarySearch(ac.content, uint16(firstOfRange)) 76 if indexstart < 0 { 77 indexstart = -indexstart - 1 78 } 79 indexend := binarySearch(ac.content, uint16(endx-1)) 80 if indexend < 0 { 81 indexend = -indexend - 1 82 } else { 83 indexend++ 84 } 85 rangelength := endx - firstOfRange 86 newcardinality := indexstart + (ac.getCardinality() - indexend) + rangelength 87 if newcardinality > arrayDefaultMaxSize { 88 a := ac.toBitmapContainer() 89 return a.iaddRange(firstOfRange, endx) 90 } 91 if cap(ac.content) < newcardinality { 92 tmp := make([]uint16, newcardinality, newcardinality) 93 copy(tmp[:indexstart], ac.content[:indexstart]) 94 copy(tmp[indexstart+rangelength:], ac.content[indexend:]) 95 96 ac.content = tmp 97 } else { 98 ac.content = ac.content[:newcardinality] 99 copy(ac.content[indexstart+rangelength:], ac.content[indexend:]) 100 101 } 102 for k := 0; k < rangelength; k++ { 103 ac.content[k+indexstart] = uint16(firstOfRange + k) 104 } 105 return ac 106 } 107 108 // remove the values in the range [firstOfRange,endx) 109 func (ac *arrayContainer) iremoveRange(firstOfRange, endx int) container { 110 if firstOfRange >= endx { 111 return ac 112 } 113 indexstart := binarySearch(ac.content, uint16(firstOfRange)) 114 if indexstart < 0 { 115 indexstart = -indexstart - 1 116 } 117 indexend := binarySearch(ac.content, uint16(endx-1)) 118 if indexend < 0 { 119 indexend = -indexend - 1 120 } else { 121 indexend++ 122 } 123 rangelength := indexend - indexstart 124 answer := ac 125 copy(answer.content[indexstart:], ac.content[indexstart+rangelength:]) 126 answer.content = answer.content[:ac.getCardinality()-rangelength] 127 return answer 128 } 129 130 // flip the values in the range [firstOfRange,endx) 131 func (ac *arrayContainer) not(firstOfRange, endx int) container { 132 if firstOfRange >= endx { 133 return ac.clone() 134 } 135 return ac.notClose(firstOfRange, endx-1) // remove everything in [firstOfRange,endx-1] 136 } 137 138 // flip the values in the range [firstOfRange,lastOfRange] 139 func (ac *arrayContainer) notClose(firstOfRange, lastOfRange int) container { 140 if firstOfRange > lastOfRange { // unlike add and remove, not uses an inclusive range [firstOfRange,lastOfRange] 141 return ac.clone() 142 } 143 144 // determine the span of array indices to be affected^M 145 startIndex := binarySearch(ac.content, uint16(firstOfRange)) 146 if startIndex < 0 { 147 startIndex = -startIndex - 1 148 } 149 lastIndex := binarySearch(ac.content, uint16(lastOfRange)) 150 if lastIndex < 0 { 151 lastIndex = -lastIndex - 2 152 } 153 currentValuesInRange := lastIndex - startIndex + 1 154 spanToBeFlipped := lastOfRange - firstOfRange + 1 155 newValuesInRange := spanToBeFlipped - currentValuesInRange 156 cardinalityChange := newValuesInRange - currentValuesInRange 157 newCardinality := len(ac.content) + cardinalityChange 158 if newCardinality > arrayDefaultMaxSize { 159 return ac.toBitmapContainer().not(firstOfRange, lastOfRange+1) 160 } 161 answer := newArrayContainer() 162 answer.content = make([]uint16, newCardinality, newCardinality) //a hack for sure 163 164 copy(answer.content, ac.content[:startIndex]) 165 outPos := startIndex 166 inPos := startIndex 167 valInRange := firstOfRange 168 for ; valInRange <= lastOfRange && inPos <= lastIndex; valInRange++ { 169 if uint16(valInRange) != ac.content[inPos] { 170 answer.content[outPos] = uint16(valInRange) 171 outPos++ 172 } else { 173 inPos++ 174 } 175 } 176 177 for ; valInRange <= lastOfRange; valInRange++ { 178 answer.content[outPos] = uint16(valInRange) 179 outPos++ 180 } 181 182 for i := lastIndex + 1; i < len(ac.content); i++ { 183 answer.content[outPos] = ac.content[i] 184 outPos++ 185 } 186 answer.content = answer.content[:newCardinality] 187 return answer 188 189 } 190 191 func (ac *arrayContainer) equals(o container) bool { 192 193 srb, ok := o.(*arrayContainer) 194 if ok { 195 // Check if the containers are the same object. 196 if ac == srb { 197 return true 198 } 199 200 if len(srb.content) != len(ac.content) { 201 return false 202 } 203 204 for i, v := range ac.content { 205 if v != srb.content[i] { 206 return false 207 } 208 } 209 return true 210 } 211 212 // use generic comparison 213 bCard := o.getCardinality() 214 aCard := ac.getCardinality() 215 if bCard != aCard { 216 return false 217 } 218 219 ait := ac.getShortIterator() 220 bit := o.getShortIterator() 221 for ait.hasNext() { 222 if bit.next() != ait.next() { 223 return false 224 } 225 } 226 return true 227 } 228 229 func (ac *arrayContainer) toBitmapContainer() *bitmapContainer { 230 bc := newBitmapContainer() 231 bc.loadData(ac) 232 return bc 233 234 } 235 func (ac *arrayContainer) iadd(x uint16) (wasNew bool) { 236 // Special case adding to the end of the container. 237 l := len(ac.content) 238 if l > 0 && l < arrayDefaultMaxSize && ac.content[l-1] < x { 239 ac.content = append(ac.content, x) 240 return true 241 } 242 243 loc := binarySearch(ac.content, x) 244 245 if loc < 0 { 246 s := ac.content 247 i := -loc - 1 248 s = append(s, 0) 249 copy(s[i+1:], s[i:]) 250 s[i] = x 251 ac.content = s 252 return true 253 } 254 return false 255 } 256 257 func (ac *arrayContainer) iaddReturnMinimized(x uint16) container { 258 // Special case adding to the end of the container. 259 l := len(ac.content) 260 if l > 0 && l < arrayDefaultMaxSize && ac.content[l-1] < x { 261 ac.content = append(ac.content, x) 262 return ac 263 } 264 265 loc := binarySearch(ac.content, x) 266 267 if loc < 0 { 268 if len(ac.content) >= arrayDefaultMaxSize { 269 a := ac.toBitmapContainer() 270 a.iadd(x) 271 return a 272 } 273 s := ac.content 274 i := -loc - 1 275 s = append(s, 0) 276 copy(s[i+1:], s[i:]) 277 s[i] = x 278 ac.content = s 279 } 280 return ac 281 } 282 283 // iremoveReturnMinimized is allowed to change the return type to minimize storage. 284 func (ac *arrayContainer) iremoveReturnMinimized(x uint16) container { 285 ac.iremove(x) 286 return ac 287 } 288 289 func (ac *arrayContainer) iremove(x uint16) bool { 290 loc := binarySearch(ac.content, x) 291 if loc >= 0 { 292 s := ac.content 293 s = append(s[:loc], s[loc+1:]...) 294 ac.content = s 295 return true 296 } 297 return false 298 } 299 300 func (ac *arrayContainer) remove(x uint16) container { 301 out := &arrayContainer{make([]uint16, len(ac.content))} 302 copy(out.content, ac.content[:]) 303 304 loc := binarySearch(out.content, x) 305 if loc >= 0 { 306 s := out.content 307 s = append(s[:loc], s[loc+1:]...) 308 out.content = s 309 } 310 return out 311 } 312 313 func (ac *arrayContainer) or(a container) container { 314 switch x := a.(type) { 315 case *arrayContainer: 316 return ac.orArray(x) 317 case *bitmapContainer: 318 return x.orArray(ac) 319 case *runContainer16: 320 if x.isFull() { 321 return x.clone() 322 } 323 return x.orArray(ac) 324 } 325 panic("unsupported container type") 326 } 327 328 func (ac *arrayContainer) orCardinality(a container) int { 329 switch x := a.(type) { 330 case *arrayContainer: 331 return ac.orArrayCardinality(x) 332 case *bitmapContainer: 333 return x.orArrayCardinality(ac) 334 case *runContainer16: 335 return x.orArrayCardinality(ac) 336 } 337 panic("unsupported container type") 338 } 339 340 func (ac *arrayContainer) ior(a container) container { 341 switch x := a.(type) { 342 case *arrayContainer: 343 return ac.iorArray(x) 344 case *bitmapContainer: 345 return a.(*bitmapContainer).orArray(ac) 346 //return ac.iorBitmap(x) // note: this does not make sense 347 case *runContainer16: 348 if x.isFull() { 349 return x.clone() 350 } 351 return ac.iorRun16(x) 352 } 353 panic("unsupported container type") 354 } 355 356 func (ac *arrayContainer) iorArray(value2 *arrayContainer) container { 357 value1 := ac 358 len1 := value1.getCardinality() 359 len2 := value2.getCardinality() 360 maxPossibleCardinality := len1 + len2 361 if maxPossibleCardinality > cap(value1.content) { 362 // doubling the capacity reduces new slice allocations in the case of 363 // repeated calls to iorArray(). 364 newSize := 2 * maxPossibleCardinality 365 // the second check is to handle overly large array containers 366 // and should not occur in normal usage, 367 // as all array containers should be at most arrayDefaultMaxSize 368 if newSize > 2*arrayDefaultMaxSize && maxPossibleCardinality <= 2*arrayDefaultMaxSize { 369 newSize = 2 * arrayDefaultMaxSize 370 } 371 newcontent := make([]uint16, 0, newSize) 372 copy(newcontent[len2:maxPossibleCardinality], ac.content[0:len1]) 373 ac.content = newcontent 374 } else { 375 copy(ac.content[len2:maxPossibleCardinality], ac.content[0:len1]) 376 } 377 nl := union2by2(value1.content[len2:maxPossibleCardinality], value2.content, ac.content) 378 ac.content = ac.content[:nl] // reslice to match actual used capacity 379 380 if nl > arrayDefaultMaxSize { 381 // Only converting to a bitmap when arrayDefaultMaxSize 382 // is actually exceeded minimizes conversions in the case of repeated 383 // calls to iorArray(). 384 return ac.toBitmapContainer() 385 } 386 return ac 387 } 388 389 // Note: such code does not make practical sense, except for lazy evaluations 390 func (ac *arrayContainer) iorBitmap(bc2 *bitmapContainer) container { 391 bc1 := ac.toBitmapContainer() 392 bc1.iorBitmap(bc2) 393 *ac = *newArrayContainerFromBitmap(bc1) 394 return ac 395 } 396 397 func (ac *arrayContainer) iorRun16(rc *runContainer16) container { 398 runCardinality := rc.getCardinality() 399 // heuristic for if the container should maybe be an 400 // array container. 401 if runCardinality < ac.getCardinality() && 402 runCardinality+ac.getCardinality() < arrayDefaultMaxSize { 403 var result container 404 result = ac 405 for _, run := range rc.iv { 406 result = result.iaddRange(int(run.start), int(run.start)+int(run.length)+1) 407 } 408 return result 409 } 410 return rc.orArray(ac) 411 } 412 413 func (ac *arrayContainer) lazyIOR(a container) container { 414 switch x := a.(type) { 415 case *arrayContainer: 416 return ac.lazyIorArray(x) 417 case *bitmapContainer: 418 return ac.lazyIorBitmap(x) 419 case *runContainer16: 420 if x.isFull() { 421 return x.clone() 422 } 423 return ac.lazyIorRun16(x) 424 425 } 426 panic("unsupported container type") 427 } 428 429 func (ac *arrayContainer) lazyIorArray(ac2 *arrayContainer) container { 430 // TODO actually make this lazy 431 return ac.iorArray(ac2) 432 } 433 434 func (ac *arrayContainer) lazyIorBitmap(bc *bitmapContainer) container { 435 // TODO actually make this lazy 436 return ac.iorBitmap(bc) 437 } 438 439 func (ac *arrayContainer) lazyIorRun16(rc *runContainer16) container { 440 // TODO actually make this lazy 441 return ac.iorRun16(rc) 442 } 443 444 func (ac *arrayContainer) lazyOR(a container) container { 445 switch x := a.(type) { 446 case *arrayContainer: 447 return ac.lazyorArray(x) 448 case *bitmapContainer: 449 return a.lazyOR(ac) 450 case *runContainer16: 451 if x.isFull() { 452 return x.clone() 453 } 454 return x.orArray(ac) 455 } 456 panic("unsupported container type") 457 } 458 459 func (ac *arrayContainer) orArray(value2 *arrayContainer) container { 460 value1 := ac 461 maxPossibleCardinality := value1.getCardinality() + value2.getCardinality() 462 if maxPossibleCardinality > arrayDefaultMaxSize { // it could be a bitmap! 463 bc := newBitmapContainer() 464 for k := 0; k < len(value2.content); k++ { 465 v := value2.content[k] 466 i := uint(v) >> 6 467 mask := uint64(1) << (v % 64) 468 bc.bitmap[i] |= mask 469 } 470 for k := 0; k < len(ac.content); k++ { 471 v := ac.content[k] 472 i := uint(v) >> 6 473 mask := uint64(1) << (v % 64) 474 bc.bitmap[i] |= mask 475 } 476 bc.cardinality = int(popcntSlice(bc.bitmap)) 477 if bc.cardinality <= arrayDefaultMaxSize { 478 return bc.toArrayContainer() 479 } 480 return bc 481 } 482 answer := newArrayContainerCapacity(maxPossibleCardinality) 483 nl := union2by2(value1.content, value2.content, answer.content) 484 answer.content = answer.content[:nl] // reslice to match actual used capacity 485 return answer 486 } 487 488 func (ac *arrayContainer) orArrayCardinality(value2 *arrayContainer) int { 489 return union2by2Cardinality(ac.content, value2.content) 490 } 491 492 func (ac *arrayContainer) lazyorArray(value2 *arrayContainer) container { 493 value1 := ac 494 maxPossibleCardinality := value1.getCardinality() + value2.getCardinality() 495 if maxPossibleCardinality > arrayLazyLowerBound { // it could be a bitmap! 496 bc := newBitmapContainer() 497 for k := 0; k < len(value2.content); k++ { 498 v := value2.content[k] 499 i := uint(v) >> 6 500 mask := uint64(1) << (v % 64) 501 bc.bitmap[i] |= mask 502 } 503 for k := 0; k < len(ac.content); k++ { 504 v := ac.content[k] 505 i := uint(v) >> 6 506 mask := uint64(1) << (v % 64) 507 bc.bitmap[i] |= mask 508 } 509 bc.cardinality = invalidCardinality 510 return bc 511 } 512 answer := newArrayContainerCapacity(maxPossibleCardinality) 513 nl := union2by2(value1.content, value2.content, answer.content) 514 answer.content = answer.content[:nl] // reslice to match actual used capacity 515 return answer 516 } 517 518 func (ac *arrayContainer) and(a container) container { 519 switch x := a.(type) { 520 case *arrayContainer: 521 return ac.andArray(x) 522 case *bitmapContainer: 523 return x.and(ac) 524 case *runContainer16: 525 if x.isFull() { 526 return ac.clone() 527 } 528 return x.andArray(ac) 529 } 530 panic("unsupported container type") 531 } 532 533 func (ac *arrayContainer) andCardinality(a container) int { 534 switch x := a.(type) { 535 case *arrayContainer: 536 return ac.andArrayCardinality(x) 537 case *bitmapContainer: 538 return x.andCardinality(ac) 539 case *runContainer16: 540 return x.andArrayCardinality(ac) 541 } 542 panic("unsupported container type") 543 } 544 545 func (ac *arrayContainer) intersects(a container) bool { 546 switch x := a.(type) { 547 case *arrayContainer: 548 return ac.intersectsArray(x) 549 case *bitmapContainer: 550 return x.intersects(ac) 551 case *runContainer16: 552 return x.intersects(ac) 553 } 554 panic("unsupported container type") 555 } 556 557 func (ac *arrayContainer) iand(a container) container { 558 switch x := a.(type) { 559 case *arrayContainer: 560 return ac.iandArray(x) 561 case *bitmapContainer: 562 return ac.iandBitmap(x) 563 case *runContainer16: 564 if x.isFull() { 565 return ac 566 } 567 return x.andArray(ac) 568 } 569 panic("unsupported container type") 570 } 571 572 func (ac *arrayContainer) iandBitmap(bc *bitmapContainer) container { 573 pos := 0 574 c := ac.getCardinality() 575 for k := 0; k < c; k++ { 576 // branchless 577 v := ac.content[k] 578 ac.content[pos] = v 579 pos += int(bc.bitValue(v)) 580 } 581 ac.content = ac.content[:pos] 582 return ac 583 584 } 585 586 func (ac *arrayContainer) xor(a container) container { 587 switch x := a.(type) { 588 case *arrayContainer: 589 return ac.xorArray(x) 590 case *bitmapContainer: 591 return a.xor(ac) 592 case *runContainer16: 593 return x.xorArray(ac) 594 } 595 panic("unsupported container type") 596 } 597 598 func (ac *arrayContainer) xorArray(value2 *arrayContainer) container { 599 value1 := ac 600 totalCardinality := value1.getCardinality() + value2.getCardinality() 601 if totalCardinality > arrayDefaultMaxSize { // it could be a bitmap! 602 bc := newBitmapContainer() 603 for k := 0; k < len(value2.content); k++ { 604 v := value2.content[k] 605 i := uint(v) >> 6 606 bc.bitmap[i] ^= (uint64(1) << (v % 64)) 607 } 608 for k := 0; k < len(ac.content); k++ { 609 v := ac.content[k] 610 i := uint(v) >> 6 611 bc.bitmap[i] ^= (uint64(1) << (v % 64)) 612 } 613 bc.computeCardinality() 614 if bc.cardinality <= arrayDefaultMaxSize { 615 return bc.toArrayContainer() 616 } 617 return bc 618 } 619 desiredCapacity := totalCardinality 620 answer := newArrayContainerCapacity(desiredCapacity) 621 length := exclusiveUnion2by2(value1.content, value2.content, answer.content) 622 answer.content = answer.content[:length] 623 return answer 624 625 } 626 627 func (ac *arrayContainer) andNot(a container) container { 628 switch x := a.(type) { 629 case *arrayContainer: 630 return ac.andNotArray(x) 631 case *bitmapContainer: 632 return ac.andNotBitmap(x) 633 case *runContainer16: 634 return ac.andNotRun16(x) 635 } 636 panic("unsupported container type") 637 } 638 639 func (ac *arrayContainer) andNotRun16(rc *runContainer16) container { 640 acb := ac.toBitmapContainer() 641 rcb := rc.toBitmapContainer() 642 return acb.andNotBitmap(rcb) 643 } 644 645 func (ac *arrayContainer) iandNot(a container) container { 646 switch x := a.(type) { 647 case *arrayContainer: 648 return ac.iandNotArray(x) 649 case *bitmapContainer: 650 return ac.iandNotBitmap(x) 651 case *runContainer16: 652 return ac.iandNotRun16(x) 653 } 654 panic("unsupported container type") 655 } 656 657 func (ac *arrayContainer) iandNotRun16(rc *runContainer16) container { 658 rcb := rc.toBitmapContainer() 659 acb := ac.toBitmapContainer() 660 acb.iandNotBitmapSurely(rcb) 661 *ac = *(acb.toArrayContainer()) 662 return ac 663 } 664 665 func (ac *arrayContainer) andNotArray(value2 *arrayContainer) container { 666 value1 := ac 667 desiredcapacity := value1.getCardinality() 668 answer := newArrayContainerCapacity(desiredcapacity) 669 length := difference(value1.content, value2.content, answer.content) 670 answer.content = answer.content[:length] 671 return answer 672 } 673 674 func (ac *arrayContainer) iandNotArray(value2 *arrayContainer) container { 675 length := difference(ac.content, value2.content, ac.content) 676 ac.content = ac.content[:length] 677 return ac 678 } 679 680 func (ac *arrayContainer) andNotBitmap(value2 *bitmapContainer) container { 681 desiredcapacity := ac.getCardinality() 682 answer := newArrayContainerCapacity(desiredcapacity) 683 answer.content = answer.content[:desiredcapacity] 684 pos := 0 685 for _, v := range ac.content { 686 answer.content[pos] = v 687 pos += 1 - int(value2.bitValue(v)) 688 } 689 answer.content = answer.content[:pos] 690 return answer 691 } 692 693 func (ac *arrayContainer) andBitmap(value2 *bitmapContainer) container { 694 desiredcapacity := ac.getCardinality() 695 answer := newArrayContainerCapacity(desiredcapacity) 696 answer.content = answer.content[:desiredcapacity] 697 pos := 0 698 for _, v := range ac.content { 699 answer.content[pos] = v 700 pos += int(value2.bitValue(v)) 701 } 702 answer.content = answer.content[:pos] 703 return answer 704 } 705 706 func (ac *arrayContainer) iandNotBitmap(value2 *bitmapContainer) container { 707 pos := 0 708 for _, v := range ac.content { 709 ac.content[pos] = v 710 pos += 1 - int(value2.bitValue(v)) 711 } 712 ac.content = ac.content[:pos] 713 return ac 714 } 715 716 func copyOf(array []uint16, size int) []uint16 { 717 result := make([]uint16, size) 718 for i, x := range array { 719 if i == size { 720 break 721 } 722 result[i] = x 723 } 724 return result 725 } 726 727 // flip the values in the range [firstOfRange,endx) 728 func (ac *arrayContainer) inot(firstOfRange, endx int) container { 729 if firstOfRange >= endx { 730 return ac 731 } 732 return ac.inotClose(firstOfRange, endx-1) // remove everything in [firstOfRange,endx-1] 733 } 734 735 // flip the values in the range [firstOfRange,lastOfRange] 736 func (ac *arrayContainer) inotClose(firstOfRange, lastOfRange int) container { 737 if firstOfRange > lastOfRange { // unlike add and remove, not uses an inclusive range [firstOfRange,lastOfRange] 738 return ac 739 } 740 // determine the span of array indices to be affected 741 startIndex := binarySearch(ac.content, uint16(firstOfRange)) 742 if startIndex < 0 { 743 startIndex = -startIndex - 1 744 } 745 lastIndex := binarySearch(ac.content, uint16(lastOfRange)) 746 if lastIndex < 0 { 747 lastIndex = -lastIndex - 1 - 1 748 } 749 currentValuesInRange := lastIndex - startIndex + 1 750 spanToBeFlipped := lastOfRange - firstOfRange + 1 751 752 newValuesInRange := spanToBeFlipped - currentValuesInRange 753 buffer := make([]uint16, newValuesInRange) 754 cardinalityChange := newValuesInRange - currentValuesInRange 755 newCardinality := len(ac.content) + cardinalityChange 756 if cardinalityChange > 0 { 757 if newCardinality > len(ac.content) { 758 if newCardinality > arrayDefaultMaxSize { 759 bcRet := ac.toBitmapContainer() 760 bcRet.inot(firstOfRange, lastOfRange+1) 761 *ac = *bcRet.toArrayContainer() 762 return bcRet 763 } 764 ac.content = copyOf(ac.content, newCardinality) 765 } 766 base := lastIndex + 1 767 copy(ac.content[lastIndex+1+cardinalityChange:], ac.content[base:base+len(ac.content)-1-lastIndex]) 768 ac.negateRange(buffer, startIndex, lastIndex, firstOfRange, lastOfRange+1) 769 } else { // no expansion needed 770 ac.negateRange(buffer, startIndex, lastIndex, firstOfRange, lastOfRange+1) 771 if cardinalityChange < 0 { 772 773 for i := startIndex + newValuesInRange; i < newCardinality; i++ { 774 ac.content[i] = ac.content[i-cardinalityChange] 775 } 776 } 777 } 778 ac.content = ac.content[:newCardinality] 779 return ac 780 } 781 782 func (ac *arrayContainer) negateRange(buffer []uint16, startIndex, lastIndex, startRange, lastRange int) { 783 // compute the negation into buffer 784 outPos := 0 785 inPos := startIndex // value here always >= valInRange, 786 // until it is exhausted 787 // n.b., we can start initially exhausted. 788 789 valInRange := startRange 790 for ; valInRange < lastRange && inPos <= lastIndex; valInRange++ { 791 if uint16(valInRange) != ac.content[inPos] { 792 buffer[outPos] = uint16(valInRange) 793 outPos++ 794 } else { 795 inPos++ 796 } 797 } 798 799 // if there are extra items (greater than the biggest 800 // pre-existing one in range), buffer them 801 for ; valInRange < lastRange; valInRange++ { 802 buffer[outPos] = uint16(valInRange) 803 outPos++ 804 } 805 806 if outPos != len(buffer) { 807 panic("negateRange: internal bug") 808 } 809 810 for i, item := range buffer { 811 ac.content[i+startIndex] = item 812 } 813 } 814 815 func (ac *arrayContainer) isFull() bool { 816 return false 817 } 818 819 func (ac *arrayContainer) andArray(value2 *arrayContainer) container { 820 desiredcapacity := minOfInt(ac.getCardinality(), value2.getCardinality()) 821 answer := newArrayContainerCapacity(desiredcapacity) 822 length := intersection2by2( 823 ac.content, 824 value2.content, 825 answer.content) 826 answer.content = answer.content[:length] 827 return answer 828 } 829 830 func (ac *arrayContainer) andArrayCardinality(value2 *arrayContainer) int { 831 return intersection2by2Cardinality( 832 ac.content, 833 value2.content) 834 } 835 836 func (ac *arrayContainer) intersectsArray(value2 *arrayContainer) bool { 837 return intersects2by2( 838 ac.content, 839 value2.content) 840 } 841 842 func (ac *arrayContainer) iandArray(value2 *arrayContainer) container { 843 length := intersection2by2( 844 ac.content, 845 value2.content, 846 ac.content) 847 ac.content = ac.content[:length] 848 return ac 849 } 850 851 func (ac *arrayContainer) getCardinality() int { 852 return len(ac.content) 853 } 854 855 func (ac *arrayContainer) isEmpty() bool { 856 return len(ac.content) == 0 857 } 858 859 func (ac *arrayContainer) rank(x uint16) int { 860 answer := binarySearch(ac.content, x) 861 if answer >= 0 { 862 return answer + 1 863 } 864 return -answer - 1 865 866 } 867 868 func (ac *arrayContainer) selectInt(x uint16) int { 869 return int(ac.content[x]) 870 } 871 872 func (ac *arrayContainer) clone() container { 873 ptr := arrayContainer{make([]uint16, len(ac.content))} 874 copy(ptr.content, ac.content[:]) 875 return &ptr 876 } 877 878 func (ac *arrayContainer) contains(x uint16) bool { 879 return binarySearch(ac.content, x) >= 0 880 } 881 882 func (ac *arrayContainer) loadData(bitmapContainer *bitmapContainer) { 883 ac.content = make([]uint16, bitmapContainer.cardinality, bitmapContainer.cardinality) 884 bitmapContainer.fillArray(ac.content) 885 } 886 887 func (ac *arrayContainer) resetTo(a container) { 888 switch x := a.(type) { 889 case *arrayContainer: 890 ac.realloc(len(x.content)) 891 copy(ac.content, x.content) 892 893 case *bitmapContainer: 894 ac.realloc(x.cardinality) 895 x.fillArray(ac.content) 896 897 case *runContainer16: 898 card := int(x.getCardinality()) 899 ac.realloc(card) 900 cur := 0 901 for _, r := range x.iv { 902 for val := r.start; val <= r.last(); val++ { 903 ac.content[cur] = val 904 cur++ 905 } 906 } 907 908 default: 909 panic("unsupported container type") 910 } 911 } 912 913 func (ac *arrayContainer) realloc(size int) { 914 if cap(ac.content) < size { 915 ac.content = make([]uint16, size) 916 } else { 917 ac.content = ac.content[:size] 918 } 919 } 920 921 func newArrayContainer() *arrayContainer { 922 p := new(arrayContainer) 923 return p 924 } 925 926 func newArrayContainerFromBitmap(bc *bitmapContainer) *arrayContainer { 927 ac := &arrayContainer{} 928 ac.loadData(bc) 929 return ac 930 } 931 932 func newArrayContainerCapacity(size int) *arrayContainer { 933 p := new(arrayContainer) 934 p.content = make([]uint16, 0, size) 935 return p 936 } 937 938 func newArrayContainerSize(size int) *arrayContainer { 939 p := new(arrayContainer) 940 p.content = make([]uint16, size, size) 941 return p 942 } 943 944 func newArrayContainerRange(firstOfRun, lastOfRun int) *arrayContainer { 945 valuesInRange := lastOfRun - firstOfRun + 1 946 this := newArrayContainerCapacity(valuesInRange) 947 for i := 0; i < valuesInRange; i++ { 948 this.content = append(this.content, uint16(firstOfRun+i)) 949 } 950 return this 951 } 952 953 func (ac *arrayContainer) numberOfRuns() (nr int) { 954 n := len(ac.content) 955 var runlen uint16 956 var cur, prev uint16 957 958 switch n { 959 case 0: 960 return 0 961 case 1: 962 return 1 963 default: 964 for i := 1; i < n; i++ { 965 prev = ac.content[i-1] 966 cur = ac.content[i] 967 968 if cur == prev+1 { 969 runlen++ 970 } else { 971 if cur < prev { 972 panic("the fundamental arrayContainer assumption of sorted ac.content was broken") 973 } 974 if cur == prev { 975 panic("the fundamental arrayContainer assumption of deduplicated content was broken") 976 } else { 977 nr++ 978 runlen = 0 979 } 980 } 981 } 982 nr++ 983 } 984 return 985 } 986 987 // convert to run or array *if needed* 988 func (ac *arrayContainer) toEfficientContainer() container { 989 990 numRuns := ac.numberOfRuns() 991 992 sizeAsRunContainer := runContainer16SerializedSizeInBytes(numRuns) 993 sizeAsBitmapContainer := bitmapContainerSizeInBytes() 994 card := ac.getCardinality() 995 sizeAsArrayContainer := arrayContainerSizeInBytes(card) 996 997 if sizeAsRunContainer <= minOfInt(sizeAsBitmapContainer, sizeAsArrayContainer) { 998 return newRunContainer16FromArray(ac) 999 } 1000 if card <= arrayDefaultMaxSize { 1001 return ac 1002 } 1003 return ac.toBitmapContainer() 1004 } 1005 1006 func (ac *arrayContainer) containerType() contype { 1007 return arrayContype 1008 } 1009 1010 func (ac *arrayContainer) addOffset(x uint16) (container, container) { 1011 var low, high *arrayContainer 1012 1013 if len(ac.content) == 0 { 1014 return nil, nil 1015 } 1016 1017 if y := uint32(ac.content[0]) + uint32(x); highbits(y) == 0 { 1018 // Some elements will fall into low part, allocate a container. 1019 // Checking the first one is enough because they are ordered. 1020 low = &arrayContainer{} 1021 } 1022 if y := uint32(ac.content[len(ac.content)-1]) + uint32(x); highbits(y) > 0 { 1023 // Some elements will fall into high part, allocate a container. 1024 // Checking the last one is enough because they are ordered. 1025 high = &arrayContainer{} 1026 } 1027 1028 for _, val := range ac.content { 1029 y := uint32(val) + uint32(x) 1030 if highbits(y) > 0 { 1031 // OK, if high == nil then highbits(y) == 0 for all y. 1032 high.content = append(high.content, lowbits(y)) 1033 } else { 1034 // OK, if low == nil then highbits(y) > 0 for all y. 1035 low.content = append(low.content, lowbits(y)) 1036 } 1037 } 1038 1039 // Ensure proper nil interface. 1040 if low == nil { 1041 return nil, high 1042 } 1043 if high == nil { 1044 return low, nil 1045 } 1046 1047 return low, high 1048 }