GoPLS Viewer

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