1092 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			1092 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			Go
		
	
	
	
| // Copyright 2014 The Go Authors. All rights reserved.
 | ||
| // Use of this source code is governed by a BSD-style
 | ||
| // license that can be found in the LICENSE file.
 | ||
| 
 | ||
| // Package intsets provides Sparse, a compact and fast representation
 | ||
| // for sparse sets of int values.
 | ||
| //
 | ||
| // The time complexity of the operations Len, Insert, Remove and Has
 | ||
| // is in O(n) but in practice those methods are faster and more
 | ||
| // space-efficient than equivalent operations on sets based on the Go
 | ||
| // map type.  The IsEmpty, Min, Max, Clear and TakeMin operations
 | ||
| // require constant time.
 | ||
| //
 | ||
| package intsets // import "golang.org/x/tools/container/intsets"
 | ||
| 
 | ||
| // TODO(adonovan):
 | ||
| // - Add InsertAll(...int), RemoveAll(...int)
 | ||
| // - Add 'bool changed' results for {Intersection,Difference}With too.
 | ||
| //
 | ||
| // TODO(adonovan): implement Dense, a dense bit vector with a similar API.
 | ||
| // The space usage would be proportional to Max(), not Len(), and the
 | ||
| // implementation would be based upon big.Int.
 | ||
| //
 | ||
| // TODO(adonovan): opt: make UnionWith and Difference faster.
 | ||
| // These are the hot-spots for go/pointer.
 | ||
| 
 | ||
| import (
 | ||
| 	"bytes"
 | ||
| 	"fmt"
 | ||
| )
 | ||
| 
 | ||
| // A Sparse is a set of int values.
 | ||
| // Sparse operations (even queries) are not concurrency-safe.
 | ||
| //
 | ||
| // The zero value for Sparse is a valid empty set.
 | ||
| //
 | ||
| // Sparse sets must be copied using the Copy method, not by assigning
 | ||
| // a Sparse value.
 | ||
| //
 | ||
| type Sparse struct {
 | ||
| 	// An uninitialized Sparse represents an empty set.
 | ||
| 	// An empty set may also be represented by
 | ||
| 	//  root.next == root.prev == &root.
 | ||
| 	//
 | ||
| 	// The root is always the block with the smallest offset.
 | ||
| 	// It can be empty, but only if it is the only block; in that case, offset is
 | ||
| 	// MaxInt (which is not a valid offset).
 | ||
| 	root block
 | ||
| }
 | ||
| 
 | ||
| type word uintptr
 | ||
| 
 | ||
| const (
 | ||
| 	_m            = ^word(0)
 | ||
| 	bitsPerWord   = 8 << (_m>>8&1 + _m>>16&1 + _m>>32&1)
 | ||
| 	bitsPerBlock  = 256 // optimal value for go/pointer solver performance
 | ||
| 	wordsPerBlock = bitsPerBlock / bitsPerWord
 | ||
| )
 | ||
| 
 | ||
| // Limit values of implementation-specific int type.
 | ||
| const (
 | ||
| 	MaxInt = int(^uint(0) >> 1)
 | ||
| 	MinInt = -MaxInt - 1
 | ||
| )
 | ||
| 
 | ||
| // -- block ------------------------------------------------------------
 | ||
| 
 | ||
| // A set is represented as a circular doubly-linked list of blocks,
 | ||
| // each containing an offset and a bit array of fixed size
 | ||
| // bitsPerBlock; the blocks are ordered by increasing offset.
 | ||
| //
 | ||
| // The set contains an element x iff the block whose offset is x - (x
 | ||
| // mod bitsPerBlock) has the bit (x mod bitsPerBlock) set, where mod
 | ||
| // is the Euclidean remainder.
 | ||
| //
 | ||
| // A block may only be empty transiently.
 | ||
| //
 | ||
| type block struct {
 | ||
| 	offset     int                 // offset mod bitsPerBlock == 0
 | ||
| 	bits       [wordsPerBlock]word // contains at least one set bit
 | ||
| 	next, prev *block              // doubly-linked list of blocks
 | ||
| }
 | ||
| 
 | ||
| // wordMask returns the word index (in block.bits)
 | ||
| // and single-bit mask for the block's ith bit.
 | ||
| func wordMask(i uint) (w uint, mask word) {
 | ||
| 	w = i / bitsPerWord
 | ||
| 	mask = 1 << (i % bitsPerWord)
 | ||
| 	return
 | ||
| }
 | ||
| 
 | ||
| // insert sets the block b's ith bit and
 | ||
| // returns true if it was not already set.
 | ||
| //
 | ||
| func (b *block) insert(i uint) bool {
 | ||
| 	w, mask := wordMask(i)
 | ||
| 	if b.bits[w]&mask == 0 {
 | ||
| 		b.bits[w] |= mask
 | ||
| 		return true
 | ||
| 	}
 | ||
| 	return false
 | ||
| }
 | ||
| 
 | ||
| // remove clears the block's ith bit and
 | ||
| // returns true if the bit was previously set.
 | ||
| // NB: may leave the block empty.
 | ||
| //
 | ||
| func (b *block) remove(i uint) bool {
 | ||
| 	w, mask := wordMask(i)
 | ||
| 	if b.bits[w]&mask != 0 {
 | ||
| 		b.bits[w] &^= mask
 | ||
| 		return true
 | ||
| 	}
 | ||
| 	return false
 | ||
| }
 | ||
| 
 | ||
| // has reports whether the block's ith bit is set.
 | ||
| func (b *block) has(i uint) bool {
 | ||
| 	w, mask := wordMask(i)
 | ||
| 	return b.bits[w]&mask != 0
 | ||
| }
 | ||
