func (r *Replica) executeCommands() { execedUpTo := int32(-1) skippedTo := make([]int32, r.N) skippedToOrig := make([]int32, r.N) conflicts := make(map[state.Key]int32, 60000) for q := 0; q < r.N; q++ { skippedToOrig[q] = -1 } for !r.Shutdown { executed := false jump := false copy(skippedTo, skippedToOrig) for i := execedUpTo + 1; i < r.crtInstance; i++ { if i < skippedTo[i%int32(r.N)] { continue } if r.instanceSpace[i] == nil { break } if r.instanceSpace[i].status == EXECUTED { continue } if r.instanceSpace[i].status != COMMITTED { if !r.instanceSpace[i].skipped { confInst, present := conflicts[r.instanceSpace[i].command.K] if present && r.instanceSpace[confInst].status != EXECUTED { break } conflicts[r.instanceSpace[i].command.K] = i jump = true continue } else { break } } if r.instanceSpace[i].skipped { skippedTo[i%int32(r.N)] = i + int32(r.instanceSpace[i].nbInstSkipped*r.N) if !jump { skippedToOrig[i%int32(r.N)] = skippedTo[i%int32(r.N)] } continue } inst := r.instanceSpace[i] for inst.command == nil { time.Sleep(1000 * 1000) } confInst, present := conflicts[inst.command.K] if present && confInst < i && r.instanceSpace[confInst].status != EXECUTED && state.Conflict(r.instanceSpace[confInst].command, inst.command) { break } inst.command.Execute(r.State) if r.Dreply && inst.lb != nil && inst.lb.clientProposal != nil { dlog.Printf("Sending ACK for req. %d\n", inst.lb.clientProposal.CommandId) r.ReplyProposeTS(&genericsmrproto.ProposeReplyTS{TRUE, inst.lb.clientProposal.CommandId, state.NIL, inst.lb.clientProposal.Timestamp}, inst.lb.clientProposal.Reply) } inst.status = EXECUTED executed = true if !jump { execedUpTo = i } } if !executed { time.Sleep(1000 * 1000) } } }
func (r *Replica) learn(getLub bool) (conflict bool, glb []int32, lub []int32) { if r.crtBalnum < 0 { return false, nil, nil } crtbal := r.ballotArray[r.crtBalnum] if len(crtbal.lb.cstructs) == 0 { return false, nil, nil } idToNode := make(map[int32]*node, 2*len(crtbal.cstruct)) // build directed graph dlog.Println(crtbal.lb.cstructs) for i := 0; i < len(crtbal.lb.cstructs); i++ { cs := crtbal.lb.cstructs[i] for idx, cid := range cs { var n *node var present bool crtCmd := r.commands[cid] if _, present = r.committed[cid]; present { continue } if n, present = idToNode[cid]; !present { n = &node{0, make(map[int32]int, 2), WHITE} idToNode[cid] = n } n.count++ for j := 0; j < idx; j++ { if _, present = r.committed[cs[j]]; present { continue } if crtCmd == nil { log.Println("crtCmd is nil") return false, nil, nil } if r.commands[cs[j]] == nil { log.Println("cs[j] is nil") return false, nil, nil } if !state.Conflict(crtCmd, r.commands[cs[j]]) { continue } n.outEdges[cs[j]] = n.outEdges[cs[j]] + 1 } } } // hack /* conflict = false glb = make([]int32, 0) lub = make([]int32, 0) for cid, n := range idToNode { if n.count >= r.fastQSize { glb = append(glb, cid) } lub = append(lub, cid) } return false, glb, lub*/ // depth-first search for cid, n := range idToNode { if n.color == WHITE { var conf bool conf, glb, lub = r.dfs(cid, n, glb, lub, idToNode) conflict = conflict || conf } } /* if getLub && conflict { //sort out lub done := false for !done { done = true for i := 1; i < len(lub) - 1; i++ { for j := i + 1; j < len(lub); j++ { u := lub[i] v := lub[j] cu := r.commands[u] cv := r.commands[v] if !state.Conflict(cu, cv) { continue } nu := idToNode[u] nv := idToNode[v] if nv.count - nv.outEdges[u] > nu.count - nu.outEdges[v] { lub[i] = v lub[j] = u done = false } } } } } */ return conflict, glb, lub }