rlp: pool encoder allocations
This commit is contained in:
parent
c3d6228023
commit
3d0c6a8345
@ -5,12 +5,9 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: put encbufs in a sync.Pool.
|
|
||||||
// Doing that requires zeroing the buffers after use.
|
|
||||||
// encReader will need to drop it's buffer when done.
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// Common encoded values.
|
// Common encoded values.
|
||||||
// These are useful when implementing EncodeRLP.
|
// These are useful when implementing EncodeRLP.
|
||||||
@ -112,7 +109,9 @@ func Encode(w io.Writer, val interface{}) error {
|
|||||||
// Avoid copying by writing to the outer encbuf directly.
|
// Avoid copying by writing to the outer encbuf directly.
|
||||||
return outer.encode(val)
|
return outer.encode(val)
|
||||||
}
|
}
|
||||||
eb := newencbuf()
|
eb := encbufPool.Get().(*encbuf)
|
||||||
|
eb.reset()
|
||||||
|
defer encbufPool.Put(eb)
|
||||||
if err := eb.encode(val); err != nil {
|
if err := eb.encode(val); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -122,7 +121,9 @@ func Encode(w io.Writer, val interface{}) error {
|
|||||||
// EncodeBytes returns the RLP encoding of val.
|
// EncodeBytes returns the RLP encoding of val.
|
||||||
// Please see the documentation of Encode for the encoding rules.
|
// Please see the documentation of Encode for the encoding rules.
|
||||||
func EncodeToBytes(val interface{}) ([]byte, error) {
|
func EncodeToBytes(val interface{}) ([]byte, error) {
|
||||||
eb := newencbuf()
|
eb := encbufPool.Get().(*encbuf)
|
||||||
|
eb.reset()
|
||||||
|
defer encbufPool.Put(eb)
|
||||||
if err := eb.encode(val); err != nil {
|
if err := eb.encode(val); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -135,7 +136,8 @@ func EncodeToBytes(val interface{}) ([]byte, error) {
|
|||||||
//
|
//
|
||||||
// Please see the documentation of Encode for the encoding rules.
|
// Please see the documentation of Encode for the encoding rules.
|
||||||
func EncodeToReader(val interface{}) (size int, r io.Reader, err error) {
|
func EncodeToReader(val interface{}) (size int, r io.Reader, err error) {
|
||||||
eb := newencbuf()
|
eb := encbufPool.Get().(*encbuf)
|
||||||
|
eb.reset()
|
||||||
if err := eb.encode(val); err != nil {
|
if err := eb.encode(val); err != nil {
|
||||||
return 0, nil, err
|
return 0, nil, err
|
||||||
}
|
}
|
||||||
@ -182,8 +184,19 @@ func puthead(buf []byte, smalltag, largetag byte, size uint64) int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newencbuf() *encbuf {
|
// encbufs are pooled.
|
||||||
return &encbuf{sizebuf: make([]byte, 9)}
|
var encbufPool = sync.Pool{
|
||||||
|
New: func() interface{} { return &encbuf{sizebuf: make([]byte, 9)} },
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *encbuf) reset() {
|
||||||
|
w.lhsize = 0
|
||||||
|
if w.str != nil {
|
||||||
|
w.str = w.str[:0]
|
||||||
|
}
|
||||||
|
if w.lheads != nil {
|
||||||
|
w.lheads = w.lheads[:0]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// encbuf implements io.Writer so it can be passed it into EncodeRLP.
|
// encbuf implements io.Writer so it can be passed it into EncodeRLP.
|
||||||
@ -295,6 +308,8 @@ type encReader struct {
|
|||||||
func (r *encReader) Read(b []byte) (n int, err error) {
|
func (r *encReader) Read(b []byte) (n int, err error) {
|
||||||
for {
|
for {
|
||||||
if r.piece = r.next(); r.piece == nil {
|
if r.piece = r.next(); r.piece == nil {
|
||||||
|
encbufPool.Put(r.buf)
|
||||||
|
r.buf = nil
|
||||||
return n, io.EOF
|
return n, io.EOF
|
||||||
}
|
}
|
||||||
nn := copy(b[n:], r.piece)
|
nn := copy(b[n:], r.piece)
|
||||||
@ -313,6 +328,9 @@ func (r *encReader) Read(b []byte) (n int, err error) {
|
|||||||
// it returns nil at EOF.
|
// it returns nil at EOF.
|
||||||
func (r *encReader) next() []byte {
|
func (r *encReader) next() []byte {
|
||||||
switch {
|
switch {
|
||||||
|
case r.buf == nil:
|
||||||
|
return nil
|
||||||
|
|
||||||
case r.piece != nil:
|
case r.piece != nil:
|
||||||
// There is still data available for reading.
|
// There is still data available for reading.
|
||||||
return r.piece
|
return r.piece
|
||||||
|
Loading…
Reference in New Issue
Block a user