rlp: apply further optimization

This commit is contained in:
Martin Holst Swende 2024-01-18 11:59:25 +01:00
parent 57c39e886e
commit ab6ad71b4b
No known key found for this signature in database
GPG key ID: 683B438C05A5DDF0
2 changed files with 28 additions and 14 deletions

View file

@ -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. // EndList ends up list starting from offset and returns the extended buffer.
// Content after offset is treated as list content. // 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 { func EndList(buf []byte, offset int) []byte {
contentSize := len(buf) - offset contentSize := len(buf) - offset - 1
if contentSize == 0 { if contentSize < 56 {
buf = append(buf, 0xC0)
} else if contentSize < 56 {
// shift the content for room of list header
buf = append(buf[:offset+1], buf[offset:]...)
// write list header // write list header
buf[offset] = 0xC0 + byte(contentSize) buf[offset] = 0xC0 + byte(contentSize)
} else { return buf
}
headerSize := intsize(uint64(contentSize)) + 1 headerSize := intsize(uint64(contentSize)) + 1
// shift the content for room of list header // shift the content for room of list header
buf = append(buf[:offset+headerSize], buf[offset:]...) buf = append(buf[:offset+headerSize], buf[offset:]...)
// write list header // 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) appendUintWithTag(buf[:offset], uint64(contentSize), 0xF7)
}
return buf return buf
} }

View file

@ -24,7 +24,8 @@ func (n *fullNode) encode(buf []byte) []byte {
if buf == nil { if buf == nil {
buf = make([]byte, 0, 550) buf = make([]byte, 0, 550)
} }
offset := len(buf) var offset int
buf, offset = rlp.StartList(buf)
for _, c := range n.Children { for _, c := range n.Children {
if c != nil { if c != nil {
buf = c.encode(buf) buf = c.encode(buf)
@ -39,7 +40,8 @@ func (n *shortNode) encode(buf []byte) []byte {
if buf == nil { if buf == nil {
buf = make([]byte, 0, len(n.Key)+40) 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) buf = rlp.AppendString(buf, n.Key)
if n.Val != nil { if n.Val != nil {
buf = n.Val.encode(buf) buf = n.Val.encode(buf)