Skip to content

Commit

Permalink
Dont allocate channel and encoding buf on each proposal
Browse files Browse the repository at this point in the history
I had wanted to avoid this because Cockroach has both of these
allocations, but for the sake of clean profiles, this makes sense
to do.
  • Loading branch information
nvanbenschoten committed Apr 26, 2019
1 parent b62588c commit a417bc7
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 14 deletions.
5 changes: 4 additions & 1 deletion bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,14 @@ func benchmarkRaft(b *testing.B, conc, bytes int) {
Key: append(keyPrefix, make([]byte, 8)...),
Val: propBytes,
}
encBuf := make([]byte, proposal.Size(prop))
c := make(chan bool, 1)

iters := b.N / conc
for j := 0; j < iters; j++ {
rng.Read(prop.Key[len(keyPrefix):])
if !p.Propose(prop) {
enc := proposal.EncodeInto(prop, encBuf)
if !p.ProposeWith(enc, c) {
return errors.New("proposal failed")
}
}
Expand Down
10 changes: 7 additions & 3 deletions peer/peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,13 @@ func (p *Peer) Campaign() {

// Propose proposes the provided update to the Raft state machine.
func (p *Peer) Propose(prop proposal.Proposal) bool {
prop.ID = atomic.AddInt64(&p.pi, 1)
enc := proposal.Encode(prop)
c := make(chan bool, 1)
return p.ProposeWith(proposal.Encode(prop), make(chan bool, 1))
}

// ProposeWith proposes the provided encoded update to the Raft
// state machine. Channel c is expected to have a capacity of 1.
func (p *Peer) ProposeWith(enc proposal.EncProposal, c chan bool) bool {
enc.SetID(atomic.AddInt64(&p.pi, 1))
el := propBufElem{enc, c}

p.pb.add(el)
Expand Down
34 changes: 24 additions & 10 deletions proposal/proposal.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,38 @@ func (enc EncProposal) GetID() int64 {
return getInt64(enc[:8])
}

// Encode maps a Proposal to an EncProposal.
func Encode(p Proposal) EncProposal {
enc := make([]byte, 3*8+len(p.Key)+len(p.Val))
// Size returns the size that the Proposal will be when encoded.
func Size(p Proposal) int {
return 3*8+len(p.Key)+len(p.Val)
}

// EncodeInto maps a Proposal to an EncProposal
// in an existing byte slice.
func EncodeInto(p Proposal, b []byte) EncProposal {
if len(b) != Size(p) {
panic("size mismatch")
}
n := 0
putInt64(enc[n:n+8], p.ID)
putInt64(b[n:n+8], p.ID)
n += 8
putInt64(enc[n:n+8], int64(len(p.Key)))
putInt64(b[n:n+8], int64(len(p.Key)))
n += 8
copy(enc[n:n+len(p.Key)], p.Key)
copy(b[n:n+len(p.Key)], p.Key)
n += len(p.Key)
putInt64(enc[n:n+8], int64(len(p.Val)))
putInt64(b[n:n+8], int64(len(p.Val)))
n += 8
copy(enc[n:n+len(p.Val)], p.Val)
copy(b[n:n+len(p.Val)], p.Val)
n += len(p.Val)
if n != len(enc) {
if n != len(b) {
panic("accounting error")
}
return enc
return b
}

// Encode maps a Proposal to an EncProposal.
func Encode(p Proposal) EncProposal {
b := make([]byte, Size(p))
return EncodeInto(p, b)
}

// Decode maps an EncProposal to a Proposal.
Expand Down

0 comments on commit a417bc7

Please sign in to comment.