Unverified Commit cc536a08 authored by Hannah Howard's avatar Hannah Howard Committed by GitHub

feat(memory): improve memory usage (#110)

reduce copies of temporary buffers in message write and unverified block store
parent 0c2f18ea
package message package message
import ( import (
"encoding/binary"
"errors" "errors"
"fmt" "fmt"
"io" "io"
ggio "github.com/gogo/protobuf/io"
blocks "github.com/ipfs/go-block-format" blocks "github.com/ipfs/go-block-format"
cid "github.com/ipfs/go-cid" cid "github.com/ipfs/go-cid"
"github.com/ipld/go-ipld-prime" "github.com/ipld/go-ipld-prime"
pool "github.com/libp2p/go-buffer-pool"
"github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-msgio" "github.com/libp2p/go-msgio"
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
...@@ -346,12 +347,19 @@ func (gsm *graphSyncMessage) ToProto() (*pb.Message, error) { ...@@ -346,12 +347,19 @@ func (gsm *graphSyncMessage) ToProto() (*pb.Message, error) {
} }
func (gsm *graphSyncMessage) ToNet(w io.Writer) error { func (gsm *graphSyncMessage) ToNet(w io.Writer) error {
pbw := ggio.NewDelimitedWriter(w)
msg, err := gsm.ToProto() msg, err := gsm.ToProto()
size := proto.Size(msg)
buf := pool.Get(size + binary.MaxVarintLen64)
defer pool.Put(buf)
n := binary.PutUvarint(buf, uint64(size))
out, err := proto.MarshalOptions{}.MarshalAppend(buf[:n], msg)
if err != nil { if err != nil {
return err return err
} }
return pbw.WriteMsg(msg) _, err = w.Write(out)
return err
} }
func (gsm *graphSyncMessage) Loggable() map[string]interface{} { func (gsm *graphSyncMessage) Loggable() map[string]interface{} {
......
...@@ -6,6 +6,10 @@ import ( ...@@ -6,6 +6,10 @@ import (
ipld "github.com/ipld/go-ipld-prime" ipld "github.com/ipld/go-ipld-prime"
) )
type settableWriter interface {
SetBytes([]byte) error
}
// UnverifiedBlockStore holds an in memory cache of receied blocks from the network // UnverifiedBlockStore holds an in memory cache of receied blocks from the network
// that have not been verified to be part of a traversal // that have not been verified to be part of a traversal
type UnverifiedBlockStore struct { type UnverifiedBlockStore struct {
...@@ -55,7 +59,11 @@ func (ubs *UnverifiedBlockStore) VerifyBlock(lnk ipld.Link) ([]byte, error) { ...@@ -55,7 +59,11 @@ func (ubs *UnverifiedBlockStore) VerifyBlock(lnk ipld.Link) ([]byte, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
_, err = buffer.Write(data) if settable, ok := buffer.(settableWriter); ok {
err = settable.SetBytes(data)
} else {
_, err = buffer.Write(data)
}
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -31,7 +31,7 @@ func LoaderForBlockstore(bs bstore.Blockstore) ipld.Loader { ...@@ -31,7 +31,7 @@ func LoaderForBlockstore(bs bstore.Blockstore) ipld.Loader {
// from an IPFS blockstore // from an IPFS blockstore
func StorerForBlockstore(bs bstore.Blockstore) ipld.Storer { func StorerForBlockstore(bs bstore.Blockstore) ipld.Storer {
return func(lnkCtx ipld.LinkContext) (io.Writer, ipld.StoreCommitter, error) { return func(lnkCtx ipld.LinkContext) (io.Writer, ipld.StoreCommitter, error) {
var buffer bytes.Buffer var buffer settableBuffer
committer := func(lnk ipld.Link) error { committer := func(lnk ipld.Link) error {
asCidLink, ok := lnk.(cidlink.Link) asCidLink, ok := lnk.(cidlink.Link)
if !ok { if !ok {
...@@ -46,3 +46,22 @@ func StorerForBlockstore(bs bstore.Blockstore) ipld.Storer { ...@@ -46,3 +46,22 @@ func StorerForBlockstore(bs bstore.Blockstore) ipld.Storer {
return &buffer, committer, nil return &buffer, committer, nil
} }
} }
type settableBuffer struct {
bytes.Buffer
didSetData bool
data []byte
}
func (sb *settableBuffer) SetBytes(data []byte) error {
sb.didSetData = true
sb.data = data
return nil
}
func (sb *settableBuffer) Bytes() []byte {
if sb.didSetData {
return sb.data
}
return sb.Buffer.Bytes()
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment