From ab6ad71b4bd93898a64b857593a69ee9329a05d3 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Thu, 18 Jan 2024 11:59:25 +0100 Subject: [PATCH] rlp: apply further optimization --- rlp/raw.go | 36 ++++++++++++++++++++++++------------ trie/node_enc.go | 6 ++++-- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/rlp/raw.go b/rlp/raw.go index 53da9f0d46..cdd3ec9c18 100644 --- a/rlp/raw.go +++ b/rlp/raw.go @@ -315,23 +315,35 @@ func AppendString(buf, str []byte) []byte { } } +// StartList appends a one-byte header, and returns the offset to +// before the header. It is expected that StartList is later followed by EndList. +func StartList(buf []byte) ([]byte, int) { + offset := len(buf) + // append a 1-byte header, which will suffice if content size is < 56 bytes + return append(buf, 0xc0), offset +} + // EndList ends up list starting from offset and returns the extended buffer. // Content after offset is treated as list content. +// +// OBS: It is assumed that a 1-bytes header is already in place, put there +// by a preceding call to StartList. func EndList(buf []byte, offset int) []byte { - contentSize := len(buf) - offset - if contentSize == 0 { - buf = append(buf, 0xC0) - } else if contentSize < 56 { - // shift the content for room of list header - buf = append(buf[:offset+1], buf[offset:]...) + contentSize := len(buf) - offset - 1 + if contentSize < 56 { // write list header buf[offset] = 0xC0 + byte(contentSize) - } else { - headerSize := intsize(uint64(contentSize)) + 1 - // shift the content for room of list header - buf = append(buf[:offset+headerSize], buf[offset:]...) - // write list header - appendUintWithTag(buf[:offset], uint64(contentSize), 0xF7) + return buf } + headerSize := intsize(uint64(contentSize)) + 1 + // shift the content for room of list header + buf = append(buf[:offset+headerSize], buf[offset:]...) + // write list header. OBS! This call ignores the return value, + // since the append operation is performed on buf[:offset], and we + // already just moved the content, we know that the append operation + // will not cause a realloc. This operation simply writes the header into + // the given location. + appendUintWithTag(buf[:offset], uint64(contentSize), 0xF7) + return buf } diff --git a/trie/node_enc.go b/trie/node_enc.go index c2a32a5d98..74e716236a 100644 --- a/trie/node_enc.go +++ b/trie/node_enc.go @@ -24,7 +24,8 @@ func (n *fullNode) encode(buf []byte) []byte { if buf == nil { buf = make([]byte, 0, 550) } - offset := len(buf) + var offset int + buf, offset = rlp.StartList(buf) for _, c := range n.Children { if c != nil { buf = c.encode(buf) @@ -39,7 +40,8 @@ func (n *shortNode) encode(buf []byte) []byte { if buf == nil { buf = make([]byte, 0, len(n.Key)+40) } - offset := len(buf) + var offset int + buf, offset = rlp.StartList(buf) buf = rlp.AppendString(buf, n.Key) if n.Val != nil { buf = n.Val.encode(buf)