Skip to content

Commit

Permalink
asynchronous update snap in updatetrie
Browse files Browse the repository at this point in the history
  • Loading branch information
flywukong committed May 23, 2022
1 parent 2f2b98a commit 3563a29
Showing 1 changed file with 38 additions and 18 deletions.
56 changes: 38 additions & 18 deletions core/state/state_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,41 +390,61 @@ func (s *StateObject) updateTrie(db Database) Trie {
s.db.MetricsMux.Unlock()
}(time.Now())
}
// The snapshot storage map for the object
var storage map[string][]byte
// Insert all the pending updates into the trie
tr := s.getTrie(db)

usedStorage := make([][]byte, 0, len(s.pendingStorage))
dirtyStorage := make(map[common.Hash][]byte)
for key, value := range s.pendingStorage {
// Skip noop changes, persist actual changes
if value == s.originStorage[key] {
continue
}
s.originStorage[key] = value
var v []byte
if (value == common.Hash{}) {
s.setError(tr.TryDelete(key[:]))
} else {
if (value != common.Hash{}) {
// Encoding []byte cannot fail, ok to ignore the error.
v, _ = rlp.EncodeToBytes(common.TrimLeftZeroes(value[:]))
s.setError(tr.TryUpdate(key[:], v))
}
// If state snapshotting is active, cache the data til commit
if s.db.snap != nil {
s.db.snapMux.Lock()
if storage == nil {
// Retrieve the old storage map, if available, create a new one otherwise
if storage = s.db.snapStorage[s.address]; storage == nil {
storage = make(map[string][]byte)
s.db.snapStorage[s.address] = storage
dirtyStorage[key] = v
}
var wg sync.WaitGroup
wg.Add(2)

go func() {
defer wg.Done()
for key, value := range dirtyStorage {
if len(value) == 0 {
s.setError(tr.TryDelete(key[:]))
} else {
s.setError(tr.TryUpdate(key[:], value))
}
}
}()
go func() {
defer wg.Done()
// The snapshot storage map for the object
var storage map[string][]byte
for key, value := range dirtyStorage {
// If state snapshotting is active, cache the data til commit
if s.db.snap != nil {
s.db.snapMux.Lock()
if storage == nil {
// Retrieve the old storage map, if available, create a new one otherwise
if storage = s.db.snapStorage[s.address]; storage == nil {
storage = make(map[string][]byte)
s.db.snapStorage[s.address] = storage
}
}

storage[string(key[:])] = value // value will be nil if value is 0x00
s.db.snapMux.Unlock()
}
storage[string(key[:])] = v // v will be nil if value is 0x00
s.db.snapMux.Unlock()
usedStorage = append(usedStorage, common.CopyBytes(key[:])) // Copy needed for closure
}
usedStorage = append(usedStorage, common.CopyBytes(key[:])) // Copy needed for closure
}
}()
wg.Wait()

if s.db.prefetcher != nil {
s.db.prefetcher.used(s.data.Root, usedStorage)
}
Expand Down

0 comments on commit 3563a29

Please sign in to comment.