Skip to content
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

performance: cache the ID for Header entities #1279

Merged
merged 22 commits into from
Sep 16, 2021
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ func Test_AsyncUploader(t *testing.T) {
require.Equal(t, 3, callCount)
})

time.Sleep(1 * time.Second)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this added by accident?


jwinkler2083233 marked this conversation as resolved.
Show resolved Hide resolved
t.Run("stopping component stops retrying", func(t *testing.T) {

callCount := 0
Expand Down
6 changes: 5 additions & 1 deletion ledger/complete/wal/compactor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ func Test_Compactor(t *testing.T) {
select {
case <-co.done:
// continue
case <-time.After(20 * time.Second):
case <-time.After(70 * time.Second):
jwinkler2083233 marked this conversation as resolved.
Show resolved Hide resolved
assert.FailNow(t, "timed out")
}

Expand All @@ -138,6 +138,8 @@ func Test_Compactor(t *testing.T) {
require.NoError(t, err)
})

time.Sleep(2 * time.Second)

t.Run("remove unnecessary files", func(t *testing.T) {
// Remove all files apart from target checkpoint and WAL segments ahead of it
// We know their names, so just hardcode them
Expand All @@ -159,6 +161,8 @@ func Test_Compactor(t *testing.T) {
f2, err := mtrie.NewForest(size*10, metricsCollector, func(tree *trie.MTrie) error { return nil })
require.NoError(t, err)

time.Sleep(2 * time.Second)

t.Run("load data from checkpoint and WAL", func(t *testing.T) {
wal2, err := NewDiskWAL(zerolog.Nop(), nil, metrics.NewNoopCollector(), dir, size*10, pathByteSize, 32*1024)
require.NoError(t, err)
Expand Down
58 changes: 57 additions & 1 deletion model/flow/header.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package flow

import (
"bytes"
"encoding/json"
"sync"
"time"

"github.com/fxamacker/cbor/v2"
Expand Down Expand Up @@ -72,6 +74,10 @@ func (h Header) Fingerprint() []byte {
return fingerprint.Fingerprint(h.Body())
}

var mutex_hdr sync.Mutex
var previd_hdr Identifier
var prev_hdr Header
jwinkler2083233 marked this conversation as resolved.
Show resolved Hide resolved
jwinkler2083233 marked this conversation as resolved.
Show resolved Hide resolved

// ID returns a unique ID to singularly identify the header and its block
// within the flow system.
func (h Header) ID() Identifier {
Expand All @@ -80,7 +86,57 @@ func (h Header) ID() Identifier {
if h.Timestamp.Location() != time.UTC {
h.Timestamp = h.Timestamp.UTC()
}
return MakeID(h)

mutex_hdr.Lock()

// unlock at the return
defer mutex_hdr.Unlock()

for {
// compare these elements individually
if prev_hdr.ParentVoterIDs == nil ||
prev_hdr.ParentVoterSigData == nil ||
prev_hdr.ProposerSigData == nil ||
len(h.ParentVoterIDs) != len(prev_hdr.ParentVoterIDs) ||
len(h.ParentVoterSigData) != len(prev_hdr.ParentVoterSigData) ||
len(h.ProposerSigData) != len(prev_hdr.ProposerSigData) {
break
}
bNotEqual := false
if len(h.ParentVoterIDs) > 0 {
for i, v := range h.ParentVoterIDs {
jwinkler2083233 marked this conversation as resolved.
Show resolved Hide resolved
if v == prev_hdr.ParentVoterIDs[i] {
continue
}
bNotEqual = true
break
}
}

if !bNotEqual &&
h.ChainID == prev_hdr.ChainID &&
h.Timestamp == prev_hdr.Timestamp &&
h.Height == prev_hdr.Height &&
h.ParentID == prev_hdr.ParentID &&
h.View == prev_hdr.View &&
h.PayloadHash == prev_hdr.PayloadHash &&
bytes.Equal(h.ProposerSigData, prev_hdr.ProposerSigData) &&
bytes.Equal(h.ParentVoterSigData, prev_hdr.ParentVoterSigData) &&
h.ProposerID == prev_hdr.ProposerID {

// cache hit, return the previous identifier
return previd_hdr
}
// exit the for loop
break
}
jwinkler2083233 marked this conversation as resolved.
Show resolved Hide resolved

previd_hdr = MakeID(h)

// store a reference to the Header entity data
prev_hdr = h

return previd_hdr
}

// Checksum returns the checksum of the header.
Expand Down