triedb/pathdb: flush mutation records in parallel

This commit is contained in:
Gary Rong 2025-06-11 17:18:12 +08:00
parent aa65b94969
commit fdac3b7756

View file

@ -19,6 +19,7 @@ package pathdb
import ( import (
"errors" "errors"
"fmt" "fmt"
"runtime"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
@ -29,6 +30,7 @@ import (
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"golang.org/x/sync/errgroup"
) )
const ( const (
@ -125,36 +127,17 @@ func (b *batchIndexer) finish(force bool) error {
if !force && b.counter < historyIndexBatch { if !force && b.counter < historyIndexBatch {
return nil return nil
} }
batch := b.db.NewBatch() var (
batch = b.db.NewBatch()
batchMu sync.RWMutex
eg errgroup.Group
)
eg.SetLimit(runtime.NumCPU())
for addrHash, idList := range b.accounts { for addrHash, idList := range b.accounts {
if !b.delete { eg.Go(func() error {
iw, err := newIndexWriter(b.db, newAccountIdent(addrHash))
if err != nil {
return err
}
for _, n := range idList {
if err := iw.append(n); err != nil {
return err
}
}
iw.finish(batch)
} else {
id, err := newIndexDeleter(b.db, newAccountIdent(addrHash))
if err != nil {
return err
}
for _, n := range idList {
if err := id.pop(n); err != nil {
return err
}
}
id.finish(batch)
}
}
for addrHash, slots := range b.storages {
for storageHash, idList := range slots {
if !b.delete { if !b.delete {
iw, err := newIndexWriter(b.db, newStorageIdent(addrHash, storageHash)) iw, err := newIndexWriter(b.db, newAccountIdent(addrHash))
if err != nil { if err != nil {
return err return err
} }
@ -163,9 +146,11 @@ func (b *batchIndexer) finish(force bool) error {
return err return err
} }
} }
batchMu.Lock()
iw.finish(batch) iw.finish(batch)
batchMu.Unlock()
} else { } else {
id, err := newIndexDeleter(b.db, newStorageIdent(addrHash, storageHash)) id, err := newIndexDeleter(b.db, newAccountIdent(addrHash))
if err != nil { if err != nil {
return err return err
} }
@ -174,10 +159,50 @@ func (b *batchIndexer) finish(force bool) error {
return err return err
} }
} }
batchMu.Lock()
id.finish(batch) id.finish(batch)
batchMu.Unlock()
} }
return nil
})
}
for addrHash, slots := range b.storages {
for storageHash, idList := range slots {
eg.Go(func() error {
if !b.delete {
iw, err := newIndexWriter(b.db, newStorageIdent(addrHash, storageHash))
if err != nil {
return err
}
for _, n := range idList {
if err := iw.append(n); err != nil {
return err
}
}
batchMu.Lock()
iw.finish(batch)
batchMu.Unlock()
} else {
id, err := newIndexDeleter(b.db, newStorageIdent(addrHash, storageHash))
if err != nil {
return err
}
for _, n := range idList {
if err := id.pop(n); err != nil {
return err
}
}
batchMu.Lock()
id.finish(batch)
batchMu.Unlock()
}
return nil
})
} }
} }
if err := eg.Wait(); err != nil {
return err
}
// Update the position of last indexed state history // Update the position of last indexed state history
if !b.delete { if !b.delete {
storeIndexMetadata(batch, b.lastID) storeIndexMetadata(batch, b.lastID)