aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarius van der Wijden <m.vanderwijden@live.de>2019-02-25 18:34:08 +0800
committerPéter Szilágyi <peterke@gmail.com>2019-02-25 18:34:08 +0800
commit7d881e45bdaad3cf1a301c7523a07026a479fd04 (patch)
tree637cd5891967904f0fba84d65e9ccd0ff43d9706
parent872370e3bc3c753937784e33e32d499ec277ab5f (diff)
downloadgo-tangerine-7d881e45bdaad3cf1a301c7523a07026a479fd04.tar
go-tangerine-7d881e45bdaad3cf1a301c7523a07026a479fd04.tar.gz
go-tangerine-7d881e45bdaad3cf1a301c7523a07026a479fd04.tar.bz2
go-tangerine-7d881e45bdaad3cf1a301c7523a07026a479fd04.tar.lz
go-tangerine-7d881e45bdaad3cf1a301c7523a07026a479fd04.tar.xz
go-tangerine-7d881e45bdaad3cf1a301c7523a07026a479fd04.tar.zst
go-tangerine-7d881e45bdaad3cf1a301c7523a07026a479fd04.zip
rlp: added pooling of streams using sync (#19044)
Prevents reallocation, improves performance
-rw-r--r--rlp/decode.go21
1 files changed, 17 insertions, 4 deletions
diff --git a/rlp/decode.go b/rlp/decode.go
index dbbe59959..e638c01ea 100644
--- a/rlp/decode.go
+++ b/rlp/decode.go
@@ -26,6 +26,7 @@ import (
"math/big"
"reflect"
"strings"
+ "sync"
)
var (
@@ -48,6 +49,10 @@ var (
errUintOverflow = errors.New("rlp: uint overflow")
errNoPointer = errors.New("rlp: interface given to Decode must be a pointer")
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
@@ -126,17 +131,24 @@ type Decoder interface {
//
// NewStream(r, limit).Decode(val)
func Decode(r io.Reader, val interface{}) error {
- // TODO: this could use a Stream from a pool.
- return NewStream(r, 0).Decode(val)
+ stream := streamPool.Get().(*Stream)
+ defer streamPool.Put(stream)
+
+ stream.Reset(r, 0)
+ return stream.Decode(val)
}
// DecodeBytes parses RLP data from b into val.
// Please see the documentation of Decode for the decoding rules.
// The input must contain exactly one value and no trailing data.
func DecodeBytes(b []byte, val interface{}) error {
- // TODO: this could use a Stream from a pool.
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
}
if r.Len() > 0 {
@@ -853,6 +865,7 @@ func (s *Stream) Reset(r io.Reader, inputLimit uint64) {
if s.uintbuf == nil {
s.uintbuf = make([]byte, 8)
}
+ s.byteval = 0
}
// Kind returns the kind and size of the next value in the