| 
 | ||
| // empty reports whether b.len()==0, but more efficiently.
 | ||
| func (b *block) empty() bool {
 | ||
| 	for _, w := range b.bits {
 | ||
| 		if w != 0 {
 | ||
| 			return false
 | ||
| 		}
 | ||
| 	}
 | ||
| 	return true
 | ||
| }
 | ||
| 
 | ||
| // len returns the number of set bits in block b.
 | ||
| func (b *block) len() int {
 | ||
| 	var l int
 | ||
| 	for _, w := range b.bits {
 | ||
| 		l += popcount(w)
 | ||
| 	}
 | ||
| 	return l
 | ||
| }
 | ||
| 
 | ||
| // max returns the maximum element of the block.
 | ||
| // The block must not be empty.
 | ||
| func (b *block) max() int {
 | ||
| 	bi := b.offset + bitsPerBlock
 | ||
| 	// Decrement bi by number of high zeros in last.bits.
 | ||
| 	for i := len(b.bits) - 1; i >= 0; i-- {
 | ||
| 		if w := b.bits[i]; w != 0 {
 | ||
| 			return bi - nlz(w) - 1
 | ||
| 		}
 | ||
| 		bi -= bitsPerWord
 | ||
| 	}
 | ||
| 	panic("BUG: empty block")
 | ||
| }
 | ||
| 
 | ||
| // min returns the minimum element of the block,
 | ||
| // and also removes it if take is set.
 | ||
| // The block must not be initially empty.
 | ||
| // NB: may leave the block empty.
 | ||
| func (b *block) min(take bool) int {
 | ||
| 	for i, w := range b.bits {
 | ||
| 		if w != 0 {
 | ||
| 			tz := ntz(w)
 | ||
| 			if take {
 | ||
| 				b.bits[i] = w &^ (1 << uint(tz))
 | ||
| 			}
 | ||
| 			return b.offset + int(i*bitsPerWord) + tz
 | ||
| 		}
 | ||
| 	}
 | ||
| 	panic("BUG: empty block")
 | ||
| }
 | ||
| 
 | ||
| // lowerBound returns the smallest element of the block that is greater than or
 | ||
| // equal to the element corresponding to the ith bit. If there is no such
 | ||
| // element, the second return value is false.
 | ||
| func (b *block) lowerBound(i uint) (int, bool) {
 | ||
| 	w := i / bitsPerWord
 | ||
| 	bit := i % bitsPerWord
 | ||
| 
 | ||
| 	if val := b.bits[w] >> bit; val != 0 {
 | ||
| 		return b.offset + int(i) + ntz(val), true
 | ||
| 	}
 | ||
| 
 | ||
| 	for w++; w < wordsPerBlock; w++ {
 | ||
| 		if val := b.bits[w]; val != 0 {
 | ||
| 			return b.offset + int(w*bitsPerWord) + ntz(val), true
 | ||
| 		}
 | ||
| 	}
 | ||
| 
 | ||
| 	return 0, false
 | ||
| }
 | ||
| 
 | ||
| // forEach calls f for each element of block b.
 | ||
| // f must not mutate b's enclosing Sparse.
 | ||
