// // support for Raft and kvraft to save persistent // Raft state (log &c) and k/v server snapshots. // // we will use the original persister.go to test your code for grading. // so, while you can modify this code to help you debug, please // test with the original before submitting. //
import"sync"
type Persister struct { mu sync.Mutex raftstate []byte snapshot []byte }
// Save both Raft state and K/V snapshot as a single atomic action, // to help avoid them getting out of sync. func(ps *Persister) Save(raftstate []byte, snapshot []byte) { ps.mu.Lock() defer ps.mu.Unlock() ps.raftstate = clone(raftstate) ps.snapshot = clone(snapshot) }
// save Raft's persistent state to stable storage, // where it can later be retrieved after a crash and restart. // see paper's Figure 2 for a description of what should be persistent. func(rf *Raft) persist() { // Your code here (2C). // Example: w := new(bytes.Buffer) e := labgob.NewEncoder(w) e.Encode(rf.currentTerm) e.Encode(rf.votedFor) e.Encode(rf.logs) data := w.Bytes() rf.persister.SaveRaftState(data) }
// restore previously persisted state. func(rf *Raft) readPersist(data []byte) { if data == nil || len(data) < 1 { // bootstrap without any state? return } // Your code here (2C). // Example: r := bytes.NewBuffer(data) d := labgob.NewDecoder(r) var currentTerm int var votedFor int var logs []LogEntry if d.Decode(¤tTerm) != nil || d.Decode(&votedFor) != nil || d.Decode(&logs) != nil { fmt.Println("decode error") } else { rf.currentTerm = currentTerm rf.votedFor = votedFor rf.logs = logs } }