Skip to content

Commit

Permalink
rlp.Decode: alloc-free reader (#12013)
Browse files Browse the repository at this point in the history
it's 15% of allocs of `blockReader.GetBlockWithSenders`
  • Loading branch information
AskAlexSharov authored Sep 17, 2024
1 parent fef39d7 commit e96cd34
Showing 1 changed file with 22 additions and 2 deletions.
24 changes: 22 additions & 2 deletions rlp/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func Decode(r io.Reader, val interface{}) error {
// DecodeBytes parses RLP data from b into val. Please see package-level documentation for
// the decoding rules. The input must contain exactly one value and no trailing data.
func DecodeBytes(b []byte, val interface{}) error {
r := bytes.NewReader(b)
r := (*sliceReader)(&b)

stream, ok := streamPool.Get().(*Stream)
if !ok {
Expand All @@ -133,7 +133,7 @@ func DecodeBytes(b []byte, val interface{}) error {
if err := stream.Decode(val); err != nil {
return err
}
if r.Len() > 0 {
if len(b) > 0 {
return ErrMoreThanOneValue
}
return nil
Expand Down Expand Up @@ -1131,3 +1131,23 @@ func (s *Stream) willRead(n uint64) error {
}
return nil
}

type sliceReader []byte

func (sr *sliceReader) Read(b []byte) (int, error) {
if len(*sr) == 0 {
return 0, io.EOF
}
n := copy(b, *sr)
*sr = (*sr)[n:]
return n, nil
}

func (sr *sliceReader) ReadByte() (byte, error) {
if len(*sr) == 0 {
return 0, io.EOF
}
b := (*sr)[0]
*sr = (*sr)[1:]
return b, nil
}

0 comments on commit e96cd34

Please sign in to comment.