package kvraft import ( "6.5840/labgob" "6.5840/labrpc" "6.5840/raft" "log" "sync" "sync/atomic" ) const Debug = false func DPrintf(format string, a ...interface{}) (n int, err error) { if Debug { log.Printf(format, a...) } return } type Op struct { // Your definitions here. // Field names must start with capital letters, // otherwise RPC will break. } type KVServer struct { mu sync.Mutex me int rf *raft.Raft applyCh chan raft.ApplyMsg dead int32 // set by Kill() maxraftstate int // snapshot if log grows this big // Your definitions here. } func (kv *KVServer) Get(args *GetArgs, reply *GetReply) { // Your code here. } func (kv *KVServer) Put(args *PutAppendArgs, reply *PutAppendReply) { // Your code here. } func (kv *KVServer) Append(args *PutAppendArgs, reply *PutAppendReply) { // Your code here. } // the tester calls Kill() when a KVServer instance won't // be needed again. for your convenience, we supply // code to set rf.dead (without needing a lock), // and a killed() method to test rf.dead in // long-running loops. you can also add your own // code to Kill(). you're not required to do anything // about this, but it may be convenient (for example) // to suppress debug output from a Kill()ed instance. func (kv *KVServer) Kill() { atomic.StoreInt32(&kv.dead, 1) kv.rf.Kill() // Your code here, if desired. } func (kv *KVServer) killed() bool { z := atomic.LoadInt32(&kv.dead) return z == 1 } // servers[] contains the ports of the set of // servers that will cooperate via Raft to // form the fault-tolerant key/value service. // me is the index of the current server in servers[]. // the k/v server should store snapshots through the underlying Raft // implementation, which should call persister.SaveStateAndSnapshot() to // atomically save the Raft state along with the snapshot. // the k/v server should snapshot when Raft's saved state exceeds maxraftstate bytes, // in order to allow Raft to garbage-collect its log. if maxraftstate is -1, // you don't need to snapshot. // StartKVServer() must return quickly, so it should start goroutines // for any long-running work. func StartKVServer(servers []*labrpc.ClientEnd, me int, persister *raft.Persister, maxraftstate int) *KVServer { // call labgob.Register on structures you want // Go's RPC library to marshall/unmarshall. labgob.Register(Op{}) kv := new(KVServer) kv.me = me kv.maxraftstate = maxraftstate // You may need initialization code here. kv.applyCh = make(chan raft.ApplyMsg) kv.rf = raft.Make(servers, me, persister, kv.applyCh) // You may need initialization code here. return kv }