diff --git a/bitset.go b/bitset.go index fbf0496..5751b68 100644 --- a/bitset.go +++ b/bitset.go @@ -115,6 +115,12 @@ func wordsNeeded(i uint) int { return int((i + (wordSize - 1)) >> log2WordSize) } +// wordsNeededUnbound calculates the number of words needed for i bits, possibly exceeding the capacity. +// This function is useful if you know that the capacity cannot be exceeded (e.g., you have an existing bitmap). +func wordsNeededUnbound(i uint) int { + return int((i + (wordSize - 1)) >> log2WordSize) +} + // wordsIndex calculates the index of words in a `uint64` func wordsIndex(i uint) uint { return i & (wordSize - 1) @@ -530,7 +536,7 @@ func (b *BitSet) ClearAll() *BitSet { // wordCount returns the number of words used in a bit set func (b *BitSet) wordCount() int { - return len(b.set) + return wordsNeededUnbound(b.length) } // Clone this BitSet @@ -606,10 +612,9 @@ func (b *BitSet) Equal(c *BitSet) bool { if b.length == 0 { // if they have both length == 0, then could have nil set return true } - // testing for equality shoud not transform the bitset (no call to safeSet) - - for p, v := range b.set { - if c.set[p] != v { + wn := b.wordCount() + for p:= 0; p < wn; p++ { + if c.set[p] != b.set[p] { return false } } @@ -898,7 +903,7 @@ func (b *BitSet) DumpAsBits() string { // BinaryStorageSize returns the binary storage requirements func (b *BitSet) BinaryStorageSize() int { - nWords := wordsNeeded(b.length) + nWords := b.wordCount() return binary.Size(uint64(0)) + binary.Size(b.set[:nWords]) } @@ -917,7 +922,7 @@ func (b *BitSet) WriteTo(stream io.Writer) (int64, error) { // binary.Write for large set writer := bufio.NewWriter(stream) var item = make([]byte, binary.Size(uint64(0))) // for serializing one uint64 - nWords := wordsNeeded(uint(length)) + nWords := b.wordCount() for i := range b.set[:nWords] { binaryOrder.PutUint64(item, b.set[i]) if nn, err := writer.Write(item); err != nil { diff --git a/bitset_test.go b/bitset_test.go index efa202f..601c274 100644 --- a/bitset_test.go +++ b/bitset_test.go @@ -1395,6 +1395,16 @@ func TestSetBitsetFrom(t *testing.T) { } } +func TestIssue116(t *testing.T) { + a := []uint64{2, 3, 5, 7, 11} + b := []uint64{2, 3, 5, 7, 11, 0, 1} + bitset1 := FromWithLength(320, a) + bitset2 := FromWithLength(320, b) + if !bitset1.Equal(bitset2) || !bitset2.Equal(bitset1) { + t.Error("Bitsets should be equal irrespective of the underlying capacity") + } +} + func TestFrom(t *testing.T) { u := []uint64{2, 3, 5, 7, 11} b := From(u)