rlp: added pooling of streams using sync (#19044)
Prevents reallocation, improves performance
This commit is contained in:
parent
872370e3bc
commit
7d881e45bd
@ -26,6 +26,7 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -48,6 +49,10 @@ var (
|
|||||||
errUintOverflow = errors.New("rlp: uint overflow")
|
errUintOverflow = errors.New("rlp: uint overflow")
|
||||||
errNoPointer = errors.New("rlp: interface given to Decode must be a pointer")
|
errNoPointer = errors.New("rlp: interface given to Decode must be a pointer")
|
||||||
errDecodeIntoNil = errors.New("rlp: pointer given to Decode must not be nil")
|
errDecodeIntoNil = errors.New("rlp: pointer given to Decode must not be nil")
|
||||||
|
|
||||||
|
streamPool = sync.Pool{
|
||||||
|
New: func() interface{} { return new(Stream) },
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Decoder is implemented by types that require custom RLP
|
// Decoder is implemented by types that require custom RLP
|
||||||
@ -126,17 +131,24 @@ type Decoder interface {
|
|||||||
//
|
//
|
||||||
// NewStream(r, limit).Decode(val)
|
// NewStream(r, limit).Decode(val)
|
||||||
func Decode(r io.Reader, val interface{}) error {
|
func Decode(r io.Reader, val interface{}) error {
|
||||||
// TODO: this could use a Stream from a pool.
|
stream := streamPool.Get().(*Stream)
|
||||||
return NewStream(r, 0).Decode(val)
|
defer streamPool.Put(stream)
|
||||||
|
|
||||||
|
stream.Reset(r, 0)
|
||||||
|
return stream.Decode(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeBytes parses RLP data from b into val.
|
// DecodeBytes parses RLP data from b into val.
|
||||||
// Please see the documentation of Decode for the decoding rules.
|
// Please see the documentation of Decode for the decoding rules.
|
||||||
// The input must contain exactly one value and no trailing data.
|
// The input must contain exactly one value and no trailing data.
|
||||||
func DecodeBytes(b []byte, val interface{}) error {
|
func DecodeBytes(b []byte, val interface{}) error {
|
||||||
// TODO: this could use a Stream from a pool.
|
|
||||||
r := bytes.NewReader(b)
|
r := bytes.NewReader(b)
|
||||||
if err := NewStream(r, uint64(len(b))).Decode(val); err != nil {
|
|
||||||
|
stream := streamPool.Get().(*Stream)
|
||||||
|
defer streamPool.Put(stream)
|
||||||
|
|
||||||
|
stream.Reset(r, uint64(len(b)))
|
||||||
|
if err := stream.Decode(val); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if r.Len() > 0 {
|
if r.Len() > 0 {
|
||||||
@ -853,6 +865,7 @@ func (s *Stream) Reset(r io.Reader, inputLimit uint64) {
|
|||||||
if s.uintbuf == nil {
|
if s.uintbuf == nil {
|
||||||
s.uintbuf = make([]byte, 8)
|
s.uintbuf = make([]byte, 8)
|
||||||
}
|
}
|
||||||
|
s.byteval = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kind returns the kind and size of the next value in the
|
// Kind returns the kind and size of the next value in the
|
||||||
|
Loading…
Reference in New Issue
Block a user