diff --git a/container/intsets/sparse.go b/container/intsets/sparse.go index 763b384858..0017ddfe89 100644 --- a/container/intsets/sparse.go +++ b/container/intsets/sparse.go @@ -21,6 +21,10 @@ package intsets // 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): experiment with making the root block indirect (nil +// iff IsEmpty). This would reduce the memory usage when empty and +// might simplify the aliasing invariants. import ( "bytes" @@ -50,7 +54,7 @@ type word uintptr const ( _m = ^word(0) bitsPerWord = 8 << (_m>>8&1 + _m>>16&1 + _m>>32&1) - bitsPerBlock = 128 + bitsPerBlock = 256 // optimal value for go/pointer solver performance wordsPerBlock = bitsPerBlock / bitsPerWord ) @@ -161,9 +165,9 @@ func (b *block) min(take bool) int { if w != 0 { tz := ntz(w) if take { - b.bits[i] = w &^ (1 << tz) + b.bits[i] = w &^ (1 << uint(tz)) } - return b.offset + int(i*bitsPerWord) + int(tz) + return b.offset + int(i*bitsPerWord) + tz } } panic("BUG: empty block") diff --git a/container/intsets/util.go b/container/intsets/util.go index a626048122..76e682cf4d 100644 --- a/container/intsets/util.go +++ b/container/intsets/util.go @@ -44,11 +44,11 @@ func nlz(x word) int { // ntz returns the number of trailing zeros of x. // From Hacker's Delight, fig 5.13. -func ntz(x word) word { +func ntz(x word) int { if x == 0 { return bitsPerWord } - var n word = 1 + n := 1 if bitsPerWord == 64 { if (x & 0xffffffff) == 0 { n = n + 32 @@ -71,5 +71,5 @@ func ntz(x word) word { n = n + 2 x = x >> 2 } - return n - x&1 + return n - int(x&1) }