aboutsummaryrefslogtreecommitdiffstats
path: root/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/GraphStatistic.xtend
diff options
context:
space:
mode:
Diffstat (limited to 'Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/GraphStatistic.xtend')
-rw-r--r--Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/GraphStatistic.xtend194
1 files changed, 194 insertions, 0 deletions
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/GraphStatistic.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/GraphStatistic.xtend
new file mode 100644
index 00000000..31788bb2
--- /dev/null
+++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/GraphStatistic.xtend
@@ -0,0 +1,194 @@
1package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph
2
3import com.google.common.collect.ArrayListMultimap
4import com.google.common.collect.Multimap
5import java.util.HashMap
6import java.util.HashSet
7import java.util.List
8import java.util.Map
9import java.util.Set
10import org.eclipse.emf.ecore.EObject
11import org.eclipse.emf.ecore.EReference
12
13class GraphStatistic {
14 val incomingEdges = new HashMap<String, Multimap<EObject, EObject>>;
15 val outgoingEdges = new HashMap<String, Multimap<EObject, EObject>>;
16
17 val edgeTypes = new HashSet<String>();
18 val nodeToType = new HashMap<EObject, Set<String>>();
19
20 /**
21 * Add an edge type to to the graph
22 * @param type: type to add
23 */
24 def void addEdgeType(String type){
25 if(edgeTypes.contains(type)){
26 return;
27 }
28
29 edgeTypes.add(type);
30 incomingEdges.put(type, ArrayListMultimap.create());
31 outgoingEdges.put(type, ArrayListMultimap.create());
32 }
33
34 /**
35 * Add a node to the graph with one type in its type hierarchy
36 * @param node: node to add
37 */
38 def void addNodeWithType(EObject n, String Type){
39 var types = nodeToType.getOrDefault(n, new HashSet<String>());
40 types.add(Type);
41 nodeToType.put(n, types);
42 }
43
44 def boolean containsNode(EObject o){
45 return nodeToType.containsKey(o);
46 }
47
48 def Set<String> getTypesForNode(EObject o){
49 return nodeToType.getOrDefault(o, new HashSet<String>());
50 }
51
52 def void overwriteCurrentType(EObject o, String type){
53 var typeSet = nodeToType.getOrDefault(o, new HashSet<String>());
54
55 // clear current types
56 typeSet.clear();
57 typeSet.add(type);
58 nodeToType.put(o, typeSet);
59 }
60
61 /**
62 * Add a node to the graph with all types in its type hierarchy
63 */
64 def void addNodeWithAllTypes(EObject n, Set<String> types){
65 nodeToType.put(n, types);
66 }
67
68 /**
69 * Add an edge to the graph
70 * @param source: source node
71 * @param target: target node
72 * @param type: type of the reference
73 */
74 def void addEdge(EObject source, EObject target, String type){
75 outgoingEdges.get(type).put(source, target);
76 incomingEdges.get(type).put(target, source);
77 }
78
79 /**
80 * check if this graph contains a specific edge type
81 */
82 def boolean containsEdgeType(String typeName){
83 if(outgoingEdges.containsKey(typeName) && incomingEdges.containsKey(typeName)){
84 return true;
85 }
86 return false;
87 }
88
89 /**
90 * remove references from the statistics, potentially remove the nodes associated with it
91 * @Param name: name of the reference
92 * @Param isContainment: if true then the corresponding nodes on the incoming side will also be removed
93 */
94 def removeReference(String name, boolean isContainment){
95 if(!edgeTypes.contains(name)){
96 return;
97 }
98
99 edgeTypes.remove(name);
100 var incomingSet = incomingEdges.remove(name);
101 outgoingEdges.remove(name);
102
103 // if the reference is not a containment, then removing the reference is enough
104 if(!isContainment){
105 return;
106 }
107
108 // else remove all corresponding nodes
109 val nodesToRemove = incomingSet.keySet();
110
111 //remove nodes from node sets
112 nodesToRemove.forEach[nodeToType.remove(it)];
113
114 val removeForMultimap = [Multimap<EObject, EObject> refMap|
115 nodesToRemove.forEach[refMap.removeAll(it)];
116 var values = refMap.values()
117 //remove the values from the list is equavalent to remove it in the multimap
118 values.removeAll(nodesToRemove);
119 return;
120 ];
121
122 //remove nodes from all other references on incomingEdges
123 incomingEdges.values.forEach(removeForMultimap);
124 outgoingEdges.values.forEach(removeForMultimap);
125 }
126
127 /**
128 * calculate the out degree for an object
129 */
130 def int outDegree(EObject o){
131 var count = 0;
132
133 for (String type : edgeTypes){
134 count += outgoingEdges.get(type).get(o).size();
135 }
136 return count;
137 }
138
139 /**
140 * calculate the in degree of an object
141 */
142 def int inDegree(EObject o){
143 var count = 0;
144
145 for (String type : edgeTypes){
146 count += incomingEdges.get(type).get(o).size();
147 }
148 return count;
149 }
150
151 /**
152 * calculate the dimentional degree of a node
153 */
154 def int dimentionalDegree(EObject o, String type){
155 return incomingEdges.get(type).get(o).size() + outgoingEdges.get(type).get(o).size();
156 }
157
158 /**
159 * calculate the number of edge types for a given node.
160 */
161 def int numOfEdgeTypes(EObject o){
162 var count = 0;
163
164 for(String type : edgeTypes){
165 if(dimentionalDegree(o, type) > 0){
166 count++;
167 }
168 }
169
170 return count;
171 }
172
173 def List<String> getAllTypes(){
174 return edgeTypes.toList();
175 }
176
177 def Map<EObject, Set<String>> getNodeToTypesMap(){
178 return nodeToType;
179 }
180
181 def List<EObject> getAllNodes(){
182 return nodeToType.keySet().toList();
183 }
184
185 def HashMap<String, Multimap<EObject, EObject>> getOutgoingEdges(){
186 return outgoingEdges;
187 }
188
189 def HashMap<String, Multimap<EObject, EObject>> incomingEdges(){
190 return incomingEdges;
191 }
192
193}
194