Skip to content

Commit

Permalink
GetDiffSet speeup (#12945)
Browse files Browse the repository at this point in the history
  • Loading branch information
AskAlexSharov authored Dec 2, 2024
1 parent 7354753 commit 6c7acce
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 24 deletions.
8 changes: 6 additions & 2 deletions core/state/rw_v3.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"fmt"
"sync"
"time"
"unsafe"

"github.com/erigontech/erigon-lib/log/v3"
"github.com/holiman/uint256"
Expand Down Expand Up @@ -299,13 +300,13 @@ func (rs *StateV3) Unwind(ctx context.Context, tx kv.RwTx, blockUnwindTo, txUnwi

accountDiffs := changeset[kv.AccountsDomain]
for _, kv := range accountDiffs {
if err := stateChanges.Collect(kv.Key[:length.Addr], kv.Value); err != nil {
if err := stateChanges.Collect(toBytesZeroCopy(kv.Key)[:length.Addr], kv.Value); err != nil {
return err
}
}
storageDiffs := changeset[kv.StorageDomain]
for _, kv := range storageDiffs {
if err := stateChanges.Collect(kv.Key, kv.Value); err != nil {
if err := stateChanges.Collect(toBytesZeroCopy(kv.Key), kv.Value); err != nil {
return err
}
}
Expand Down Expand Up @@ -849,3 +850,6 @@ func returnReadList(v map[string]*libstate.KvList) {
//}
readListPool.Put(v)
}

func toStringZeroCopy(v []byte) string { return unsafe.String(&v[0], len(v)) }
func toBytesZeroCopy(s string) []byte { return unsafe.Slice(unsafe.StringData(s), len(s)) }
3 changes: 2 additions & 1 deletion erigon-lib/state/domain.go
Original file line number Diff line number Diff line change
Expand Up @@ -1467,7 +1467,8 @@ func (dt *DomainRoTx) Unwind(ctx context.Context, rwTx kv.RwTx, step, txNumUnwin
defer valsCursor.Close()
// First revert keys
for i := range domainDiffs {
key, value, prevStepBytes := domainDiffs[i].Key, domainDiffs[i].Value, domainDiffs[i].PrevStepBytes
keyStr, value, prevStepBytes := domainDiffs[i].Key, domainDiffs[i].Value, domainDiffs[i].PrevStepBytes
key := toBytesZeroCopy(keyStr)
if dt.d.largeValues {
if len(value) == 0 {
if !bytes.Equal(key[len(key)-8:], prevStepBytes) {
Expand Down
22 changes: 11 additions & 11 deletions erigon-lib/state/state_changeset.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"maps"
"math"
"sort"
"strings"

"github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon-lib/kv"
Expand All @@ -41,7 +42,7 @@ func (s *StateChangeSet) Copy() *StateChangeSet {
}

type DomainEntryDiff struct {
Key []byte
Key string
Value []byte
PrevStepBytes []byte
}
Expand Down Expand Up @@ -96,18 +97,17 @@ func (d *StateDiffDomain) GetDiffSet() (keysToValue []DomainEntryDiff) {
if len(d.prevValsSlice) != 0 {
return d.prevValsSlice
}
d.prevValsSlice = make([]DomainEntryDiff, 0, len(d.prevValues))
d.prevValsSlice = make([]DomainEntryDiff, len(d.prevValues))
i := 0
for k, v := range d.prevValues {
d.prevValsSlice = append(d.prevValsSlice, DomainEntryDiff{
Key: []byte(k),
Value: v,
PrevStepBytes: d.keys[k[:len(k)-8]],
})
d.prevValsSlice[i].Key = k
d.prevValsSlice[i].Value = v
d.prevValsSlice[i].PrevStepBytes = d.keys[k[:len(k)-8]]
i++
}
sort.Slice(d.prevValsSlice, func(i, j int) bool {
return bytes.Compare(d.prevValsSlice[i].Key, d.prevValsSlice[j].Key) < 0
return d.prevValsSlice[i].Key < d.prevValsSlice[j].Key
})

return d.prevValsSlice
}

Expand Down Expand Up @@ -197,7 +197,7 @@ func DeserializeDiffSet(in []byte) []DomainEntryDiff {
prevStepBytes := dict[in[0]]
in = in[1:]
diffSet[i] = DomainEntryDiff{
Key: key,
Key: toStringZeroCopy(key),
Value: value,
PrevStepBytes: prevStepBytes,
}
Expand All @@ -216,7 +216,7 @@ func MergeDiffSets(newer, older []DomainEntryDiff) []DomainEntryDiff {
var result []DomainEntryDiff
i, j := 0, 0
for i < len(newer) && j < len(older) {
cmp := bytes.Compare(older[j].Key, newer[i].Key)
cmp := strings.Compare(older[j].Key, newer[i].Key)
if cmp < 0 {
result = append(result, older[j])
j++
Expand Down
20 changes: 10 additions & 10 deletions erigon-lib/state/state_changeset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ func TestSerializeDeserializeDiff(t *testing.T) {

var d []DomainEntryDiff
step1, step2, step3 := [8]byte{1}, [8]byte{2}, [8]byte{3}
d = append(d, DomainEntryDiff{Key: []byte("key188888888"), Value: []byte("value1"), PrevStepBytes: step1[:]})
d = append(d, DomainEntryDiff{Key: []byte("key288888888"), Value: []byte("value2"), PrevStepBytes: step2[:]})
d = append(d, DomainEntryDiff{Key: []byte("key388888888"), Value: []byte("value3"), PrevStepBytes: step3[:]})
d = append(d, DomainEntryDiff{Key: []byte("key388888888"), Value: []byte("value3"), PrevStepBytes: step1[:]})
d = append(d, DomainEntryDiff{Key: "key188888888", Value: []byte("value1"), PrevStepBytes: step1[:]})
d = append(d, DomainEntryDiff{Key: "key288888888", Value: []byte("value2"), PrevStepBytes: step2[:]})
d = append(d, DomainEntryDiff{Key: "key388888888", Value: []byte("value3"), PrevStepBytes: step3[:]})
d = append(d, DomainEntryDiff{Key: "key388888888", Value: []byte("value3"), PrevStepBytes: step1[:]})

serialized := SerializeDiffSet(d, nil)
fmt.Println(len(serialized))
Expand All @@ -67,15 +67,15 @@ func TestMergeDiffSet(t *testing.T) {

var d1 []DomainEntryDiff
step1, step2, step3 := [8]byte{1}, [8]byte{2}, [8]byte{3}
d1 = append(d1, DomainEntryDiff{Key: []byte("key188888888"), Value: []byte("value1"), PrevStepBytes: step1[:]})
d1 = append(d1, DomainEntryDiff{Key: []byte("key288888888"), Value: []byte("value2"), PrevStepBytes: step2[:]})
d1 = append(d1, DomainEntryDiff{Key: []byte("key388888888"), Value: []byte("value3"), PrevStepBytes: step3[:]})
d1 = append(d1, DomainEntryDiff{Key: "key188888888", Value: []byte("value1"), PrevStepBytes: step1[:]})
d1 = append(d1, DomainEntryDiff{Key: "key288888888", Value: []byte("value2"), PrevStepBytes: step2[:]})
d1 = append(d1, DomainEntryDiff{Key: "key388888888", Value: []byte("value3"), PrevStepBytes: step3[:]})

var d2 []DomainEntryDiff
step4, step5, step6 := [8]byte{4}, [8]byte{5}, [8]byte{6}
d2 = append(d2, DomainEntryDiff{Key: []byte("key188888888"), Value: []byte("value5"), PrevStepBytes: step5[:]})
d2 = append(d2, DomainEntryDiff{Key: []byte("key388888888"), Value: []byte("value6"), PrevStepBytes: step6[:]})
d2 = append(d2, DomainEntryDiff{Key: []byte("key488888888"), Value: []byte("value4"), PrevStepBytes: step4[:]})
d2 = append(d2, DomainEntryDiff{Key: "key188888888", Value: []byte("value5"), PrevStepBytes: step5[:]})
d2 = append(d2, DomainEntryDiff{Key: "key388888888", Value: []byte("value6"), PrevStepBytes: step6[:]})
d2 = append(d2, DomainEntryDiff{Key: "key488888888", Value: []byte("value4"), PrevStepBytes: step4[:]})

merged := MergeDiffSets(d1, d2)
require.Equal(t, 4, len(merged))
Expand Down

0 comments on commit 6c7acce

Please sign in to comment.