750086c5c1c37fa63ab18072a5a2a7d94b504879
[c11tester.git] / cyclegraph.cc
1 #include "cyclegraph.h"
2 #include "action.h"
3
4 /** Initializes a CycleGraph object. */
5
6 CycleGraph::CycleGraph() {
7         hasCycles=false;
8 }
9
10 /** Returns the CycleNode for a given ModelAction. */
11
12 CycleNode * CycleGraph::getNode(ModelAction * action) {
13         CycleNode *node=actionToNode.get(action);
14         if (node==NULL) {
15                 node=new CycleNode(action);
16                 actionToNode.put(action, node);
17         }
18         return node;
19 }
20
21 /** Adds an edge between two ModelActions. */
22
23 void CycleGraph::addEdge(ModelAction *from, ModelAction *to) {
24         CycleNode *fromnode=getNode(from);
25         CycleNode *tonode=getNode(to);
26         if (!hasCycles) {
27                 // Check for Cycles
28                 hasCycles=checkReachable(fromnode, tonode);
29         }
30         fromnode->addEdge(tonode);
31 }
32
33 /** Checks whether the first CycleNode can reach the second one. */
34
35 bool CycleGraph::checkReachable(CycleNode *from, CycleNode *to) {
36         std::vector<CycleNode *> queue;
37         HashTable<CycleNode *, CycleNode *, uintptr_t, 4> discovered;
38
39         queue.push_back(from);
40         discovered.put(from, from);
41         while(!queue.empty()) {
42                 CycleNode * node=queue.back();
43                 queue.pop_back();
44                 if (node==to)
45                         return true;
46
47                 for(unsigned int i=0;i<node->getEdges()->size();i++) {
48                         CycleNode *next=(*node->getEdges())[i];
49                         if (!discovered.contains(next)) {
50                                 discovered.put(next,next);
51                                 queue.push_back(next);
52                         }
53                 }
54         }
55         return false;
56 }
57
58 /** Returns whether a CycleGraph contains cycles. */
59 bool checkForCycles() {
60         return hasCycles;
61 }
62
63 /** Constructor for a CycleNode. */
64
65 CycleNode::CycleNode(ModelAction *modelaction) {
66         action=modelaction;
67 }
68
69 /** Returns a vector of the edges from a CycleNode. */
70
71 std::vector<CycleNode *> * CycleNode::getEdges() {
72         return &edges;
73 }
74
75 /** Adds an edge to a CycleNode. */
76
77 void CycleNode::addEdge(CycleNode * node) {
78         edges.push_back(node);
79 }