Skip to content

Commit

Permalink
fix(trie): do not get buffer for nil child
Browse files Browse the repository at this point in the history
  • Loading branch information
qdm12 committed Nov 8, 2022
1 parent 7131290 commit 9565ef5
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 21 deletions.
48 changes: 28 additions & 20 deletions internal/trie/node/branch_encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,12 @@ func encodeChildrenOpportunisticParallel(children []*Node, buffer io.Writer) (er
resultsCh := make(chan encodingAsyncResult, ChildrenCapacity)

for i, child := range children {
if child == nil || child.Kind() == Leaf {
if child == nil {
resultsCh <- encodingAsyncResult{index: i}
continue
}

if child.Kind() == Leaf {
runEncodeChild(child, i, resultsCh, nil)
continue
}
Expand All @@ -74,19 +79,30 @@ func encodeChildrenOpportunisticParallel(children []*Node, buffer io.Writer) (er
}

currentIndex := 0
resultBuffers := make([]*bytes.Buffer, ChildrenCapacity)
indexToBuffer := make(map[int]*bytes.Buffer, ChildrenCapacity)
for range children {
result := <-resultsCh
if result.err != nil && err == nil { // only set the first error we get
err = result.err
}

resultBuffers[result.index] = result.buffer
indexToBuffer[result.index] = result.buffer

// write as many completed buffers to the result buffer.
for currentIndex < ChildrenCapacity &&
resultBuffers[currentIndex] != nil {
bufferSlice := resultBuffers[currentIndex].Bytes()
for currentIndex < ChildrenCapacity {
resultBuffer, done := indexToBuffer[currentIndex]
if !done {
break
}

nilChildNode := resultBuffer == nil
if nilChildNode {
delete(indexToBuffer, currentIndex)
currentIndex++
continue
}

bufferSlice := resultBuffer.Bytes()
if err == nil && len(bufferSlice) > 0 {
// note buffer.Write copies the byte slice given as argument
_, writeErr := buffer.Write(bufferSlice)
Expand All @@ -97,25 +113,21 @@ func encodeChildrenOpportunisticParallel(children []*Node, buffer io.Writer) (er
}
}

pools.EncodingBuffers.Put(resultBuffers[currentIndex])
resultBuffers[currentIndex] = nil

pools.EncodingBuffers.Put(resultBuffer)
delete(indexToBuffer, currentIndex)
currentIndex++
}
}

for _, buffer := range resultBuffers {
if buffer == nil { // already emptied and put back in pool
continue
}
pools.EncodingBuffers.Put(buffer)
}

return err
}

func encodeChildrenSequentially(children []*Node, buffer io.Writer) (err error) {
for i, child := range children {
if child == nil {
continue
}

err = encodeChild(child, buffer)
if err != nil {
return fmt.Errorf("cannot encode child at index %d: %w", i, err)
Expand All @@ -125,10 +137,6 @@ func encodeChildrenSequentially(children []*Node, buffer io.Writer) (err error)
}

func encodeChild(child *Node, buffer io.Writer) (err error) {
if child == nil {
return nil
}

scaleEncodedChildHash, err := scaleEncodeHash(child)
if err != nil {
return fmt.Errorf("failed to hash and scale encode child: %w", err)
Expand Down
1 change: 0 additions & 1 deletion internal/trie/node/branch_encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,6 @@ func Test_encodeChild(t *testing.T) {
wrappedErr error
errMessage string
}{
"nil node": {},
"empty branch child": {
child: &Node{
Children: make([]*Node, ChildrenCapacity),
Expand Down

0 comments on commit 9565ef5

Please # to comment.