package algorithms;
import java.util.*;
import models.*;
import models.dataFlowModel.*;
/**
* Validation checker for data transfer model
*
* @author Nitta
*
*/
public class Validation {
private static int index = 0;
private static Deque<Node> stack = new ArrayDeque<>();
private static Set<Set<Node>> strong = new HashSet<>();
private static Map<Node, Integer> ids = new HashMap<>();
private static Map<Node, Integer> lowlink = new HashMap<>();
private static Map<Node, Boolean> onStack = new HashMap<>();
static public boolean checkUpdateConflict(DataTransferModel model) {
init();
boolean check = true;
for (Node node : model.getDataFlowGraph().getNodes()) {
if (ids.containsKey(node)) {
traverseStronglyConnectedComponents(node);
}
}
return strong.size() == 0 && check;
}
static private void init() {
index = 0;
stack = new ArrayDeque<>();
strong = new HashSet<>();
ids = new HashMap<>();
lowlink = new HashMap<>();
onStack = new HashMap<>();
}
static private void traverseStronglyConnectedComponents(Node node) {
ids.put(node, index);
lowlink.put(node, index);
index++;
stack.push(node);
onStack.put(node, true);
for (Node n : node.getSuccessors()) {
if (lowlink.containsKey(n)) {
traverseStronglyConnectedComponents(n);
if (lowlink.get(node) > lowlink.get(n)) {
lowlink.replace(node, lowlink.get(n));
}
} else if (onStack.get(n)) {
if (lowlink.get(node) > lowlink.get(n)) {
lowlink.replace(node, lowlink.get(n));
}
}
}
if (lowlink.get(node) == ids.get(node)) {
Set<Node> tmp = new HashSet<>();
Node w;
do {
w = stack.pop();
onStack.replace(node, false);
tmp.add(w);
} while (node != w);
strong.add(tmp);
}
}
}