| func (b *block) forEach(f func(int)) {
 | ||
| 	for i, w := range b.bits {
 | ||
| 		offset := b.offset + i*bitsPerWord
 | ||
| 		for bi := 0; w != 0 && bi < bitsPerWord; bi++ {
 | ||
| 			if w&1 != 0 {
 | ||
| 				f(offset)
 | ||
| 			}
 | ||
| 			offset++
 | ||
| 			w >>= 1
 | ||
| 		}
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| // offsetAndBitIndex returns the offset of the block that would
 | ||
| // contain x and the bit index of x within that block.
 | ||
| //
 | ||
| func offsetAndBitIndex(x int) (int, uint) {
 | ||
| 	mod := x % bitsPerBlock
 | ||
| 	if mod < 0 {
 | ||
| 		// Euclidean (non-negative) remainder
 | ||
| 		mod += bitsPerBlock
 | ||
| 	}
 | ||
| 	return x - mod, uint(mod)
 | ||
| }
 | ||
| 
 | ||
| // -- Sparse --------------------------------------------------------------
 | ||
| 
 | ||
| // none is a shared, empty, sentinel block that indicates the end of a block
 | ||
| // list.
 | ||
| var none block
 | ||
| 
 | ||
| // Dummy type used to generate an implicit panic. This must be defined at the
 | ||
| // package level; if it is defined inside a function, it prevents the inlining
 | ||
| // of that function.
 | ||
| type to_copy_a_sparse_you_must_call_its_Copy_method struct{}
 | ||
| 
 | ||
| // init ensures s is properly initialized.
 | ||
| func (s *Sparse) init() {
 | ||
| 	root := &s.root
 | ||
| 	if root.next == nil {
 | ||
| 		root.offset = MaxInt
 | ||
| 		root.next = root
 | ||
| 		root.prev = root
 | ||
| 	} else if root.next.prev != root {
 | ||
| 		// Copying a Sparse x leads to pernicious corruption: the
 | ||
| 		// new Sparse y shares the old linked list, but iteration
 | ||
| 		// on y will never encounter &y.root so it goes into a
 | ||
| 		// loop.  Fail fast before this occurs.
 | ||
| 		// We don't want to call panic here because it prevents the
 | ||
| 		// inlining of this function.
 | ||
| 		_ = (interface{}(nil)).(to_copy_a_sparse_you_must_call_its_Copy_method)
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| func (s *Sparse) first() *block {
 | ||
| 	s.init()
 | ||
| 	if s.root.offset == MaxInt {
 | ||
| 		return &none
 | ||
| 	}
 | ||
| 	return &s.root
 | ||
| }
 | ||
| 
 | ||
| // next returns the next block in the list, or end if b is the last block.
 | ||
| func (s *Sparse) next(b *block) *block {
 | ||
| 	if b.next == &s.root {
 | ||
| 		return &none
 | ||
| 	}
 | ||
| 	return b.next
 | ||
| }
 | ||
| 
 | ||
| // prev returns the previous block in the list, or end if b is the first block.
 | ||
| func (s *Sparse) prev(b *block) *block {
 | ||
| 	if b.prev == &s.root {
 | ||
| 		return &none
 | ||
| 	}
 | ||
| 	return b.prev
 | ||
| }
 | ||
| 
 | ||
| // IsEmpty reports whether the set s is empty.
 | ||
| func (s *Sparse) IsEmpty() bool {
 | ||
| 	return s.root.next == nil || s.root.offset == MaxInt
 | ||
| }
 | ||
| 
 | ||
| // Len returns the number of elements in the set s.
 | ||
| func (s *Sparse) Len() int {
 | ||
| 	var l int
 | ||
| 	for b := s.first(); b != &none; b = s.next(b) {
 | ||
| 		l += b.len()
 | ||
| 	}
 | ||
| 	return l
 | ||
| }
 | ||
| 
 | ||
| // Max returns the maximum element of the set s, or MinInt if s is empty.
 | ||
| func (s *Sparse) Max() int {
 | ||
| 	if s.IsEmpty() {
 | ||
| 		return MinInt
 | ||
| 	}
 | ||
| 	return s.root.prev.max()
 | ||
| }
 | ||
| 
 | ||
| // Min returns the minimum element of the set s, or MaxInt if s is empty.
 | ||
| func (s *Sparse) Min() int {
 | ||
| 	if s.IsEmpty() {
 | ||
| 		return MaxInt
 | ||
| 	}
 | ||
| 	return s.root.min(false)
 | ||
| }
 | ||
| 
 | ||
| // LowerBound returns the smallest element >= x, or MaxInt if there is no such
 | ||
| // element.
 | ||
| func (s *Sparse) LowerBound(x int) int {
 | ||
| 	offset, i := offsetAndBitIndex(x)
 | ||
| 	for b := s.first(); b != &none; b = s.next(b) {
 | ||
| 		if b.offset > offset {
 | ||
| 			return b.min(false)
 | ||
| 		}
 | ||
| 		if b.offset == offset {
 | ||
| 			if y, ok := b.lowerBound(i); ok {
 | ||
| 				return y
 | ||
| 			}
 | ||
| 		}
 | ||
| 	}
 | ||
| 	return MaxInt
 | ||
| }
 | ||
| 
 | ||
| // block returns the block that would contain offset,
 | ||
| // or nil if s contains no such block.
 | ||
| // Precondition: offset is a multiple of bitsPerBlock.
 | ||
| func (s *Sparse) block(offset int) *block {
 | ||
| 	for b := s.first(); b != &none && b.offset <= offset; b = s.next(b) {
 | ||
| 		if b.offset == offset {
 | ||
| 			return b
 | ||
| 		}
 | ||
| 	}
 | ||
| 	return nil
 | ||
| }
 | ||
| 
 | ||
| // Insert adds x to the set s, and reports whether the set grew.
 | ||
| func (s *Sparse) Insert(x int) bool {
 | ||
| 	offset, i := offsetAndBitIndex(x)
 | ||
| 
 | ||
| 	b := s.first()
 | ||
| 	for ; b != &none && b.offset <= offset; b = s.next(b) {
 | ||
| 		if b.offset == offset {
 | ||
| 			return b.insert(i)
 | ||
| 		}
 | ||
| 	}
 | ||
| 
 | ||
| 	// Insert new block before b.
 | ||
| 	new := s.insertBlockBefore(b)
 | ||
| 	new.offset = offset
 | ||
| 	return new.insert(i)
 | ||
| }
 | ||
| 
 | ||
| // removeBlock removes a block and returns the block that followed it (or end if
 | ||
| // it was the last block).
 | ||
| func (s *Sparse) removeBlock(b *block) *block {
 | ||
| 	if b != &s.root {
 | ||
| 		b.prev.next = b.next
 | ||
| 		b.next.prev = b.prev
 | ||
| 		if b.next == &s.root {
 | ||
| 			return &none
 | ||
| 		}
 | ||
| 		return b.next
 | ||
| 	}
 | ||
| 
 | ||
| 	first := s.root.next
 | ||
| 	if first == &s.root {
 | ||
| 		// This was the only block.
 | ||
| 		s.Clear()
 | ||
| 		return &none
 | ||
| 	}
 | ||
| 	s.root.offset = first.offset
 | ||
| 	s.root.bits = first.bits
 | ||
| 	if first.next == &s.root {
 | ||
| 		// Single block remaining.
 | ||
| 		s.root.next = &s.root
 | ||
| 		s.root.prev = &s.root
 | ||
| 	} else {
 | ||
| 		s.root.next = first.next
 | ||
| 		first.next.prev = &s.root
 | ||
| 	}
 | ||
| 	return &s.root
 | ||
| }
 | ||
| 
 | ||
| // Remove removes x from the set s, and reports whether the set shrank.
 | ||
| func (s *Sparse) Remove(x int) bool {
 | ||
| 	offset, i := offsetAndBitIndex(x)
 | ||
| 	if b := s.block(offset); b != nil {
 | ||
| 		if !b.remove(i) {
 | ||
| 			return false
 | ||
| 		}
 | ||
| 		if b.empty() {
 | ||
| 			s.removeBlock(b)
 | ||
| 		}
 | ||
| 		return true
 | ||
| 	}
 | ||
| 	return false
 | ||
| }
 | ||
| 
 | ||
| // Clear removes all elements from the set s.
 | ||
| func (s *Sparse) Clear() {
 | ||
| 	s.root = block{
 | ||
| 		offset: MaxInt,
 | ||
| 		next:   &s.root,
 | ||
| 		prev:   &s.root,
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| // If set s is non-empty, TakeMin sets *p to the minimum element of
 | ||
| // the set s, removes that element from the set and returns true.
 | ||
| // Otherwise, it returns false and *p is undefined.
 | ||
| //
 | ||
| // This method may be used for iteration over a worklist like so:
 | ||
| //
 | ||
| // 	var x int
 | ||
| // 	for worklist.TakeMin(&x) { use(x) }
 | ||
| //
 | ||
| func (s *Sparse) TakeMin(p *int) bool {
 | ||
| 	if s.IsEmpty() {
 | ||
| 		return false
 | ||
| 	}
 | ||
| 	*p = s.root.min(true)
 | ||
| 	if s.root.empty() {
 | ||
| 		s.removeBlock(&s.root)
 | ||
| 	}
 | ||
| 	return true
 | ||
| }
 | ||
| 
 | ||
| // Has reports whether x is an element of the set s.
 | ||
| func (s *Sparse) Has(x int) bool {
 | ||
| 	offset, i := offsetAndBitIndex(x)
 | ||
| 	if b := s.block(offset); b != nil {
 | ||
| 		return b.has(i)
 | ||
| 	}
 | ||
| 	return false
 | ||
| }
 | ||
| 
 | ||
| // forEach applies function f to each element of the set s in order.
 | ||
| //
 | ||
| // f must not mutate s.  Consequently, forEach is not safe to expose
 | ||
| // to clients.  In any case, using "range s.AppendTo()" allows more
 | ||
| // natural control flow with continue/break/return.
 | ||
| //
 | ||
| func (s *Sparse) forEach(f func(int)) {
 | ||
| 	for b := s.first(); b != &none; b = s.next(b) {
 | ||
| 		b.forEach(f)
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| // Copy sets s to the value of x.
 | ||
| func (s *Sparse) Copy(x *Sparse) {
 | ||
| 	if s == x {
 | ||
| 		return
 | ||
| 	}
 | ||
| 
 | ||
| 	xb := x.first()
 | ||
| 	sb := s.first()
 | ||
| 	for xb != &none {
 | ||
| 		if sb == &none {
 | ||
| 			sb = s.insertBlockBefore(sb)
 | ||
| 		}
 | ||
| 		sb.offset = xb.offset
 | ||
| 		sb.bits = xb.bits
 | ||
| 		xb = x.next(xb)
 | ||
| 		sb = s.next(sb)
 | ||
| 	}
 | ||
| 	s.discardTail(sb)
 | ||
| }
 | ||
| 
 | ||
| // insertBlockBefore returns a new block, inserting it before next.
 | ||
| // If next is the root, the root is replaced. If next is end, the block is
 | ||
| // inserted at the end.
 | ||
| func (s *Sparse) insertBlockBefore(next *block) *block {
 | ||
| 	if s.IsEmpty() {
 | ||
| 		if next != &none {
 | ||
| 			panic("BUG: passed block with empty set")
 | ||
| 		}
 | ||
| 		return &s.root
 | ||
| 	}
 | ||
| 
 | ||
| 	if next == &s.root {
 | ||
| 		// Special case: we need to create a new block that will become the root
 | ||
| 		// block.The old root block becomes the second block.
 | ||
| 		second := s.root
 | ||
| 		s.root = block{
 | ||
| 			next: &second,
 | ||
| 		}
 | ||
| 		if second.next == &s.root {
 | ||
| 			s.root.prev = &second
 | ||
| 		} else {
 | ||
| 			s.root.prev = second.prev
 | ||
| 			second.next.prev = &second
 | ||
| 			second.prev = &s.root
 | ||
| 		}
 | ||
| 		return &s.root
 | ||
| 	}
 | ||
| 	if next == &none {
 | ||
| 		// Insert before root.
 | ||
| 		next = &s.root
 | ||
| 	}
 | ||
| 	b := new(block)
 | ||
| 	b.next = next
 | ||
| 	b.prev = next.prev
 | ||
| 	b.prev.next = b
 | ||
| 	next.prev = b
 | ||
| 	return b
 | ||
| }
 | ||
| 
 | ||
| // discardTail removes block b and all its successors from s.
 | ||
| func (s *Sparse) discardTail(b *block) {
 | ||
| 	if b != &none {
 | ||
| 		if b == &s.root {
 | ||
| 			s.Clear()
 | ||
| 		} else {
 | ||
| 			b.prev.next = &s.root
 | ||
| 			s.root.prev = b.prev
 | ||
| 		}
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| // IntersectionWith sets s to the intersection s ∩ x.
 | ||
| func (s *Sparse) IntersectionWith(x *Sparse) {
 | ||
| 	if s == x {
 | ||
| 		return
 | ||
| 	}
 | ||
| 
 | ||
| 	xb := x.first()
 | ||
| 	sb := s.first()
 | ||
| 	for xb != &none && sb != &none {
 | ||
| 		switch {
 | ||
| 		case xb.offset < sb.offset:
 | ||
| 			xb = x.next(xb)
 | ||
| 
 | ||
| 		case xb.offset > sb.offset:
 | ||
| 			sb = s.removeBlock(sb)
 | ||
| 
 | ||
| 		default:
 | ||
| 			var sum word
 | ||
| 			for i := range sb.bits {
 | ||
| 				r := xb.bits[i] & sb.bits[i]
 | ||
| 				sb.bits[i] = r
 | ||
| 				sum |= r
 | ||
| 			}
 | ||
| 			if sum != 0 {
 | ||
| 				sb = s.next(sb)
 | ||
| 			} else {
 | ||
| 				// sb will be overwritten or removed
 | ||
| 			}
 | ||
| 
 | ||
| 			xb = x.next(xb)
 | ||
| 		}
 | ||
| 	}
 | ||
| 
 | ||
| 	s.discardTail(sb)
 | ||
| }
 | ||
| 
 | ||
| // Intersection sets s to the intersection x ∩ y.
 | ||
| func (s *Sparse) Intersection(x, y *Sparse) {
 | ||
| 	switch {
 | ||
| 	case s == x:
 | ||
| 		s.IntersectionWith(y)
 | ||
| 		return
 | ||
| 	case s == y:
 | ||
| 		s.IntersectionWith(x)
 | ||
| 		return
 | ||
| 	case x == y:
 | ||
| 		s.Copy(x)
 | ||
| 		return
 | ||
| 	}
 | ||
| 
 | ||
| 	xb := x.first()
 | ||
| 	yb := y.first()
 | ||
| 	sb := s.first()
 | ||
| 	for xb != &none && yb != &none {
 | ||
| 		switch {
 | ||
| 		case xb.offset < yb.offset:
 | ||
| 			xb = x.next(xb)
 | ||
| 			continue
 | ||
| 		case xb.offset > yb.offset:
 | ||
| 			yb = y.next(yb)
 | ||
| 			continue
 | ||
| 		}
 | ||
| 
 | ||
| 		if sb == &none {
 | ||
| 			sb = s.insertBlockBefore(sb)
 | ||
| 		}
 | ||
| 		sb.offset = xb.offset
 | ||
| 
 | ||
| 		var sum word
 | ||
| 		for i := range sb.bits {
 | ||
| 			r := xb.bits[i] & yb.bits[i]
 | ||
| 			sb.bits[i] = r
 | ||
| 			sum |= r
 | ||
| 		}
 | ||
| 		if sum != 0 {
 | ||
| 			sb = s.next(sb)
 | ||
| 		} else {
 | ||
| 			// sb will be overwritten or removed
 | ||
| 		}
 | ||
| 
 | ||
| 		xb = x.next(xb)
 | ||
| 		yb = y.next(yb)
 | ||
| 	}
 | ||
| 
 | ||
| 	s.discardTail(sb)
 | ||
| }
 | ||
| 
 | ||
| // Intersects reports whether s ∩ x ≠ ∅.
 | ||
| func (s *Sparse) Intersects(x *Sparse) bool {
 | ||
| 	sb := s.first()
 | ||
| 	xb := x.first()
 | ||
| 	for sb != &none && xb != &none {
 | ||
| 		switch {
 | ||
| 		case xb.offset < sb.offset:
 | ||
| 			xb = x.next(xb)
 | ||
| 		case xb.offset > sb.offset:
 | ||
| 			sb = s.next(sb)
 | ||
| 		default:
 | ||
| 			for i := range sb.bits {
 | ||
| 				if sb.bits[i]&xb.bits[i] != 0 {
 | ||
| 					return true
 | ||
| 				}
 | ||
| 			}
 | ||
| 			sb = s.next(sb)
 | ||
| 			xb = x.next(xb)
 | ||
| 		}
 | ||
| 	}
 | ||
| 	return false
 | ||
| }
 | ||
| 
 | ||
| // UnionWith sets s to the union s ∪ x, and reports whether s grew.
 | ||
| func (s *Sparse) UnionWith(x *Sparse) bool {
 | ||
| 	if s == x {
 | ||
| 		return false
 | ||
| 	}
 | ||
| 
 | ||
| 	var changed bool
 | ||
| 	xb := x.first()
 | ||
| 	sb := s.first()
 | ||
| 	for xb != &none {
 | ||
| 		if sb != &none && sb.offset == xb.offset {
 | ||
| 			for i := range xb.bits {
 | ||
| 				if sb.bits[i] != xb.bits[i] {
 | ||
| 					sb.bits[i] |= xb.bits[i]
 | ||
| 					changed = true
 | ||
| 				}
 | ||
| 			}
 | ||
| 			xb = x.next(xb)
 | ||
| 		} else if sb == &none || sb.offset > xb.offset {
 | ||
| 			sb = s.insertBlockBefore(sb)
 | ||
| 			sb.offset = xb.offset
 | ||
| 			sb.bits = xb.bits
 | ||
| 			changed = true
 | ||
| 
 | ||
| 			xb = x.next(xb)
 | ||
| 		}
 | ||
| 		sb = s.next(sb)
 | ||
| 	}
 | ||
| 	return changed
 | ||
| }
 | ||
| 
 | ||
| // Union sets s to the union x ∪ y.
 | ||
| func (s *Sparse) Union(x, y *Sparse) {
 | ||
| 	switch {
 | ||
| 	case x == y:
 | ||
| 		s.Copy(x)
 | ||
| 		return
 | ||
| 	case s == x:
 | ||
| 		s.UnionWith(y)
 | ||
| 		return
 | ||
| 	case s == y:
 | ||
| 		s.UnionWith(x)
 | ||
| 		return
 | ||
| 	}
 | ||
| 
 | ||
| 	xb := x.first()
 | ||
| 	yb := y.first()
 | ||
| 	sb := s.first()
 | ||
| 	for xb != &none || yb != &none {
 | ||
| 		if sb == &none {
 | ||
| 			sb = s.insertBlockBefore(sb)
 | ||
| 		}
 | ||
| 		switch {
 | ||
| 		case yb == &none || (xb != &none && xb.offset < yb.offset):
 | ||
| 			sb.offset = xb.offset
 | ||
| 			sb.bits = xb.bits
 | ||
| 			xb = x.next(xb)
 | ||
| 
 | ||
| 		case xb == &none || (yb != &none && yb.offset < xb.offset):
 | ||
| 			sb.offset = yb.offset
 | ||
| 			sb.bits = yb.bits
 | ||
| 			yb = y.next(yb)
 | ||
| 
 | ||
| 		default:
 | ||
| 			sb.offset = xb.offset
 | ||
| 			for i := range xb.bits {
 | ||
| 				sb.bits[i] = xb.bits[i] | yb.bits[i]
 | ||
| 			}
 | ||
| 			xb = x.next(xb)
 | ||
| 			yb = y.next(yb)
 | ||
| 		}
 | ||
| 		sb = s.next(sb)
 | ||
| 	}
 | ||
| 
 | ||
| 	s.discardTail(sb)
 | ||
| }
 | ||
| 
 | ||
| // DifferenceWith sets s to the difference s ∖ x.
 | ||
| func (s *Sparse) DifferenceWith(x *Sparse) {
 | ||
| 	if s == x {
 | ||
| 		s.Clear()
 | ||
| 		return
 | ||
| 	}
 | ||
| 
 | ||
| 	xb := x.first()
 | ||
| 	sb := s.first()
 | ||
| 	for xb != &none && sb != &none {
 | ||
| 		switch {
 | ||
| 		case xb.offset > sb.offset:
 | ||
| 			sb = s.next(sb)
 | ||
| 
 | ||
| 		case xb.offset < sb.offset:
 | ||
| 			xb = x.next(xb)
 | ||
| 
 | ||
| 		default:
 | ||
| 			var sum word
 | ||
| 			for i := range sb.bits {
 | ||
| 				r := sb.bits[i] & ^xb.bits[i]
 | ||
| 				sb.bits[i] = r
 | ||
| 				sum |= r
 | ||
| 			}
 | ||
| 			if sum == 0 {
 | ||
| 				sb = s.removeBlock(sb)
 | ||
| 			} else {
 | ||
| 				sb = s.next(sb)
 | ||
| 			}
 | ||
| 			xb = x.next(xb)
 | ||
| 		}
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| // Difference sets s to the difference x ∖ y.
 | ||
| func (s *Sparse) Difference(x, y *Sparse) {
 | ||
| 	switch {
 | ||
| 	case x == y:
 | ||
| 		s.Clear()
 | ||
| 		return
 | ||
| 	case s == x:
 | ||
| 		s.DifferenceWith(y)
 | ||
| 		return
 | ||
| 	case s == y:
 | ||
| 		var y2 Sparse
 | ||
| 		y2.Copy(y)
 | ||
| 		s.Difference(x, &y2)
 | ||
| 		return
 | ||
| 	}
 | ||
| 
 | ||
| 	xb := x.first()
 | ||
| 	yb := y.first()
 | ||
| 	sb := s.first()
 | ||
| 	for xb != &none && yb != &none {
 | ||
| 		if xb.offset > yb.offset {
 | ||
| 			// y has block, x has &none
 | ||
| 			yb = y.next(yb)
 | ||
| 			continue
 | ||
| 		}
 | ||
| 
 | ||
| 		if sb == &none {
 | ||
| 			sb = s.insertBlockBefore(sb)
 | ||
| 		}
 | ||
| 		sb.offset = xb.offset
 | ||
| 
 | ||
| 		switch {
 | ||
| 		case xb.offset < yb.offset:
 | ||
| 			// x has block, y has &none
 | ||
| 			sb.bits = xb.bits
 | ||
| 
 | ||
| 			sb = s.next(sb)
 | ||
| 
 | ||
| 		default:
 | ||
| 			// x and y have corresponding blocks
 | ||
| 			var sum word
 | ||
| 			for i := range sb.bits {
 | ||
| 				r := xb.bits[i] & ^yb.bits[i]
 | ||
| 				sb.bits[i] = r
 | ||
| 				sum |= r
 | ||
| 			}
 | ||
| 			if sum != 0 {
 | ||
| 				sb = s.next(sb)
 | ||
| 			} else {
 | ||
| 				// sb will be overwritten or removed
 | ||
| 			}
 | ||
| 
 | ||
| 			yb = y.next(yb)
 | ||
| 		}
 | ||
| 		xb = x.next(xb)
 | ||
| 	}
 | ||
| 
 | ||
| 	for xb != &none {
 | ||
| 		if sb == &none {
 | ||
| 			sb = s.insertBlockBefore(sb)
 | ||
| 		}
 | ||
| 		sb.offset = xb.offset
 | ||
| 		sb.bits = xb.bits
 | ||
| 		sb = s.next(sb)
 | ||
| 
 | ||
| 		xb = x.next(xb)
 | ||
| 	}
 | ||
| 
 | ||
| 	s.discardTail(sb)
 | ||
| }
 | ||
| 
 | ||
| // SymmetricDifferenceWith sets s to the symmetric difference s ∆ x.
 | ||
| func (s *Sparse) SymmetricDifferenceWith(x *Sparse) {
 | ||
| 	if s == x {
 | ||
| 		s.Clear()
 | ||
| 		return
 | ||
| 	}
 | ||
| 
 | ||
| 	sb := s.first()
 | ||
| 	xb := x.first()
 | ||
| 	for xb != &none && sb != &none {
 | ||
| 		switch {
 | ||
| 		case sb.offset < xb.offset:
 | ||
| 			sb = s.next(sb)
 | ||
| 		case xb.offset < sb.offset:
 | ||
| 			nb := s.insertBlockBefore(sb)
 | ||
| 			nb.offset = xb.offset
 | ||
| 			nb.bits = xb.bits
 | ||
| 			xb = x.next(xb)
 | ||
| 		default:
 | ||
| 			var sum word
 | ||
| 			for i := range sb.bits {
 | ||
| 				r := sb.bits[i] ^ xb.bits[i]
 | ||
| 				sb.bits[i] = r
 | ||
| 				sum |= r
 | ||
| 			}
 | ||
| 			if sum == 0 {
 | ||
| 				sb = s.removeBlock(sb)
 | ||
| 			} else {
 | ||
| 				sb = s.next(sb)
 | ||
| 			}
 | ||
| 			xb = x.next(xb)
 | ||
| 		}
 | ||
| 	}
 | ||
| 
 | ||
| 	for xb != &none { // append the tail of x to s
 | ||
| 		sb = s.insertBlockBefore(sb)
 | ||
| 		sb.offset = xb.offset
 | ||
| 		sb.bits = xb.bits
 | ||
| 		sb = s.next(sb)
 | ||
| 		xb = x.next(xb)
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| // SymmetricDifference sets s to the symmetric difference x ∆ y.
 | ||
| func (s *Sparse) SymmetricDifference(x, y *Sparse) {
 | ||
| 	switch {
 | ||
| 	case x == y:
 | ||
| 		s.Clear()
 | ||
| 		return
 | ||
| 	case s == x:
 | ||
| 		s.SymmetricDifferenceWith(y)
 | ||
| 		return
 | ||
| 	case s == y:
 | ||
| 		s.SymmetricDifferenceWith(x)
 | ||
| 		return
 | ||
| 	}
 | ||
| 
 | ||
| 	sb := s.first()
 | ||
| 	xb := x.first()
 | ||
| 	yb := y.first()
 | ||
| 	for xb != &none && yb != &none {
 | ||
| 		if sb == &none {
 | ||
| 			sb = s.insertBlockBefore(sb)
 | ||
| 		}
 | ||
| 		switch {
 | ||
| 		case yb.offset < xb.offset:
 | ||
| 			sb.offset = yb.offset
 | ||
| 			sb.bits = yb.bits
 | ||
| 			sb = s.next(sb)
 | ||
| 			yb = y.next(yb)
 | ||
| 		case xb.offset < yb.offset:
 | ||
| 			sb.offset = xb.offset
 | ||
| 			sb.bits = xb.bits
 | ||
| 			sb = s.next(sb)
 | ||
| 			xb = x.next(xb)
 | ||
| 		default:
 | ||
| 			var sum word
 | ||
| 			for i := range sb.bits {
 | ||
| 				r := xb.bits[i] ^ yb.bits[i]
 | ||
| 				sb.bits[i] = r
 | ||
| 				sum |= r
 | ||
| 			}
 | ||
| 			if sum != 0 {
 | ||
| 				sb.offset = xb.offset
 | ||
| 				sb = s.next(sb)
 | ||
| 			}
 | ||
| 			xb = x.next(xb)
 | ||
| 			yb = y.next(yb)
 | ||
| 		}
 | ||
| 	}
 | ||
| 
 | ||
| 	for xb != &none { // append the tail of x to s
 | ||
| 		if sb == &none {
 | ||
| 			sb = s.insertBlockBefore(sb)
 | ||
| 		}
 | ||
| 		sb.offset = xb.offset
 | ||
| 		sb.bits = xb.bits
 | ||
| 		sb = s.next(sb)
 | ||
| 		xb = x.next(xb)
 | ||
| 	}
 | ||
| 
 | ||
| 	for yb != &none { // append the tail of y to s
 | ||
| 		if sb == &none {
 | ||
| 			sb = s.insertBlockBefore(sb)
 | ||
| 		}
 | ||
| 		sb.offset = yb.offset
 | ||
| 		sb.bits = yb.bits
 | ||
| 		sb = s.next(sb)
 | ||
| 		yb = y.next(yb)
 | ||
| 	}
 | ||
| 
 | ||
| 	s.discardTail(sb)
 | ||
| }
 | ||
| 
 | ||
| // SubsetOf reports whether s ∖ x = ∅.
 | ||
| func (s *Sparse) SubsetOf(x *Sparse) bool {
 | ||
| 	if s == x {
 | ||
| 		return true
 | ||
| 	}
 | ||
| 
 | ||
| 	sb := s.first()
 | ||
| 	xb := x.first()
 | ||
| 	for sb != &none {
 | ||
| 		switch {
 | ||
| 		case xb == &none || xb.offset > sb.offset:
 | ||
| 			return false
 | ||
| 		case xb.offset < sb.offset:
 | ||
| 			xb = x.next(xb)
 | ||
| 		default:
 | ||
| 			for i := range sb.bits {
 | ||
| 				if sb.bits[i]&^xb.bits[i] != 0 {
 | ||
| 					return false
 | ||
| 				}
 | ||
| 			}
 | ||
| 			sb = s.next(sb)
 | ||
| 			xb = x.next(xb)
 | ||
| 		}
 | ||
| 	}
 | ||
| 	return true
 | ||
| }
 | ||
| 
 | ||
| // Equals reports whether the sets s and t have the same elements.
 | ||
| func (s *Sparse) Equals(t *Sparse) bool {
 | ||
| 	if s == t {
 | ||
| 		return true
 | ||
| 	}
 | ||
| 	sb := s.first()
 | ||
| 	tb := t.first()
 | ||
| 	for {
 | ||
| 		switch {
 | ||
| 		case sb == &none && tb == &none:
 | ||
| 			return true
 | ||
| 		case sb == &none || tb == &none:
 | ||
| 			return false
 | ||
| 		case sb.offset != tb.offset:
 | ||
| 			return false
 | ||
| 		case sb.bits != tb.bits:
 | ||
| 			return false
 | ||
| 		}
 | ||
| 
 | ||
| 		sb = s.next(sb)
 | ||
| 		tb = t.next(tb)
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| // String returns a human-readable description of the set s.
 | ||
| func (s *Sparse) String() string {
 | ||
| 	var buf bytes.Buffer
 | ||
| 	buf.WriteByte('{')
 | ||
| 	s.forEach(func(x int) {
 | ||
| 		if buf.Len() > 1 {
 | ||
| 			buf.WriteByte(' ')
 | ||
| 		}
 | ||
| 		fmt.Fprintf(&buf, "%d", x)
 | ||
| 	})
 | ||
| 	buf.WriteByte('}')
 | ||
| 	return buf.String()
 | ||
| }
 | ||
| 
 | ||
| // BitString returns the set as a string of 1s and 0s denoting the sum
 | ||
| // of the i'th powers of 2, for each i in s.  A radix point, always
 | ||
| // preceded by a digit, appears if the sum is non-integral.
 | ||
| //
 | ||
| // Examples:
 | ||
| //              {}.BitString() =      "0"
 | ||
| //           {4,5}.BitString() = "110000"
 | ||
| //            {-3}.BitString() =      "0.001"
 | ||
| //      {-3,0,4,5}.BitString() = "110001.001"
 | ||
| //
 | ||
| func (s *Sparse) BitString() string {
 | ||
| 	if s.IsEmpty() {
 | ||
| 		return "0"
 | ||
| 	}
 | ||
| 
 | ||
| 	min, max := s.Min(), s.Max()
 | ||
| 	var nbytes int
 | ||
| 	if max > 0 {
 | ||
| 		nbytes = max
 | ||
| 	}
 | ||
| 	nbytes++ // zero bit
 | ||
| 	radix := nbytes
 | ||
| 	if min < 0 {
 | ||
| 		nbytes += len(".") - min
 | ||
| 	}
 | ||
| 
 | ||
| 	b := make([]byte, nbytes)
 | ||
| 	for i := range b {
 | ||
| 		b[i] = '0'
 | ||
| 	}
 | ||
| 	if radix < nbytes {
 | ||
| 		b[radix] = '.'
 | ||
| 	}
 | ||
| 	s.forEach(func(x int) {
 | ||
| 		if x >= 0 {
 | ||
| 			x += len(".")
 | ||
| 		}
 | ||
| 		b[radix-x] = '1'
 | ||
| 	})
 | ||
| 	return string(b)
 | ||
| }
 | ||
| 
 | ||
| // GoString returns a string showing the internal representation of
 | ||
| // the set s.
 | ||
| //
 | ||
| func (s *Sparse) GoString() string {
 | ||
| 	var buf bytes.Buffer
 | ||
| 	for b := s.first(); b != &none; b = s.next(b) {
 | ||
| 		fmt.Fprintf(&buf, "block %p {offset=%d next=%p prev=%p",
 | ||
| 			b, b.offset, b.next, b.prev)
 | ||
| 		for _, w := range b.bits {
 | ||
| 			fmt.Fprintf(&buf, " 0%016x", w)
 | ||
| 		}
 | ||
| 		fmt.Fprintf(&buf, "}\n")
 | ||
| 	}
 | ||
| 	return buf.String()
 | ||
| }
 | ||
| 
 | ||
| // AppendTo returns the result of appending the elements of s to slice
 | ||
| // in order.
 | ||
| func (s *Sparse) AppendTo(slice []int) []int {
 | ||
| 	s.forEach(func(x int) {
 | ||
| 		slice = append(slice, x)
 | ||
| 	})
 | ||
| 	return slice
 | ||
| }
 | ||
| 
 | ||
| // -- Testing/debugging ------------------------------------------------
 | ||
| 
 | ||
| // check returns an error if the representation invariants of s are violated.
 | ||
| func (s *Sparse) check() error {
 | ||
| 	s.init()
 | ||
| 	if s.root.empty() {
 | ||
| 		// An empty set must have only the root block with offset MaxInt.
 | ||
| 		if s.root.next != &s.root {
 | ||
| 			return fmt.Errorf("multiple blocks with empty root block")
 | ||
| 		}
 | ||
| 		if s.root.offset != MaxInt {
 | ||
| 			return fmt.Errorf("empty set has offset %d, should be MaxInt", s.root.offset)
 | ||
| 		}
 | ||
| 		return nil
 | ||
| 	}
 | ||
| 	for b := s.first(); ; b = s.next(b) {
 | ||
| 		if b.offset%bitsPerBlock != 0 {
 | ||
| 			return fmt.Errorf("bad offset modulo: %d", b.offset)
 | ||
| 		}
 | ||
| 		if b.empty() {
 | ||
| 			return fmt.Errorf("empty block")
 | ||
| 		}
 | ||
| 		if b.prev.next != b {
 | ||
| 			return fmt.Errorf("bad prev.next link")
 | ||
| 		}
 | ||
| 		if b.next.prev != b {
 | ||
| 			return fmt.Errorf("bad next.prev link")
 | ||
| 		}
 | ||
| 		if b.next == &s.root {
 | ||
| 			break
 | ||
| 		}
 | ||
| 		if b.offset >= b.next.offset {
 | ||
| 			return fmt.Errorf("bad offset order: b.offset=%d, b.next.offset=%d",
 | ||
| 				b.offset, b.next.offset)
 | ||
| 		}
 | ||
| 	}
 | ||
| 	return nil
 | ||
| }
 |