WriteBatch gets created internally in a storage.Batch
// instance 1
The impl actually copies, womp womp (the batch reuses the original memory but still): // instance 2
Aside: If we kept the batch around with the proposal, we could conceivably use its backing memory. We could also apply the batch directly, possibly saving overhead on the leaseholder.
This is now sitting on a kvserverpb.RaftCommand
:
We then marshal the RaftCommand
, i.e. allocate and write: // instance 3
But we're not done yet! Because raft needs a raftpb.Entry
:
When we've given this to raft and it hands it back to us for appending to the log, we need to marshal this entry:
but we're not done there, because we'll write this via an inline put, i.e. the data goes here
and we still need to marshal that: // instance 5
(No allocation here usually - it's pooled - but we're still copying it around).
Are done yet? No! We have to send the entry to followers as well. It will be contained in a message here (concretely, in the Entries slice of a raftpb.Message
within:
and of course to be send over the wire it will need to be marshaled again (inside of gRPC), and the result copied into a network buffer. // instance 6+7
Also, we usually have two followers, not just one. // instance 8+9
We haven't applied the command yet... that will need to happen too!
calls through to unmarshal: // instance 10
There are additional copies if the raftentry cache forces us to ever fetch the entry from disk, since then we need to unmarshal first the raftpb.Entry
and then from it the kvserverpb.RaftCommand
.