1 package Analysis.SSJava;
3 import java.util.HashMap;
4 import java.util.HashSet;
5 import java.util.Iterator;
11 public class SSJavaLattice<T> extends Lattice<T> {
14 public static int seed = 0;
16 public SSJavaLattice(T top, T bottom) {
18 sharedLocSet = new HashSet<T>();
21 public Set<T> getSharedLocSet() {
25 public void addSharedLoc(T loc) {
26 sharedLocSet.add(loc);
29 public boolean isSharedLoc(T loc) {
30 return sharedLocSet.contains(loc);
33 public Set<T> getElementSet() {
34 Set<T> set = new HashSet<T>();
36 Set<T> keySet = getKeySet();
37 for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
38 T key = (T) iterator.next();
40 set.addAll(getTable().get(key));
43 set.remove(getTopItem());
44 set.remove(getBottomItem());
48 public boolean addRelationHigherToLower(T higher, T lower) {
50 System.out.println("add a relation: " + lower + "<" + higher);
52 return put(higher, lower);
55 public void insertNewLocationAtOneLevelHigher(T lowerLoc, T newLoc) {
56 // first identifying which location is connected to the input loc
57 Set<T> keySet = getKeySet();
58 Set<T> oneLevelHigherLocSet = new HashSet<T>();
60 for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
61 T locKey = (T) iterator.next();
62 Set<T> conntectedSet = get(locKey);
63 for (Iterator iterator2 = conntectedSet.iterator(); iterator2.hasNext();) {
64 T connectedLoc = (T) iterator2.next();
65 if (connectedLoc.equals(lowerLoc)) {
66 oneLevelHigherLocSet.add(locKey);
72 addRelationHigherToLower(newLoc, lowerLoc);
74 for (Iterator iterator = oneLevelHigherLocSet.iterator(); iterator.hasNext();) {
75 T higherLoc = (T) iterator.next();
76 // remove an existing edge between the higher loc and the input loc
77 get(higherLoc).remove(lowerLoc);
78 // add a new edge from the higher loc to the new location
79 put(higherLoc, newLoc);
84 public Set<T> getPossibleCycleElements(T higherLoc, T lowerLoc) {
85 // if a relation of higherloc & lowerloc introduces a new cycle flow,
86 // return the set of elements consisting of the cycle
87 Set<T> cycleElemetns = new HashSet<T>();
89 // if lowerLoc has already been higher than higherLoc, the new relation
90 // introduces a cycle to the lattice
91 if (lowerLoc.equals(higherLoc)) {
92 cycleElemetns.add(lowerLoc);
93 cycleElemetns.add(higherLoc);
94 } else if (isGreaterThan(lowerLoc, higherLoc)) {
95 cycleElemetns.add(lowerLoc);
96 cycleElemetns.add(higherLoc);
97 getInBetweenElements(lowerLoc, higherLoc, cycleElemetns);
102 private void getInBetweenElements(T start, T end, Set<T> elementSet) {
103 Set<T> connectedSet = get(start);
104 for (Iterator iterator = connectedSet.iterator(); iterator.hasNext();) {
105 T cur = (T) iterator.next();
106 if ((!start.equals(cur)) && (!cur.equals(end)) && isGreaterThan(cur, end)) {
108 getInBetweenElements(cur, end, elementSet);
113 public void mergeIntoNewLocation(Set<T> cycleSet, T newLoc) {
118 Set<T> keySet = getKeySet();
120 for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
121 T keyElement = (T) iterator.next();
122 Set<T> connectedSet = get(keyElement);
123 Set<T> removeSet = new HashSet<T>();
124 for (Iterator iterator2 = connectedSet.iterator(); iterator2.hasNext();) {
125 T cur = (T) iterator2.next();
126 if (cycleSet.contains(cur)) {
131 if (!removeSet.isEmpty()) {
132 // // remove relations of locationElement -> cycle
133 connectedSet.removeAll(removeSet);
134 // add a new relation of location Element -> shared loc
135 connectedSet.add(newLoc);
136 getTable().put(keyElement, connectedSet);
140 Set<T> newConnectedSet = new HashSet<T>();
141 for (Iterator iterator = cycleSet.iterator(); iterator.hasNext();) {
142 T cycleElement = (T) iterator.next();
143 Set<T> connectedSet = get(cycleElement);
144 if (connectedSet != null) {
145 newConnectedSet.addAll(connectedSet);
147 getTable().remove(cycleElement);
149 newConnectedSet.removeAll(cycleSet);
150 newConnectedSet.remove(newLoc);
152 Set<T> set = getTable().get(newLoc);
153 set.addAll(newConnectedSet);
156 for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
157 T keyElement = (T) iterator.next();
158 get(keyElement).removeAll(cycleSet);
161 for (Iterator iterator = cycleSet.iterator(); iterator.hasNext();) {
162 T cycleElement = (T) iterator.next();
163 getTable().remove(cycleElement);
168 public void remove(T loc) {
170 Set<T> keySet = getKeySet();
172 Set<T> inSet = new HashSet<T>();
173 for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
174 T keyElement = (T) iterator.next();
175 Set<T> connectedSet = get(keyElement);
176 if (connectedSet.contains(loc)) {
178 connectedSet.remove(loc);
182 Set<T> outSet = get(loc);
184 for (Iterator iterator = inSet.iterator(); iterator.hasNext();) {
185 T in = (T) iterator.next();
186 for (Iterator iterator2 = outSet.iterator(); iterator2.hasNext();) {
187 T out = (T) iterator2.next();
192 getTable().remove(loc);
196 public void substituteLocation(T oldLoc, T newLoc) {
197 // the new location is going to take all relations of the old location
198 if (!getKeySet().contains(newLoc)) {
202 // consider the set of location s.t. LOC is greater than oldLoc
203 Set<T> keySet = getKeySet();
204 Set<T> directedConnctedHigherLocSet = new HashSet<T>();
206 for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
207 T key = (T) iterator.next();
208 Set<T> connectedSet = getTable().get(key);
209 if (connectedSet.contains(oldLoc)) {
210 directedConnctedHigherLocSet.add(key);
214 Set<T> connctedLowerSet = getTable().get(oldLoc);
215 Set<T> directedConnctedLowerLocSet = new HashSet<T>();
216 if (connctedLowerSet != null) {
217 directedConnctedLowerLocSet.addAll(connctedLowerSet);
220 for (Iterator iterator = directedConnctedHigherLocSet.iterator(); iterator.hasNext();) {
221 T higher = (T) iterator.next();
222 if (!higher.equals(newLoc)) {
223 addRelationHigherToLower(higher, newLoc);
227 for (Iterator iterator = directedConnctedLowerLocSet.iterator(); iterator.hasNext();) {
228 T lower = (T) iterator.next();
229 if (!lower.equals(newLoc)) {
230 addRelationHigherToLower(newLoc, lower);
234 getTable().remove(oldLoc);
236 for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
237 T key = (T) iterator.next();
238 getTable().get(key).remove(oldLoc);
243 public void removeRedundantEdges() {
246 isUpdated = recurRemoveRedundant();
250 public boolean recurRemoveRedundant() {
252 Set<T> keySet = getKeySet();
253 Set<T> visited = new HashSet<T>();
255 for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
256 T key = (T) iterator.next();
257 Set<T> connectedSet = getTable().get(key);
258 if (connectedSet != null) {
259 Set<T> toberemovedSet = new HashSet<T>();
260 for (Iterator iterator2 = connectedSet.iterator(); iterator2.hasNext();) {
261 T dst = (T) iterator2.next();
262 Set<T> otherNeighborSet = new HashSet<T>();
263 otherNeighborSet.addAll(connectedSet);
264 otherNeighborSet.remove(dst);
265 for (Iterator iterator3 = otherNeighborSet.iterator(); iterator3.hasNext();) {
266 T neighbor = (T) iterator3.next();
267 if (isReachable(neighbor, visited, dst)) {
268 toberemovedSet.add(dst);
272 if (toberemovedSet.size() > 0) {
273 connectedSet.removeAll(toberemovedSet);
283 private boolean isReachable(T neighbor, Set<T> visited, T dst) {
284 Set<T> connectedSet = getTable().get(neighbor);
285 if (connectedSet != null) {
286 for (Iterator<T> iterator = connectedSet.iterator(); iterator.hasNext();) {
287 T n = iterator.next();
291 if (!visited.contains(n)) {
293 if (isReachable(n, visited, dst)) {
302 public Map<T, Set<T>> getIncomingElementMap() {
303 Map<T, Set<T>> map = new HashMap<T, Set<T>>();
305 Set<T> keySet = getKeySet();
306 for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
307 T key = (T) iterator.next();
309 Set<T> incomingSet = new HashSet<T>();
311 for (Iterator iterator2 = keySet.iterator(); iterator2.hasNext();) {
312 T in = (T) iterator2.next();
313 if (!in.equals(key) && get(in).contains(key)) {
317 map.put(key, incomingSet);