From da73e001ad929a56987bbcc57fe7a0c63139a0f9 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Tue, 5 May 2015 22:53:06 -0700 Subject: [PATCH] BitArray takes a pointer receiver. More logging --- common/bit_array.go | 52 +++++++++++++++++++--------------------- common/bit_array_test.go | 2 +- consensus/reactor.go | 44 +++++++++++++++++++--------------- consensus/vote_set.go | 6 ++--- types/block.go | 6 ++--- types/part_set.go | 4 ++-- 6 files changed, 59 insertions(+), 55 deletions(-) diff --git a/common/bit_array.go b/common/bit_array.go index 62a4ef976..119b6351f 100644 --- a/common/bit_array.go +++ b/common/bit_array.go @@ -13,30 +13,26 @@ type BitArray struct { Elems []uint64 // NOTE: persisted via reflect, must be exported } -func NewBitArray(bits uint) BitArray { - return BitArray{ +func NewBitArray(bits uint) *BitArray { + return &BitArray{ Bits: bits, Elems: make([]uint64, (bits+63)/64), } } -func (bA BitArray) Size() uint { +func (bA *BitArray) Size() uint { return bA.Bits } -func (bA BitArray) IsZero() bool { - return bA.Bits == 0 -} - // NOTE: behavior is undefined if i >= bA.Bits -func (bA BitArray) GetIndex(i uint) bool { +func (bA *BitArray) GetIndex(i uint) bool { bA.mtx.Lock() defer bA.mtx.Unlock() return bA.getIndex(i) } -func (bA BitArray) getIndex(i uint) bool { +func (bA *BitArray) getIndex(i uint) bool { if i >= bA.Bits { return false } @@ -44,15 +40,14 @@ func (bA BitArray) getIndex(i uint) bool { } // NOTE: behavior is undefined if i >= bA.Bits -func (bA BitArray) SetIndex(i uint, v bool) bool { +func (bA *BitArray) SetIndex(i uint, v bool) bool { bA.mtx.Lock() defer bA.mtx.Unlock() return bA.setIndex(i, v) } -func (bA BitArray) setIndex(i uint, v bool) bool { - +func (bA *BitArray) setIndex(i uint, v bool) bool { if i >= bA.Bits { return false } @@ -64,32 +59,32 @@ func (bA BitArray) setIndex(i uint, v bool) bool { return true } -func (bA BitArray) Copy() BitArray { +func (bA *BitArray) Copy() *BitArray { bA.mtx.Lock() defer bA.mtx.Unlock() return bA.copy() } -func (bA BitArray) copy() BitArray { +func (bA *BitArray) copy() *BitArray { c := make([]uint64, len(bA.Elems)) copy(c, bA.Elems) - return BitArray{ + return &BitArray{ Bits: bA.Bits, Elems: c, } } -func (bA BitArray) copyBits(bits uint) BitArray { +func (bA *BitArray) copyBits(bits uint) *BitArray { c := make([]uint64, (bits+63)/64) copy(c, bA.Elems) - return BitArray{ + return &BitArray{ Bits: bits, Elems: c, } } // Returns a BitArray of larger bits size. -func (bA BitArray) Or(o BitArray) BitArray { +func (bA *BitArray) Or(o *BitArray) *BitArray { bA.mtx.Lock() defer bA.mtx.Unlock() @@ -101,14 +96,14 @@ func (bA BitArray) Or(o BitArray) BitArray { } // Returns a BitArray of smaller bit size. -func (bA BitArray) And(o BitArray) BitArray { +func (bA *BitArray) And(o *BitArray) *BitArray { bA.mtx.Lock() defer bA.mtx.Unlock() return bA.and(o) } -func (bA BitArray) and(o BitArray) BitArray { +func (bA *BitArray) and(o *BitArray) *BitArray { c := bA.copyBits(MinUint(bA.Bits, o.Bits)) for i := 0; i < len(c.Elems); i++ { c.Elems[i] &= o.Elems[i] @@ -116,7 +111,7 @@ func (bA BitArray) and(o BitArray) BitArray { return c } -func (bA BitArray) Not() BitArray { +func (bA *BitArray) Not() *BitArray { bA.mtx.Lock() defer bA.mtx.Unlock() @@ -127,7 +122,7 @@ func (bA BitArray) Not() BitArray { return c } -func (bA BitArray) Sub(o BitArray) BitArray { +func (bA *BitArray) Sub(o *BitArray) *BitArray { bA.mtx.Lock() defer bA.mtx.Unlock() @@ -148,7 +143,7 @@ func (bA BitArray) Sub(o BitArray) BitArray { } } -func (bA BitArray) IsFull() bool { +func (bA *BitArray) IsFull() bool { bA.mtx.Lock() defer bA.mtx.Unlock() @@ -169,7 +164,7 @@ func (bA BitArray) IsFull() bool { return (lastElem+1)&((uint64(1)< has part + ProposalBlockBitArray *BitArray // True bit -> has part ProposalPOLParts types.PartSetHeader // - ProposalPOLBitArray BitArray // True bit -> has part - Prevotes BitArray // All votes peer has for this round - Precommits BitArray // All precommits peer has for this round - Commits BitArray // All commits peer has for this height - LastCommits BitArray // All commits peer has for last height + ProposalPOLBitArray *BitArray // True bit -> has part + Prevotes *BitArray // All votes peer has for this round + Precommits *BitArray // All precommits peer has for this round + Commits *BitArray // All commits peer has for this height + LastCommits *BitArray // All commits peer has for last height HasAllCatchupCommits bool // Used for catch-up } @@ -606,12 +606,14 @@ var ( ) type PeerState struct { + Key string + mtx sync.Mutex PeerRoundState } func NewPeerState(peer *p2p.Peer) *PeerState { - return &PeerState{} + return &PeerState{Key: peer.Key} } // Returns an atomic snapshot of the PeerRoundState. @@ -672,13 +674,13 @@ func (ps *PeerState) EnsureVoteBitArrays(height uint, numValidators uint) { return } - if ps.Prevotes.IsZero() { + if ps.Prevotes == nil { ps.Prevotes = NewBitArray(numValidators) } - if ps.Precommits.IsZero() { + if ps.Precommits == nil { ps.Precommits = NewBitArray(numValidators) } - if ps.Commits.IsZero() { + if ps.Commits == nil { ps.Commits = NewBitArray(numValidators) } } @@ -694,6 +696,7 @@ func (ps *PeerState) setHasVote(height uint, round uint, type_ byte, index uint) if ps.Height == height+1 && type_ == types.VoteTypeCommit { // Special case for LastCommits. ps.LastCommits.SetIndex(index, true) + log.Debug("SetHasVote", "lastCommits", ps.LastCommits, "index", index) return } else if ps.Height != height { // Does not apply. @@ -703,14 +706,17 @@ func (ps *PeerState) setHasVote(height uint, round uint, type_ byte, index uint) switch type_ { case types.VoteTypePrevote: ps.Prevotes.SetIndex(index, true) + log.Debug("SetHasVote", "peer", ps.Key, "prevotes", ps.Prevotes, "index", index) case types.VoteTypePrecommit: ps.Precommits.SetIndex(index, true) + log.Debug("SetHasVote", "peer", ps.Key, "precommits", ps.Precommits, "index", index) case types.VoteTypeCommit: if round < ps.Round { ps.Prevotes.SetIndex(index, true) ps.Precommits.SetIndex(index, true) } ps.Commits.SetIndex(index, true) + log.Debug("SetHasVote", "peer", ps.Key, "commits", ps.Commits, "index", index) default: panic("Invalid vote type") } @@ -744,22 +750,22 @@ func (ps *PeerState) ApplyNewRoundStepMessage(msg *NewRoundStepMessage, rs *Roun if psHeight != msg.Height || psRound != msg.Round { ps.Proposal = false ps.ProposalBlockParts = types.PartSetHeader{} - ps.ProposalBlockBitArray = BitArray{} + ps.ProposalBlockBitArray = nil ps.ProposalPOLParts = types.PartSetHeader{} - ps.ProposalPOLBitArray = BitArray{} + ps.ProposalPOLBitArray = nil // We'll update the BitArray capacity later. - ps.Prevotes = BitArray{} - ps.Precommits = BitArray{} + ps.Prevotes = nil + ps.Precommits = nil } if psHeight != msg.Height { // Shift Commits to LastCommits if psHeight+1 == msg.Height { ps.LastCommits = ps.Commits } else { - ps.LastCommits = BitArray{} + ps.LastCommits = nil } // We'll update the BitArray capacity later. - ps.Commits = BitArray{} + ps.Commits = nil ps.HasAllCatchupCommits = false } } @@ -842,7 +848,7 @@ func (m *NewRoundStepMessage) String() string { type CommitStepMessage struct { Height uint BlockParts types.PartSetHeader - BlockBitArray BitArray + BlockBitArray *BitArray } func (m *CommitStepMessage) String() string { diff --git a/consensus/vote_set.go b/consensus/vote_set.go index 960e8f070..fafee1d44 100644 --- a/consensus/vote_set.go +++ b/consensus/vote_set.go @@ -26,7 +26,7 @@ type VoteSet struct { mtx sync.Mutex valSet *sm.ValidatorSet votes []*types.Vote // validator index -> vote - votesBitArray BitArray // validator index -> has vote? + votesBitArray *BitArray // validator index -> has vote? votesByBlock map[string]uint64 // string(blockHash)+string(blockParts) -> vote sum. totalVotes uint64 maj23Hash []byte @@ -148,9 +148,9 @@ func (voteSet *VoteSet) AddFromCommits(commits *VoteSet) { } } -func (voteSet *VoteSet) BitArray() BitArray { +func (voteSet *VoteSet) BitArray() *BitArray { if voteSet == nil { - return BitArray{} + return nil } voteSet.mtx.Lock() defer voteSet.mtx.Unlock() diff --git a/types/block.go b/types/block.go index 295ba8500..bb0decc4a 100644 --- a/types/block.go +++ b/types/block.go @@ -201,7 +201,7 @@ type Validation struct { // Volatile hash []byte - bitArray BitArray + bitArray *BitArray } func (v *Validation) ValidateBasic() error { @@ -254,8 +254,8 @@ func (v *Validation) StringIndented(indent string) string { indent, v.hash) } -func (v *Validation) BitArray() BitArray { - if v.bitArray.IsZero() { +func (v *Validation) BitArray() *BitArray { + if v.bitArray == nil { v.bitArray = NewBitArray(uint(len(v.Commits))) for i, commit := range v.Commits { v.bitArray.SetIndex(uint(i), !commit.IsZero()) diff --git a/types/part_set.go b/types/part_set.go index 66988b0ef..0868724e9 100644 --- a/types/part_set.go +++ b/types/part_set.go @@ -97,7 +97,7 @@ type PartSet struct { mtx sync.Mutex parts []*Part - partsBitArray BitArray + partsBitArray *BitArray count uint } @@ -162,7 +162,7 @@ func (ps *PartSet) HasHeader(header PartSetHeader) bool { } } -func (ps *PartSet) BitArray() BitArray { +func (ps *PartSet) BitArray() *BitArray { ps.mtx.Lock() defer ps.mtx.Unlock() return ps.partsBitArray.Copy()