-
Notifications
You must be signed in to change notification settings - Fork 206
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
update trie on goroutines #6463
update trie on goroutines #6463
Conversation
trie/branchNode.go
Outdated
newModifiedHashes, bnModified := bn.insertOnChild(dataForInsertion[childPos], childPos, goRoutinesManager, db) | ||
if bnModified { | ||
bnHasBeenModified.SetValue(true) | ||
} | ||
if len(newModifiedHashes) != 0 { | ||
hashesMutex.Lock() | ||
modifiedHashes = append(modifiedHashes, newModifiedHashes...) | ||
hashesMutex.Unlock() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not a strong opinion on this, but we might consider extracting this block to a function even if there are a lot of parameters to pass
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, will extract in a different function in order to avoid duplicated code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactored
trie/branchNode.go
Outdated
func (bn *branchNode) deleteChild( | ||
dataForRemoval []core.TrieData, | ||
childPos int, | ||
hasBeenModified *atomic.Flag, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return hasBeenModified
as a variable similar to insertOnChild
and set atomic flag as in insert
case? this way the dataForInsertion(Removal) flows are very similar, they might be able to be extracted in a common function or component since insetOnChild
and deleteChild
would have the same singature
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactored.
bn.mutex.Lock() | ||
defer bn.mutex.Unlock() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for which variable(s) is the lock? i think we need to add lock also in other places
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are for dirty, hash, version. Indeed, this will need to be added in other places. Will do that in another PR, in which I will also write some tests for this cases.
trie/branchNode_test.go
Outdated
th, _ := throttler.NewNumGoRoutinesThrottler(5) | ||
goRoutinesManager, err := NewGoroutinesManager(th, errChan.NewErrChanWrapper(), make(chan struct{})) | ||
assert.Nil(t, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add a function for creating goroutinesManager?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
gm.mutex.Lock() | ||
defer gm.mutex.Unlock() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need mutex here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, because the same manager will be passed on multiple goroutines.
gm.mutex.Lock() | ||
defer gm.mutex.Unlock() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here also?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, because the same manager will be passed on multiple goroutines.
trie/goroutinesManager_test.go
Outdated
|
||
err = errCh.ReadFromChanNonBlocking() | ||
assert.Equal(t, expectedErr, err) | ||
assert.False(t, manager.(*goroutinesManager).canProcess) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe better expose canProcess
in export_test.go to avoid casting here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, the problem was that the constructor was returning an interface, not the actual type. Changed the constructor.
…ate-trie-on-goroutines # Conflicts: # trie/branchNode_test.go # trie/extensionNode_test.go
common/modifiedHashes.go
Outdated
// NewModifiedHashesSlice is used to create a new instance of modifiedHashesSlice | ||
func NewModifiedHashesSlice() *modifiedHashesSlice { | ||
return &modifiedHashesSlice{ | ||
hashes: make([][]byte, 0), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better to allocate some capacity to the hashes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -80,6 +83,12 @@ func NewTrie( | |||
return nil, err | |||
} | |||
|
|||
// TODO give this as an argument | |||
trieThrottler, err := throttler.NewNumGoRoutinesThrottler(20) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
only the config of how many go routines is enough for the arg.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that is what I was also thinking, but phrased it wrong. Rephrased the TODO. It will be implemented in a future PR.
trie/patriciaMerkleTrie.go
Outdated
@@ -203,7 +213,14 @@ func (tr *patriciaMerkleTrie) insertBatch(sortedDataForInsertion []core.TrieData | |||
tr.oldRoot = tr.root.getHash() | |||
} | |||
|
|||
newRoot, oldHashes, err := tr.root.insert(sortedDataForInsertion, tr.trieStorage) | |||
manager, err := NewGoroutinesManager(tr.goroutinesThrottler, errChan.NewErrChanWrapper(), tr.chanClose) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you need to recreate this manager every time ?
can't you create it once and only clean up here ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
trie/patriciaMerkleTrie.go
Outdated
@@ -232,11 +250,20 @@ func (tr *patriciaMerkleTrie) deleteBatch(data []core.TrieData) error { | |||
tr.oldRoot = tr.root.getHash() | |||
} | |||
|
|||
_, newRoot, oldHashes, err := tr.root.delete(data, tr.trieStorage) | |||
manager, err := NewGoroutinesManager(tr.goroutinesThrottler, errChan.NewErrChanWrapper(), tr.chanClose) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above ? can't you have the manager created once, and only clean it up here ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
common/modifiedHashes.go
Outdated
mhs.Lock() | ||
defer mhs.Unlock() | ||
|
||
mhs.hashes = nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
set to empty slice as in constructor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed func as it was not used anywhere. Will add it again if needed.
common/modifiedHashes_test.go
Outdated
assert.NotEqual(t, retrievedHashes, newRetrievedHashes) | ||
} | ||
|
||
func TestModifiedHashesSlice_Reset(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add a test with all these operations combined? append, reset, append
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed the Reset() func
@@ -1,5 +1,7 @@ | |||
package common | |||
|
|||
import "sync" | |||
|
|||
// ModifiedHashes is used to memorize all old hashes and new hashes from when a trie is committed | |||
type ModifiedHashes map[string]struct{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we still need this struct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is still used in other places.
The base branch was changed.
Reasoning behind the pull request
Proposed changes
Pre-requisites
Based on the Contributing Guidelines the PR author and the reviewers must check the following requirements are met:
feat
branch created?feat
branch merging, do all satellite projects have a proper tag insidego.mod
?