BitArray takes a pointer receiver. More logging

This commit is contained in:
Jae Kwon 2015-05-05 22:53:06 -07:00
parent 44076e816d
commit da73e001ad
6 changed files with 59 additions and 55 deletions

View File

@ -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)<<lastElemBits)-1) == 0
}
func (bA BitArray) PickRandom() (uint, bool) {
func (bA *BitArray) PickRandom() (uint, bool) {
bA.mtx.Lock()
defer bA.mtx.Unlock()
@ -209,20 +204,23 @@ func (bA BitArray) PickRandom() (uint, bool) {
return 0, false
}
func (bA BitArray) String() string {
func (bA *BitArray) String() string {
if bA == nil {
return "nil-BitArray"
}
bA.mtx.Lock()
defer bA.mtx.Unlock()
return bA.stringIndented("")
}
func (bA BitArray) StringIndented(indent string) string {
func (bA *BitArray) StringIndented(indent string) string {
bA.mtx.Lock()
defer bA.mtx.Unlock()
return bA.StringIndented(indent)
}
func (bA BitArray) stringIndented(indent string) string {
func (bA *BitArray) stringIndented(indent string) string {
lines := []string{}
bits := ""

View File

@ -4,7 +4,7 @@ import (
"testing"
)
func randBitArray(bits uint) (BitArray, []byte) {
func randBitArray(bits uint) (*BitArray, []byte) {
src := RandBytes(int((bits + 7) / 8))
bA := NewBitArray(bits)
for i := uint(0); i < uint(len(src)); i++ {

View File

@ -442,7 +442,7 @@ OUTER_LOOP:
sleeping = 0
}
trySendVote := func(voteSet *VoteSet, peerVoteSet BitArray) (sent bool) {
trySendVote := func(voteSet *VoteSet, peerVoteSet *BitArray) (sent bool) {
if prs.Height == voteSet.Height() {
// Initialize Prevotes/Precommits/Commits if needed
ps.EnsureVoteBitArrays(prs.Height, voteSet.Size())
@ -460,7 +460,7 @@ OUTER_LOOP:
return false
}
trySendCommitFromValidation := func(blockMeta *types.BlockMeta, validation *types.Validation, peerVoteSet BitArray) (sent bool) {
trySendCommitFromValidation := func(blockMeta *types.BlockMeta, validation *types.Validation, peerVoteSet *BitArray) (sent bool) {
// Initialize Commits if needed
ps.EnsureVoteBitArrays(prs.Height, uint(len(validation.Commits)))
@ -588,13 +588,13 @@ type PeerRoundState struct {
StartTime time.Time // Estimated start of round 0 at this height
Proposal bool // True if peer has proposal for this round
ProposalBlockParts types.PartSetHeader //
ProposalBlockBitArray BitArray // True bit -> 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 {

View File

@ -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()

View File

@ -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())

View File

@ -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()