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