rlp: pool encoder allocations
This commit is contained in:
		
							parent
							
								
									c3d6228023
								
							
						
					
					
						commit
						3d0c6a8345
					
				| @ -5,12 +5,9 @@ import ( | ||||
| 	"io" | ||||
| 	"math/big" | ||||
| 	"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 ( | ||||
| 	// Common encoded values.
 | ||||
| 	// 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.
 | ||||
| 		return outer.encode(val) | ||||
| 	} | ||||
| 	eb := newencbuf() | ||||
| 	eb := encbufPool.Get().(*encbuf) | ||||
| 	eb.reset() | ||||
| 	defer encbufPool.Put(eb) | ||||
| 	if err := eb.encode(val); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| @ -122,7 +121,9 @@ func Encode(w io.Writer, val interface{}) error { | ||||
| // EncodeBytes returns the RLP encoding of val.
 | ||||
| // Please see the documentation of Encode for the encoding rules.
 | ||||
| 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 { | ||||
| 		return nil, err | ||||
| 	} | ||||
| @ -135,7 +136,8 @@ func EncodeToBytes(val interface{}) ([]byte, error) { | ||||
| //
 | ||||
| // Please see the documentation of Encode for the encoding rules.
 | ||||
| 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 { | ||||
| 		return 0, nil, err | ||||
| 	} | ||||
| @ -182,8 +184,19 @@ func puthead(buf []byte, smalltag, largetag byte, size uint64) int { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func newencbuf() *encbuf { | ||||
| 	return &encbuf{sizebuf: make([]byte, 9)} | ||||
| // encbufs are pooled.
 | ||||
| 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.
 | ||||
| @ -295,6 +308,8 @@ type encReader struct { | ||||
| func (r *encReader) Read(b []byte) (n int, err error) { | ||||
| 	for { | ||||
| 		if r.piece = r.next(); r.piece == nil { | ||||
| 			encbufPool.Put(r.buf) | ||||
| 			r.buf = nil | ||||
| 			return n, io.EOF | ||||
| 		} | ||||
| 		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.
 | ||||
| func (r *encReader) next() []byte { | ||||
| 	switch { | ||||
| 	case r.buf == nil: | ||||
| 		return nil | ||||
| 
 | ||||
| 	case r.piece != nil: | ||||
| 		// There is still data available for reading.
 | ||||
| 		return r.piece | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user