aboutsummaryrefslogtreecommitdiffstats
path: root/core/types
diff options
context:
space:
mode:
authorMission Liao <mission.liao@dexon.org>2018-08-28 13:13:21 +0800
committerGitHub <noreply@github.com>2018-08-28 13:13:21 +0800
commit7e9d2db5576d697b578669c935b2e7bbf9422ec7 (patch)
treee4fb9f4b95b23934a142a88ee05fbd49dff50b3c /core/types
parent9c8f9a447bfd768a7b29db904bd604410ec66a09 (diff)
downloaddexon-consensus-7e9d2db5576d697b578669c935b2e7bbf9422ec7.tar
dexon-consensus-7e9d2db5576d697b578669c935b2e7bbf9422ec7.tar.gz
dexon-consensus-7e9d2db5576d697b578669c935b2e7bbf9422ec7.tar.bz2
dexon-consensus-7e9d2db5576d697b578669c935b2e7bbf9422ec7.tar.lz
dexon-consensus-7e9d2db5576d697b578669c935b2e7bbf9422ec7.tar.xz
dexon-consensus-7e9d2db5576d697b578669c935b2e7bbf9422ec7.tar.zst
dexon-consensus-7e9d2db5576d697b578669c935b2e7bbf9422ec7.zip
core: tune performance (#73)
- Avoid using recursive function in critical path. - Do not write through when using levelDB. Things put to levelDB would be safe from panic even we didn't force to write through every time. - Dump count of confirmed blocks proposed by self. - Avoid allocating variables in loop. - Return length of acking node set, we only need that when total ordering. - Fix potential bug: make sure win records updated when acking height vectors of candidates are changed. - Keep dirty validators in slice. - Add cache for objects to ease the pressure to garbage collector. - Cache global acking status when total ordering. - Add method to recycle blocks. - Marshal JSON should be called once for each broadcast. - Make updateWinRecord called in parallel. - Log average / deviation of latencies when simulation finished.
Diffstat (limited to 'core/types')
-rw-r--r--core/types/block.go62
1 files changed, 48 insertions, 14 deletions
diff --git a/core/types/block.go b/core/types/block.go
index 92b0f8a..78548b4 100644
--- a/core/types/block.go
+++ b/core/types/block.go
@@ -22,12 +22,44 @@ package types
import (
"bytes"
"fmt"
+ "sync"
"time"
"github.com/dexon-foundation/dexon-consensus-core/common"
"github.com/dexon-foundation/dexon-consensus-core/crypto"
)
+var (
+ // blockPool is the blocks cache to reuse allocated blocks.
+ blockPool = sync.Pool{
+ New: func() interface{} {
+ return &Block{}
+ },
+ }
+)
+
+// RecycleBlock put unused block into cache, which might be reused if
+// not garbage collected.
+func RecycleBlock(b *Block) {
+ blockPool.Put(b)
+}
+
+// NewBlock initiate a block.
+func NewBlock() (b *Block) {
+ b = blockPool.Get().(*Block)
+ if b.Acks != nil {
+ for k := range b.Acks {
+ delete(b.Acks, k)
+ }
+ }
+ if b.Timestamps != nil {
+ for k := range b.Timestamps {
+ delete(b.Timestamps, k)
+ }
+ }
+ return
+}
+
// Block represents a single event broadcasted on the network.
type Block struct {
ProposerID ValidatorID `json:"proposer_id"`
@@ -71,27 +103,29 @@ func (b *Block) String() string {
}
// Clone returns a deep copy of a block.
-func (b *Block) Clone() *Block {
- bcopy := &Block{
- ProposerID: b.ProposerID,
- ParentHash: b.ParentHash,
- Hash: b.Hash,
- Height: b.Height,
- Timestamps: make(map[ValidatorID]time.Time),
- Acks: make(map[common.Hash]struct{}),
- Signature: b.Signature.Clone(),
- Notary: Notary{
- Timestamp: b.Notary.Timestamp,
- Height: b.Notary.Height,
- },
+func (b *Block) Clone() (bcopy *Block) {
+ bcopy = NewBlock()
+ bcopy.ProposerID = b.ProposerID
+ bcopy.ParentHash = b.ParentHash
+ bcopy.Hash = b.Hash
+ bcopy.Height = b.Height
+ bcopy.Signature = b.Signature.Clone()
+ bcopy.Notary.Timestamp = b.Notary.Timestamp
+ bcopy.Notary.Height = b.Notary.Height
+ if bcopy.Timestamps == nil {
+ bcopy.Timestamps = make(
+ map[ValidatorID]time.Time, len(b.Timestamps))
}
for k, v := range b.Timestamps {
bcopy.Timestamps[k] = v
}
+ if bcopy.Acks == nil {
+ bcopy.Acks = make(map[common.Hash]struct{}, len(b.Acks))
+ }
for k, v := range b.Acks {
bcopy.Acks[k] = v
}
- return bcopy
+ return
}
// IsGenesis checks if the block is a genesisBlock