Step 01 — Cluster and log
Goal
Define the three core types — Op, LogEntry, Node — and the
container Cluster that holds three nodes. No replication yet; the
leader appends to its own log only.
Tasks
- Define
OpKindasPut | DelandOp { kind, k: i64, v: i64 }. - Define
LogEntry { term: u64, index: u64, op: Op }. - Define
Node { id: u8, term: u64, commit_index: u64, last_applied: u64, log: Vec<LogEntry>, kv: Map<i64,i64> }. - Implement
Node::appendrequiringentry.index == log.len() + 1, with idempotent re-acceptance of an already-present index (used later bycatch_up). - Implement
Node::apply_committed: whilelast_applied < commit_index, applylog[last_applied]tokvand increment. - Implement
Node::encodewith the canonical wire format from CONCEPTS.md. - Implement
Cluster::newwith three nodes (ids 0, 1, 2) all marked up, andCluster::encode_snapshot= concat of all three encodings.
Acceptance
snapshot_layout_smoketest passes in all three languages.- An empty cluster's snapshot has length
3 × (8+1+8+8+4+4) = 99bytes.
Pitfalls
- Go map iteration order is undefined — sort keys before encoding.
std::map(ordered) in C++, NOTstd::unordered_map.- All multi-byte ints are little-endian.
vfor aDelop encodes as0.