github.com/gopherd/gonum@v0.0.4/container/intsets/sparse.go (about) 1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package intsets provides Sparse, a compact and fast representation 6 // for sparse sets of int values. 7 // 8 // The time complexity of the operations Len, Insert, Remove and Has 9 // is in O(n) but in practice those methods are faster and more 10 // space-efficient than equivalent operations on sets based on the Go 11 // map type. The IsEmpty, Min, Max, Clear and TakeMin operations 12 // require constant time. 13 // 14 package intsets 15 16 // TODO(adonovan): 17 // - Add InsertAll(...int), RemoveAll(...int) 18 // - Add 'bool changed' results for {Intersection,Difference}With too. 19 // 20 // TODO(adonovan): implement Dense, a dense bit vector with a similar API. 21 // The space usage would be proportional to Max(), not Len(), and the 22 // implementation would be based upon big.Int. 23 // 24 // TODO(adonovan): opt: make UnionWith and Difference faster. 25 // These are the hot-spots for go/pointer. 26 27 import ( 28 "bytes" 29 "fmt" 30 "math/bits" 31 ) 32 33 // A Sparse is a set of int values. 34 // Sparse operations (even queries) are not concurrency-safe. 35 // 36 // The zero value for Sparse is a valid empty set. 37 // 38 // Sparse sets must be copied using the Copy method, not by assigning 39 // a Sparse value. 40 // 41 type Sparse struct { 42 // An uninitialized Sparse represents an empty set. 43 // An empty set may also be represented by 44 // root.next == root.prev == &root. 45 // 46 // The root is always the block with the smallest offset. 47 // It can be empty, but only if it is the only block; in that case, offset is 48 // MaxInt (which is not a valid offset). 49 root block 50 } 51 52 type word uintptr 53 54 const ( 55 _m = ^word(0) 56 bitsPerWord = 8 << (_m>>8&1 + _m>>16&1 + _m>>32&1) 57 bitsPerBlock = 256 // optimal value for go/pointer solver performance 58 wordsPerBlock = bitsPerBlock / bitsPerWord 59 ) 60 61 // Limit values of implementation-specific int type. 62 const ( 63 MaxInt = int(^uint(0) >> 1) 64 MinInt = -MaxInt - 1 65 ) 66 67 // popcount returns the number of set bits in w. 68 func popcount(x word) int { 69 // Avoid OnesCount(uint): don't assume uint = uintptr. 70 if bitsPerWord == 32 { 71 return bits.OnesCount32(uint32(x)) 72 } else { 73 return bits.OnesCount64(uint64(x)) 74 } 75 } 76 77 // nlz returns the number of leading zeros of x. 78 func nlz(x word) int { 79 // Avoid LeadingZeros(uint): don't assume uint = uintptr. 80 if bitsPerWord == 32 { 81 return bits.LeadingZeros32(uint32(x)) 82 } else { 83 return bits.LeadingZeros64(uint64(x)) 84 } 85 } 86 87 // ntz returns the number of trailing zeros of x. 88 func ntz(x word) int { 89 // Avoid TrailingZeros(uint): don't assume uint = uintptr. 90 if bitsPerWord == 32 { 91 return bits.TrailingZeros32(uint32(x)) 92 } else { 93 return bits.TrailingZeros64(uint64(x)) 94 } 95 } 96 97 // -- block ------------------------------------------------------------ 98 99 // A set is represented as a circular doubly-linked list of blocks, 100 // each containing an offset and a bit array of fixed size 101 // bitsPerBlock; the blocks are ordered by increasing offset. 102 // 103 // The set contains an element x iff the block whose offset is x - (x 104 // mod bitsPerBlock) has the bit (x mod bitsPerBlock) set, where mod 105 // is the Euclidean remainder. 106 // 107 // A block may only be empty transiently. 108 // 109 type block struct { 110 offset int // offset mod bitsPerBlock == 0 111 bits [wordsPerBlock]word // contains at least one set bit 112 next, prev *block // doubly-linked list of blocks 113 } 114 115 // wordMask returns the word index (in block.bits) 116 // and single-bit mask for the block's ith bit. 117 func wordMask(i uint) (w uint, mask word) { 118 w = i / bitsPerWord 119 mask = 1 << (i % bitsPerWord) 120 return 121 } 122 123 // insert sets the block b's ith bit and 124 // returns true if it was not already set. 125 // 126 func (b *block) insert(i uint) bool { 127 w, mask := wordMask(i) 128 if b.bits[w]&mask == 0 { 129 b.bits[w] |= mask 130 return true 131 } 132 return false 133 } 134 135 // remove clears the block's ith bit and 136 // returns true if the bit was previously set. 137 // NB: may leave the block empty. 138 // 139 func (b *block) remove(i uint) bool { 140 w, mask := wordMask(i) 141 if b.bits[w]&mask != 0 { 142 b.bits[w] &^= mask 143 return true 144 } 145 return false 146 } 147 148 // has reports whether the block's ith bit is set. 149 func (b *block) has(i uint) bool { 150 w, mask := wordMask(i) 151 return b.bits[w]&mask != 0 152 } 153 154 // empty reports whether b.len()==0, but more efficiently. 155 func (b *block) empty() bool { 156 for _, w := range b.bits { 157 if w != 0 { 158 return false 159 } 160 } 161 return true 162 } 163 164 // len returns the number of set bits in block b. 165 func (b *block) len() int { 166 var l int 167 for _, w := range b.bits { 168 l += popcount(w) 169 } 170 return l 171 } 172 173 // max returns the maximum element of the block. 174 // The block must not be empty. 175 func (b *block) max() int { 176 bi := b.offset + bitsPerBlock 177 // Decrement bi by number of high zeros in last.bits. 178 for i := len(b.bits) - 1; i >= 0; i-- { 179 if w := b.bits[i]; w != 0 { 180 return bi - nlz(w) - 1 181 } 182 bi -= bitsPerWord 183 } 184 panic("BUG: empty block") 185 } 186 187 // min returns the minimum element of the block, 188 // and also removes it if take is set. 189 // The block must not be initially empty. 190 // NB: may leave the block empty. 191 func (b *block) min(take bool) int { 192 for i, w := range b.bits { 193 if w != 0 { 194 tz := ntz(w) 195 if take { 196 b.bits[i] = w &^ (1 << uint(tz)) 197 } 198 return b.offset + int(i*bitsPerWord) + tz 199 } 200 } 201 panic("BUG: empty block") 202 } 203 204 // lowerBound returns the smallest element of the block that is greater than or 205 // equal to the element corresponding to the ith bit. If there is no such 206 // element, the second return value is false. 207 func (b *block) lowerBound(i uint) (int, bool) { 208 w := i / bitsPerWord 209 bit := i % bitsPerWord 210 211 if val := b.bits[w] >> bit; val != 0 { 212 return b.offset + int(i) + ntz(val), true 213 } 214 215 for w++; w < wordsPerBlock; w++ { 216 if val := b.bits[w]; val != 0 { 217 return b.offset + int(w*bitsPerWord) + ntz(val), true 218 } 219 } 220 221 return 0, false 222 } 223 224 // forEach calls f for each element of block b. 225 // f must not mutate b's enclosing Sparse. 226 func (b *block) forEach(f func(int)) { 227 for i, w := range b.bits { 228 offset := b.offset + i*bitsPerWord 229 for bi := 0; w != 0 && bi < bitsPerWord; bi++ { 230 if w&1 != 0 { 231 f(offset) 232 } 233 offset++ 234 w >>= 1 235 } 236 } 237 } 238 239 // offsetAndBitIndex returns the offset of the block that would 240 // contain x and the bit index of x within that block. 241 // 242 func offsetAndBitIndex(x int) (int, uint) { 243 mod := x % bitsPerBlock 244 if mod < 0 { 245 // Euclidean (non-negative) remainder 246 mod += bitsPerBlock 247 } 248 return x - mod, uint(mod) 249 } 250 251 // -- Sparse -------------------------------------------------------------- 252 253 // none is a shared, empty, sentinel block that indicates the end of a block 254 // list. 255 var none block 256 257 // Dummy type used to generate an implicit panic. This must be defined at the 258 // package level; if it is defined inside a function, it prevents the inlining 259 // of that function. 260 type to_copy_a_sparse_you_must_call_its_Copy_method struct{} 261 262 // init ensures s is properly initialized. 263 func (s *Sparse) init() { 264 root := &s.root 265 if root.next == nil { 266 root.offset = MaxInt 267 root.next = root 268 root.prev = root 269 } else if root.next.prev != root { 270 // Copying a Sparse x leads to pernicious corruption: the 271 // new Sparse y shares the old linked list, but iteration 272 // on y will never encounter &y.root so it goes into a 273 // loop. Fail fast before this occurs. 274 // We don't want to call panic here because it prevents the 275 // inlining of this function. 276 _ = (interface{}(nil)).(to_copy_a_sparse_you_must_call_its_Copy_method) 277 } 278 } 279 280 func (s *Sparse) first() *block { 281 s.init() 282 if s.root.offset == MaxInt { 283 return &none 284 } 285 return &s.root 286 } 287 288 // next returns the next block in the list, or end if b is the last block. 289 func (s *Sparse) next(b *block) *block { 290 if b.next == &s.root { 291 return &none 292 } 293 return b.next 294 } 295 296 // prev returns the previous block in the list, or end if b is the first block. 297 func (s *Sparse) prev(b *block) *block { 298 if b.prev == &s.root { 299 return &none 300 } 301 return b.prev 302 } 303 304 // IsEmpty reports whether the set s is empty. 305 func (s *Sparse) IsEmpty() bool { 306 return s.root.next == nil || s.root.offset == MaxInt 307 } 308 309 // Len returns the number of elements in the set s. 310 func (s *Sparse) Len() int { 311 var l int 312 for b := s.first(); b != &none; b = s.next(b) { 313 l += b.len() 314 } 315 return l 316 } 317 318 // Max returns the maximum element of the set s, or MinInt if s is empty. 319 func (s *Sparse) Max() int { 320 if s.IsEmpty() { 321 return MinInt 322 } 323 return s.root.prev.max() 324 } 325 326 // Min returns the minimum element of the set s, or MaxInt if s is empty. 327 func (s *Sparse) Min() int { 328 if s.IsEmpty() { 329 return MaxInt 330 } 331 return s.root.min(false) 332 } 333 334 // LowerBound returns the smallest element >= x, or MaxInt if there is no such 335 // element. 336 func (s *Sparse) LowerBound(x int) int { 337 offset, i := offsetAndBitIndex(x) 338 for b := s.first(); b != &none; b = s.next(b) { 339 if b.offset > offset { 340 return b.min(false) 341 } 342 if b.offset == offset { 343 if y, ok := b.lowerBound(i); ok { 344 return y 345 } 346 } 347 } 348 return MaxInt 349 } 350 351 // block returns the block that would contain offset, 352 // or nil if s contains no such block. 353 // Precondition: offset is a multiple of bitsPerBlock. 354 func (s *Sparse) block(offset int) *block { 355 for b := s.first(); b != &none && b.offset <= offset; b = s.next(b) { 356 if b.offset == offset { 357 return b 358 } 359 } 360 return nil 361 } 362 363 // Insert adds x to the set s, and reports whether the set grew. 364 func (s *Sparse) Insert(x int) bool { 365 offset, i := offsetAndBitIndex(x) 366 367 b := s.first() 368 for ; b != &none && b.offset <= offset; b = s.next(b) { 369 if b.offset == offset { 370 return b.insert(i) 371 } 372 } 373 374 // Insert new block before b. 375 new := s.insertBlockBefore(b) 376 new.offset = offset 377 return new.insert(i) 378 } 379 380 // removeBlock removes a block and returns the block that followed it (or end if 381 // it was the last block). 382 func (s *Sparse) removeBlock(b *block) *block { 383 if b != &s.root { 384 b.prev.next = b.next 385 b.next.prev = b.prev 386 if b.next == &s.root { 387 return &none 388 } 389 return b.next 390 } 391 392 first := s.root.next 393 if first == &s.root { 394 // This was the only block. 395 s.Clear() 396 return &none 397 } 398 s.root.offset = first.offset 399 s.root.bits = first.bits 400 if first.next == &s.root { 401 // Single block remaining. 402 s.root.next = &s.root 403 s.root.prev = &s.root 404 } else { 405 s.root.next = first.next 406 first.next.prev = &s.root 407 } 408 return &s.root 409 } 410 411 // Remove removes x from the set s, and reports whether the set shrank. 412 func (s *Sparse) Remove(x int) bool { 413 offset, i := offsetAndBitIndex(x) 414 if b := s.block(offset); b != nil { 415 if !b.remove(i) { 416 return false 417 } 418 if b.empty() { 419 s.removeBlock(b) 420 } 421 return true 422 } 423 return false 424 } 425 426 // Clear removes all elements from the set s. 427 func (s *Sparse) Clear() { 428 s.root = block{ 429 offset: MaxInt, 430 next: &s.root, 431 prev: &s.root, 432 } 433 } 434 435 // If set s is non-empty, TakeMin sets *p to the minimum element of 436 // the set s, removes that element from the set and returns true. 437 // Otherwise, it returns false and *p is undefined. 438 // 439 // This method may be used for iteration over a worklist like so: 440 // 441 // var x int 442 // for worklist.TakeMin(&x) { use(x) } 443 // 444 func (s *Sparse) TakeMin(p *int) bool { 445 if s.IsEmpty() { 446 return false 447 } 448 *p = s.root.min(true) 449 if s.root.empty() { 450 s.removeBlock(&s.root) 451 } 452 return true 453 } 454 455 // Has reports whether x is an element of the set s. 456 func (s *Sparse) Has(x int) bool { 457 offset, i := offsetAndBitIndex(x) 458 if b := s.block(offset); b != nil { 459 return b.has(i) 460 } 461 return false 462 } 463 464 // forEach applies function f to each element of the set s in order. 465 // 466 // f must not mutate s. Consequently, forEach is not safe to expose 467 // to clients. In any case, using "range s.AppendTo()" allows more 468 // natural control flow with continue/break/return. 469 // 470 func (s *Sparse) forEach(f func(int)) { 471 for b := s.first(); b != &none; b = s.next(b) { 472 b.forEach(f) 473 } 474 } 475 476 // Copy sets s to the value of x. 477 func (s *Sparse) Copy(x *Sparse) { 478 if s == x { 479 return 480 } 481 482 xb := x.first() 483 sb := s.first() 484 for xb != &none { 485 if sb == &none { 486 sb = s.insertBlockBefore(sb) 487 } 488 sb.offset = xb.offset 489 sb.bits = xb.bits 490 xb = x.next(xb) 491 sb = s.next(sb) 492 } 493 s.discardTail(sb) 494 } 495 496 // insertBlockBefore returns a new block, inserting it before next. 497 // If next is the root, the root is replaced. If next is end, the block is 498 // inserted at the end. 499 func (s *Sparse) insertBlockBefore(next *block) *block { 500 if s.IsEmpty() { 501 if next != &none { 502 panic("BUG: passed block with empty set") 503 } 504 return &s.root 505 } 506 507 if next == &s.root { 508 // Special case: we need to create a new block that will become the root 509 // block.The old root block becomes the second block. 510 second := s.root 511 s.root = block{ 512 next: &second, 513 } 514 if second.next == &s.root { 515 s.root.prev = &second 516 } else { 517 s.root.prev = second.prev 518 second.next.prev = &second 519 second.prev = &s.root 520 } 521 return &s.root 522 } 523 if next == &none { 524 // Insert before root. 525 next = &s.root 526 } 527 b := new(block) 528 b.next = next 529 b.prev = next.prev 530 b.prev.next = b 531 next.prev = b 532 return b 533 } 534 535 // discardTail removes block b and all its successors from s. 536 func (s *Sparse) discardTail(b *block) { 537 if b != &none { 538 if b == &s.root { 539 s.Clear() 540 } else { 541 b.prev.next = &s.root 542 s.root.prev = b.prev 543 } 544 } 545 } 546 547 // IntersectionWith sets s to the intersection s ∩ x. 548 func (s *Sparse) IntersectionWith(x *Sparse) { 549 if s == x { 550 return 551 } 552 553 xb := x.first() 554 sb := s.first() 555 for xb != &none && sb != &none { 556 switch { 557 case xb.offset < sb.offset: 558 xb = x.next(xb) 559 560 case xb.offset > sb.offset: 561 sb = s.removeBlock(sb) 562 563 default: 564 var sum word 565 for i := range sb.bits { 566 r := xb.bits[i] & sb.bits[i] 567 sb.bits[i] = r 568 sum |= r 569 } 570 if sum != 0 { 571 sb = s.next(sb) 572 } else { 573 // sb will be overwritten or removed 574 } 575 576 xb = x.next(xb) 577 } 578 } 579 580 s.discardTail(sb) 581 } 582 583 // Intersection sets s to the intersection x ∩ y. 584 func (s *Sparse) Intersection(x, y *Sparse) { 585 switch { 586 case s == x: 587 s.IntersectionWith(y) 588 return 589 case s == y: 590 s.IntersectionWith(x) 591 return 592 case x == y: 593 s.Copy(x) 594 return 595 } 596 597 xb := x.first() 598 yb := y.first() 599 sb := s.first() 600 for xb != &none && yb != &none { 601 switch { 602 case xb.offset < yb.offset: 603 xb = x.next(xb) 604 continue 605 case xb.offset > yb.offset: 606 yb = y.next(yb) 607 continue 608 } 609 610 if sb == &none { 611 sb = s.insertBlockBefore(sb) 612 } 613 sb.offset = xb.offset 614 615 var sum word 616 for i := range sb.bits { 617 r := xb.bits[i] & yb.bits[i] 618 sb.bits[i] = r 619 sum |= r 620 } 621 if sum != 0 { 622 sb = s.next(sb) 623 } else { 624 // sb will be overwritten or removed 625 } 626 627 xb = x.next(xb) 628 yb = y.next(yb) 629 } 630 631 s.discardTail(sb) 632 } 633 634 // Intersects reports whether s ∩ x ≠ ∅. 635 func (s *Sparse) Intersects(x *Sparse) bool { 636 sb := s.first() 637 xb := x.first() 638 for sb != &none && xb != &none { 639 switch { 640 case xb.offset < sb.offset: 641 xb = x.next(xb) 642 case xb.offset > sb.offset: 643 sb = s.next(sb) 644 default: 645 for i := range sb.bits { 646 if sb.bits[i]&xb.bits[i] != 0 { 647 return true 648 } 649 } 650 sb = s.next(sb) 651 xb = x.next(xb) 652 } 653 } 654 return false 655 } 656 657 // UnionWith sets s to the union s ∪ x, and reports whether s grew. 658 func (s *Sparse) UnionWith(x *Sparse) bool { 659 if s == x { 660 return false 661 } 662 663 var changed bool 664 xb := x.first() 665 sb := s.first() 666 for xb != &none { 667 if sb != &none && sb.offset == xb.offset { 668 for i := range xb.bits { 669 union := sb.bits[i] | xb.bits[i] 670 if sb.bits[i] != union { 671 sb.bits[i] = union 672 changed = true 673 } 674 } 675 xb = x.next(xb) 676 } else if sb == &none || sb.offset > xb.offset { 677 sb = s.insertBlockBefore(sb) 678 sb.offset = xb.offset 679 sb.bits = xb.bits 680 changed = true 681 682 xb = x.next(xb) 683 } 684 sb = s.next(sb) 685 } 686 return changed 687 } 688 689 // Union sets s to the union x ∪ y. 690 func (s *Sparse) Union(x, y *Sparse) { 691 switch { 692 case x == y: 693 s.Copy(x) 694 return 695 case s == x: 696 s.UnionWith(y) 697 return 698 case s == y: 699 s.UnionWith(x) 700 return 701 } 702 703 xb := x.first() 704 yb := y.first() 705 sb := s.first() 706 for xb != &none || yb != &none { 707 if sb == &none { 708 sb = s.insertBlockBefore(sb) 709 } 710 switch { 711 case yb == &none || (xb != &none && xb.offset < yb.offset): 712 sb.offset = xb.offset 713 sb.bits = xb.bits 714 xb = x.next(xb) 715 716 case xb == &none || (yb != &none && yb.offset < xb.offset): 717 sb.offset = yb.offset 718 sb.bits = yb.bits 719 yb = y.next(yb) 720 721 default: 722 sb.offset = xb.offset 723 for i := range xb.bits { 724 sb.bits[i] = xb.bits[i] | yb.bits[i] 725 } 726 xb = x.next(xb) 727 yb = y.next(yb) 728 } 729 sb = s.next(sb) 730 } 731 732 s.discardTail(sb) 733 } 734 735 // DifferenceWith sets s to the difference s ∖ x. 736 func (s *Sparse) DifferenceWith(x *Sparse) { 737 if s == x { 738 s.Clear() 739 return 740 } 741 742 xb := x.first() 743 sb := s.first() 744 for xb != &none && sb != &none { 745 switch { 746 case xb.offset > sb.offset: 747 sb = s.next(sb) 748 749 case xb.offset < sb.offset: 750 xb = x.next(xb) 751 752 default: 753 var sum word 754 for i := range sb.bits { 755 r := sb.bits[i] & ^xb.bits[i] 756 sb.bits[i] = r 757 sum |= r 758 } 759 if sum == 0 { 760 sb = s.removeBlock(sb) 761 } else { 762 sb = s.next(sb) 763 } 764 xb = x.next(xb) 765 } 766 } 767 } 768 769 // Difference sets s to the difference x ∖ y. 770 func (s *Sparse) Difference(x, y *Sparse) { 771 switch { 772 case x == y: 773 s.Clear() 774 return 775 case s == x: 776 s.DifferenceWith(y) 777 return 778 case s == y: 779 var y2 Sparse 780 y2.Copy(y) 781 s.Difference(x, &y2) 782 return 783 } 784 785 xb := x.first() 786 yb := y.first() 787 sb := s.first() 788 for xb != &none && yb != &none { 789 if xb.offset > yb.offset { 790 // y has block, x has &none 791 yb = y.next(yb) 792 continue 793 } 794 795 if sb == &none { 796 sb = s.insertBlockBefore(sb) 797 } 798 sb.offset = xb.offset 799 800 switch { 801 case xb.offset < yb.offset: 802 // x has block, y has &none 803 sb.bits = xb.bits 804 805 sb = s.next(sb) 806 807 default: 808 // x and y have corresponding blocks 809 var sum word 810 for i := range sb.bits { 811 r := xb.bits[i] & ^yb.bits[i] 812 sb.bits[i] = r 813 sum |= r 814 } 815 if sum != 0 { 816 sb = s.next(sb) 817 } else { 818 // sb will be overwritten or removed 819 } 820 821 yb = y.next(yb) 822 } 823 xb = x.next(xb) 824 } 825 826 for xb != &none { 827 if sb == &none { 828 sb = s.insertBlockBefore(sb) 829 } 830 sb.offset = xb.offset 831 sb.bits = xb.bits 832 sb = s.next(sb) 833 834 xb = x.next(xb) 835 } 836 837 s.discardTail(sb) 838 } 839 840 // SymmetricDifferenceWith sets s to the symmetric difference s ∆ x. 841 func (s *Sparse) SymmetricDifferenceWith(x *Sparse) { 842 if s == x { 843 s.Clear() 844 return 845 } 846 847 sb := s.first() 848 xb := x.first() 849 for xb != &none && sb != &none { 850 switch { 851 case sb.offset < xb.offset: 852 sb = s.next(sb) 853 case xb.offset < sb.offset: 854 nb := s.insertBlockBefore(sb) 855 nb.offset = xb.offset 856 nb.bits = xb.bits 857 xb = x.next(xb) 858 default: 859 var sum word 860 for i := range sb.bits { 861 r := sb.bits[i] ^ xb.bits[i] 862 sb.bits[i] = r 863 sum |= r 864 } 865 if sum == 0 { 866 sb = s.removeBlock(sb) 867 } else { 868 sb = s.next(sb) 869 } 870 xb = x.next(xb) 871 } 872 } 873 874 for xb != &none { // append the tail of x to s 875 sb = s.insertBlockBefore(sb) 876 sb.offset = xb.offset 877 sb.bits = xb.bits 878 sb = s.next(sb) 879 xb = x.next(xb) 880 } 881 } 882 883 // SymmetricDifference sets s to the symmetric difference x ∆ y. 884 func (s *Sparse) SymmetricDifference(x, y *Sparse) { 885 switch { 886 case x == y: 887 s.Clear() 888 return 889 case s == x: 890 s.SymmetricDifferenceWith(y) 891 return 892 case s == y: 893 s.SymmetricDifferenceWith(x) 894 return 895 } 896 897 sb := s.first() 898 xb := x.first() 899 yb := y.first() 900 for xb != &none && yb != &none { 901 if sb == &none { 902 sb = s.insertBlockBefore(sb) 903 } 904 switch { 905 case yb.offset < xb.offset: 906 sb.offset = yb.offset 907 sb.bits = yb.bits 908 sb = s.next(sb) 909 yb = y.next(yb) 910 case xb.offset < yb.offset: 911 sb.offset = xb.offset 912 sb.bits = xb.bits 913 sb = s.next(sb) 914 xb = x.next(xb) 915 default: 916 var sum word 917 for i := range sb.bits { 918 r := xb.bits[i] ^ yb.bits[i] 919 sb.bits[i] = r 920 sum |= r 921 } 922 if sum != 0 { 923 sb.offset = xb.offset 924 sb = s.next(sb) 925 } 926 xb = x.next(xb) 927 yb = y.next(yb) 928 } 929 } 930 931 for xb != &none { // append the tail of x to s 932 if sb == &none { 933 sb = s.insertBlockBefore(sb) 934 } 935 sb.offset = xb.offset 936 sb.bits = xb.bits 937 sb = s.next(sb) 938 xb = x.next(xb) 939 } 940 941 for yb != &none { // append the tail of y to s 942 if sb == &none { 943 sb = s.insertBlockBefore(sb) 944 } 945 sb.offset = yb.offset 946 sb.bits = yb.bits 947 sb = s.next(sb) 948 yb = y.next(yb) 949 } 950 951 s.discardTail(sb) 952 } 953 954 // SubsetOf reports whether s ∖ x = ∅. 955 func (s *Sparse) SubsetOf(x *Sparse) bool { 956 if s == x { 957 return true 958 } 959 960 sb := s.first() 961 xb := x.first() 962 for sb != &none { 963 switch { 964 case xb == &none || xb.offset > sb.offset: 965 return false 966 case xb.offset < sb.offset: 967 xb = x.next(xb) 968 default: 969 for i := range sb.bits { 970 if sb.bits[i]&^xb.bits[i] != 0 { 971 return false 972 } 973 } 974 sb = s.next(sb) 975 xb = x.next(xb) 976 } 977 } 978 return true 979 } 980 981 // Equals reports whether the sets s and t have the same elements. 982 func (s *Sparse) Equals(t *Sparse) bool { 983 if s == t { 984 return true 985 } 986 sb := s.first() 987 tb := t.first() 988 for { 989 switch { 990 case sb == &none && tb == &none: 991 return true 992 case sb == &none || tb == &none: 993 return false 994 case sb.offset != tb.offset: 995 return false 996 case sb.bits != tb.bits: 997 return false 998 } 999 1000 sb = s.next(sb) 1001 tb = t.next(tb) 1002 } 1003 } 1004 1005 // String returns a human-readable description of the set s. 1006 func (s *Sparse) String() string { 1007 var buf bytes.Buffer 1008 buf.WriteByte('{') 1009 s.forEach(func(x int) { 1010 if buf.Len() > 1 { 1011 buf.WriteByte(' ') 1012 } 1013 fmt.Fprintf(&buf, "%d", x) 1014 }) 1015 buf.WriteByte('}') 1016 return buf.String() 1017 } 1018 1019 // BitString returns the set as a string of 1s and 0s denoting the sum 1020 // of the i'th powers of 2, for each i in s. A radix point, always 1021 // preceded by a digit, appears if the sum is non-integral. 1022 // 1023 // Examples: 1024 // {}.BitString() = "0" 1025 // {4,5}.BitString() = "110000" 1026 // {-3}.BitString() = "0.001" 1027 // {-3,0,4,5}.BitString() = "110001.001" 1028 // 1029 func (s *Sparse) BitString() string { 1030 if s.IsEmpty() { 1031 return "0" 1032 } 1033 1034 min, max := s.Min(), s.Max() 1035 var nbytes int 1036 if max > 0 { 1037 nbytes = max 1038 } 1039 nbytes++ // zero bit 1040 radix := nbytes 1041 if min < 0 { 1042 nbytes += len(".") - min 1043 } 1044 1045 b := make([]byte, nbytes) 1046 for i := range b { 1047 b[i] = '0' 1048 } 1049 if radix < nbytes { 1050 b[radix] = '.' 1051 } 1052 s.forEach(func(x int) { 1053 if x >= 0 { 1054 x += len(".") 1055 } 1056 b[radix-x] = '1' 1057 }) 1058 return string(b) 1059 } 1060 1061 // GoString returns a string showing the internal representation of 1062 // the set s. 1063 // 1064 func (s *Sparse) GoString() string { 1065 var buf bytes.Buffer 1066 for b := s.first(); b != &none; b = s.next(b) { 1067 fmt.Fprintf(&buf, "block %p {offset=%d next=%p prev=%p", 1068 b, b.offset, b.next, b.prev) 1069 for _, w := range b.bits { 1070 fmt.Fprintf(&buf, " 0%016x", w) 1071 } 1072 fmt.Fprintf(&buf, "}\n") 1073 } 1074 return buf.String() 1075 } 1076 1077 // AppendTo returns the result of appending the elements of s to slice 1078 // in order. 1079 func (s *Sparse) AppendTo(slice []int) []int { 1080 s.forEach(func(x int) { 1081 slice = append(slice, x) 1082 }) 1083 return slice 1084 } 1085 1086 // -- Testing/debugging ------------------------------------------------ 1087 1088 // check returns an error if the representation invariants of s are violated. 1089 func (s *Sparse) check() error { 1090 s.init() 1091 if s.root.empty() { 1092 // An empty set must have only the root block with offset MaxInt. 1093 if s.root.next != &s.root { 1094 return fmt.Errorf("multiple blocks with empty root block") 1095 } 1096 if s.root.offset != MaxInt { 1097 return fmt.Errorf("empty set has offset %d, should be MaxInt", s.root.offset) 1098 } 1099 return nil 1100 } 1101 for b := s.first(); ; b = s.next(b) { 1102 if b.offset%bitsPerBlock != 0 { 1103 return fmt.Errorf("bad offset modulo: %d", b.offset) 1104 } 1105 if b.empty() { 1106 return fmt.Errorf("empty block") 1107 } 1108 if b.prev.next != b { 1109 return fmt.Errorf("bad prev.next link") 1110 } 1111 if b.next.prev != b { 1112 return fmt.Errorf("bad next.prev link") 1113 } 1114 if b.next == &s.root { 1115 break 1116 } 1117 if b.offset >= b.next.offset { 1118 return fmt.Errorf("bad offset order: b.offset=%d, b.next.offset=%d", 1119 b.offset, b.next.offset) 1120 } 1121 } 1122 return nil 1123 }