Skip to content

Commit

Permalink
use bufio.Writer and bufio.Reader for smaller memory footprint while …
Browse files Browse the repository at this point in the history
…serializing
  • Loading branch information
thanhpk committed Mar 16, 2022
1 parent 04f5e3f commit 389c477
Showing 1 changed file with 32 additions and 14 deletions.
46 changes: 32 additions & 14 deletions bitset.go
Original file line number Diff line number Diff line change
Expand Up @@ -895,8 +895,22 @@ func (b *BitSet) WriteTo(stream io.Writer) (int64, error) {
}

// Write set
err = binary.Write(stream, binaryOrder, b.set)
return int64(b.BinaryStorageSize()), err
// current implementation of bufio.Writer is more memory efficient than
// binary.Write for large set
writer := bufio.NewWriter(stream)
var item = make([]byte, 8) // for serializing uint64
var n = binary.Size(uint64(0)) // number of bytes written
for _, x := range b.set {
binaryOrder.PutUint64(item, x)
nn, err := writer.Write(item)
if err != nil {
return int64(n+nn), err
}
n += nn
}

err = writer.Flush()
return int64(n), err
}

// ReadFrom reads a BitSet from a stream written using WriteTo
Expand All @@ -915,9 +929,20 @@ func (b *BitSet) ReadFrom(stream io.Reader) (int64, error) {
}

// Read remaining bytes as set
err = binary.Read(stream, binaryOrder, newset.set)
if err != nil {
return 0, err
// current implementation bufio.Reader is more memory efficient than
// binary.Read for large set
reader := bufio.NewReader(stream)
i := 0
var item = make([]byte, 8) // one uint64
for {
if _, err := reader.Read(item); err != nil {
if err == io.EOF {
break // done
}
return 0, err
}
newset.set[i] = binaryOrder.Uint64(item)
i++
}

*b = *newset
Expand All @@ -927,25 +952,18 @@ func (b *BitSet) ReadFrom(stream io.Reader) (int64, error) {
// MarshalBinary encodes a BitSet into a binary form and returns the result.
func (b *BitSet) MarshalBinary() ([]byte, error) {
var buf bytes.Buffer
writer := bufio.NewWriter(&buf)

_, err := b.WriteTo(writer)
_, err := b.WriteTo(&buf)
if err != nil {
return []byte{}, err
}

err = writer.Flush()

return buf.Bytes(), err
}

// UnmarshalBinary decodes the binary form generated by MarshalBinary.
func (b *BitSet) UnmarshalBinary(data []byte) error {
buf := bytes.NewReader(data)
reader := bufio.NewReader(buf)

_, err := b.ReadFrom(reader)

_, err := b.ReadFrom(buf)
return err
}

Expand Down

0 comments on commit 389c477

Please sign in to comment.