예제 #1
0
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)
		}
	}
}
예제 #2
0
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
}