mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 03:30:37 +00:00
core/types, rlp: optimize derivesha (#21728)
This PR contains a minor optimization in derivesha, by exposing the RLP int-encoding and making use of it to write integers directly to a buffer (an RLP integer is known to never require more than 9 bytes total). rlp.AppendUint64 might be useful in other places too. The code assumes, just as before, that the hasher (a trie) will copy the key internally, which it does when doing keybytesToHex(key). Co-authored-by: Felix Lange <fjl@twurst.com> # Conflicts: # core/types/derive_sha.go
This commit is contained in:
parent
040dcebf57
commit
288f9bd414
71
rlp/raw.go
71
rlp/raw.go
@ -180,3 +180,74 @@ func readSize(b []byte, slen byte) (uint64, error) {
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// AppendUint64 appends the RLP encoding of i to b, and returns the resulting slice.
|
||||
func AppendUint64(b []byte, i uint64) []byte {
|
||||
if i == 0 {
|
||||
return append(b, 0x80)
|
||||
} else if i < 128 {
|
||||
return append(b, byte(i))
|
||||
}
|
||||
switch {
|
||||
case i < (1 << 8):
|
||||
return append(b, 0x81, byte(i))
|
||||
case i < (1 << 16):
|
||||
return append(b, 0x82,
|
||||
byte(i>>8),
|
||||
byte(i),
|
||||
)
|
||||
case i < (1 << 24):
|
||||
return append(b, 0x83,
|
||||
byte(i>>16),
|
||||
byte(i>>8),
|
||||
byte(i),
|
||||
)
|
||||
case i < (1 << 32):
|
||||
return append(b, 0x84,
|
||||
byte(i>>24),
|
||||
byte(i>>16),
|
||||
byte(i>>8),
|
||||
byte(i),
|
||||
)
|
||||
case i < (1 << 40):
|
||||
return append(b, 0x85,
|
||||
byte(i>>32),
|
||||
byte(i>>24),
|
||||
byte(i>>16),
|
||||
byte(i>>8),
|
||||
byte(i),
|
||||
)
|
||||
|
||||
case i < (1 << 48):
|
||||
return append(b, 0x86,
|
||||
byte(i>>40),
|
||||
byte(i>>32),
|
||||
byte(i>>24),
|
||||
byte(i>>16),
|
||||
byte(i>>8),
|
||||
byte(i),
|
||||
)
|
||||
case i < (1 << 56):
|
||||
return append(b, 0x87,
|
||||
byte(i>>48),
|
||||
byte(i>>40),
|
||||
byte(i>>32),
|
||||
byte(i>>24),
|
||||
byte(i>>16),
|
||||
byte(i>>8),
|
||||
byte(i),
|
||||
)
|
||||
|
||||
default:
|
||||
return append(b, 0x88,
|
||||
byte(i>>56),
|
||||
byte(i>>48),
|
||||
byte(i>>40),
|
||||
byte(i>>32),
|
||||
byte(i>>24),
|
||||
byte(i>>16),
|
||||
byte(i>>8),
|
||||
byte(i),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import (
|
||||
"io"
|
||||
"reflect"
|
||||
"testing"
|
||||
"testing/quick"
|
||||
)
|
||||
|
||||
func TestCountValues(t *testing.T) {
|
||||
@ -240,3 +241,40 @@ func TestReadSize(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendUint64(t *testing.T) {
|
||||
tests := []struct {
|
||||
input uint64
|
||||
slice []byte
|
||||
output string
|
||||
}{
|
||||
{0, nil, "80"},
|
||||
{1, nil, "01"},
|
||||
{2, nil, "02"},
|
||||
{127, nil, "7F"},
|
||||
{128, nil, "8180"},
|
||||
{129, nil, "8181"},
|
||||
{0xFFFFFF, nil, "83FFFFFF"},
|
||||
{127, []byte{1, 2, 3}, "0102037F"},
|
||||
{0xFFFFFF, []byte{1, 2, 3}, "01020383FFFFFF"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
x := AppendUint64(test.slice, test.input)
|
||||
if !bytes.Equal(x, unhex(test.output)) {
|
||||
t.Errorf("AppendUint64(%v, %d): got %x, want %s", test.slice, test.input, x, test.output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendUint64Random(t *testing.T) {
|
||||
fn := func(i uint64) bool {
|
||||
enc, _ := EncodeToBytes(i)
|
||||
encAppend := AppendUint64(nil, i)
|
||||
return bytes.Equal(enc, encAppend)
|
||||
}
|
||||
config := quick.Config{MaxCountScale: 50}
|
||||
if err := quick.Check(fn, &config); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user