Skip to content

Commit

Permalink
Make WriteTo respect BitSet length
Browse files Browse the repository at this point in the history
Fixes #114
  • Loading branch information
omerfirmak committed Nov 17, 2022
1 parent e4f40f1 commit 6752638
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
6 changes: 4 additions & 2 deletions bitset.go
Original file line number Diff line number Diff line change
Expand Up @@ -897,7 +897,8 @@ func (b *BitSet) DumpAsBits() string {

// BinaryStorageSize returns the binary storage requirements
func (b *BitSet) BinaryStorageSize() int {
return binary.Size(uint64(0)) + binary.Size(b.set)
nWords := wordsNeeded(b.length)
return binary.Size(uint64(0)) + binary.Size(b.set[:nWords])
}

// WriteTo writes a BitSet to a stream
Expand All @@ -915,7 +916,8 @@ 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
for i := range b.set {
nWords := wordsNeeded(uint(length))
for i := range b.set[:nWords] {
binaryOrder.PutUint64(item, b.set[i])
if nn, err := writer.Write(item); err != nil {
return int64(i*binary.Size(uint64(0)) + nn), err
Expand Down
29 changes: 29 additions & 0 deletions bitset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1224,6 +1224,35 @@ func TestMarshalUnmarshalBinary(t *testing.T) {
t.Error("Bitsets are not equal:\n\t", a.DumpAsBits(), "\n\t", b.DumpAsBits())
return
}

aSetBit := uint(128)
a = New(256).Set(aSetBit)
aExpectedMarshaledSize := 8 /* length: uint64 */ + 4 * 8 /* set : [4]uint64 */
aMarshaled, err := a.MarshalBinary()

if err != nil || aExpectedMarshaledSize != len(aMarshaled) || aExpectedMarshaledSize != a.BinaryStorageSize() {
t.Error("MarshalBinary failed to produce expected (", aExpectedMarshaledSize , ") number of bytes")
return
}

shiftAmount := uint(72)
// https://github.com/bits-and-blooms/bitset/issues/114
for i := uint(0) ; i < shiftAmount; i++ {
a.DeleteAt(0)
}

aExpectedMarshaledSize = 8 /* length: uint64 */ + 3 * 8 /* set : [3]uint64 */
aMarshaled, err = a.MarshalBinary()
if err != nil || aExpectedMarshaledSize != len(aMarshaled) || aExpectedMarshaledSize != a.BinaryStorageSize() {
t.Error("MarshalBinary failed to produce expected (", aExpectedMarshaledSize , ") number of bytes")
return
}

copyBinary(t, a, b)

if b.Len() != 256 - shiftAmount || !b.Test(aSetBit - shiftAmount) {
t.Error("Shifted bitset is not copied correctly")
}
}

func TestMarshalUnmarshalBinaryByLittleEndian(t *testing.T) {
Expand Down

0 comments on commit 6752638

Please sign in to comment.