Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
rjl493456442 committed Oct 14, 2024
1 parent 15d3ece commit 5583db5
Showing 1 changed file with 37 additions and 111 deletions.
148 changes: 37 additions & 111 deletions triedb/pathdb/lookup.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,9 @@ package pathdb

import (
"fmt"
"runtime"
"sync"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/trie/trienode"
)

// lookup is an internal help structure to quickly identify
Expand Down Expand Up @@ -78,57 +75,25 @@ func (l *lookup) nodeTip(owner common.Hash, path []byte, head common.Hash) commo
return common.Hash{}
}

type task struct {
accountHash common.Hash
nodes map[string]*trienode.Node
}

// addLayer traverses all the dirty nodes within the given diff layer and links
// them into the lookup set.
func (l *lookup) addLayer(diff *diffLayer) {
defer func(now time.Time) {
lookupAddLayerTimer.UpdateSince(now)
}(time.Now())

var (
state = diff.rootHash()
lock sync.Mutex
wg sync.WaitGroup
threads = runtime.NumCPU()
)
if threads > len(diff.nodes) {
threads = len(diff.nodes)
}
tasks := make(chan task, threads)
for i := 0; i < threads; i++ {
wg.Add(1)
go func() {
defer wg.Done()

for t := range tasks {
lock.Lock()
subset := l.nodes[t.accountHash]
if subset == nil {
subset = make(map[string][]common.Hash)
l.nodes[t.accountHash] = subset
}
lock.Unlock()

// Put the layer hash at the end of the list
for path := range t.nodes {
subset[path] = append(subset[path], state)
}
}
}()
}
state := diff.rootHash()
for accountHash, nodes := range diff.nodes {
tasks <- task{
accountHash: accountHash,
nodes: nodes,
subset := l.nodes[accountHash]
if subset == nil {
subset = make(map[string][]common.Hash)
l.nodes[accountHash] = subset
}
// Put the layer hash at the end of the list
for path := range nodes {
subset[path] = append(subset[path], state)
}
}
close(tasks)
wg.Wait()
}

// removeLayer traverses all the dirty nodes within the given diff layer and
Expand All @@ -138,76 +103,37 @@ func (l *lookup) removeLayer(diff *diffLayer) error {
lookupRemoveLayerTimer.UpdateSince(now)
}(time.Now())

var (
state = diff.rootHash()
lock sync.RWMutex
wg sync.WaitGroup
err error
errOnce sync.Once
threads = 1
)
if threads > len(diff.nodes) {
threads = len(diff.nodes)
}
tasks := make(chan task, threads)
for i := 0; i < threads; i++ {
wg.Add(1)
go func() {
defer wg.Done()

for t := range tasks {
lock.RLock()
subset := l.nodes[t.accountHash]
lock.RUnlock()

if subset == nil {
errOnce.Do(func() {
err = fmt.Errorf("unknown node owner %x", t.accountHash)
})
return
}
// Traverse the list from oldest to newest to quickly locate the ID
// of the stale layer.
for path := range t.nodes {
var found bool
for j := 0; j < len(subset[path]); j++ {
if subset[path][j] == state {
if j == 0 {
subset[path] = subset[path][1:] // TODO what if the underlying slice is held forever?
} else {
subset[path] = append(subset[path][:j], subset[path][j+1:]...)
}
found = true
break
}
}
if !found {
errOnce.Do(func() {
err = fmt.Errorf("failed to delete lookup %x %v", t.accountHash, []byte(path))
})
return
}
if len(subset[path]) == 0 {
delete(subset, path)
state := diff.rootHash()
for accountHash, nodes := range diff.nodes {
subset := l.nodes[accountHash]
if subset == nil {
return fmt.Errorf("unknown node owner %x", accountHash)
}
// Traverse the list from oldest to newest to quickly locate the ID
// of the stale layer.
for path := range nodes {
var found bool
for j := 0; j < len(subset[path]); j++ {
if subset[path][j] == state {
if j == 0 {
subset[path] = subset[path][1:] // TODO what if the underlying slice is held forever?
} else {
subset[path] = append(subset[path][:j], subset[path][j+1:]...)
}
}
if len(subset) == 0 {
lock.Lock()
delete(l.nodes, t.accountHash)
lock.Unlock()
found = true
break
}
}
}()
}

for accountHash, nodes := range diff.nodes {
tasks <- task{
accountHash: accountHash,
nodes: nodes,
if !found {
return fmt.Errorf("failed to delete lookup %x %v", accountHash, []byte(path))
}
if len(subset[path]) == 0 {
delete(subset, path)
}
}
if len(subset) == 0 {
delete(l.nodes, accountHash)
}
}
close(tasks)
wg.Wait()

return err
return nil
}

0 comments on commit 5583db5

Please sign in to comment.