X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=Robust%2Fsrc%2FAnalysis%2FSSJava%2FHierarchyGraph.java;h=d7900939e6d4d6e4f221838c2113f8177527ce35;hb=47cc527f574f19b71e92fceac668fb8c0655b13b;hp=50744f0140b6c3b1d0ef224a8950ef0f2c744925;hpb=9e11ce79473fe199b045066b384fdfed8eb022ea;p=IRC.git diff --git a/Robust/src/Analysis/SSJava/HierarchyGraph.java b/Robust/src/Analysis/SSJava/HierarchyGraph.java index 50744f01..d7900939 100644 --- a/Robust/src/Analysis/SSJava/HierarchyGraph.java +++ b/Robust/src/Analysis/SSJava/HierarchyGraph.java @@ -8,15 +8,17 @@ import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; +import java.util.Stack; import IR.Descriptor; import IR.FieldDescriptor; -import IR.VarDescriptor; public class HierarchyGraph { Descriptor desc; + boolean isSCgraph; + String name; // graph structure @@ -26,6 +28,8 @@ public class HierarchyGraph { Map mapDescToHNode; Map> mapHNodeToDescSet; Map mapHNodeToCurrentHNode; // tracking which node corresponds to the initial node + Map mapHNodeNameToCurrentHNode; // tracking which node corresponds to the initial + // node Map> mapMergeNodetoMergingSet; // data structures for a combination node @@ -34,9 +38,11 @@ public class HierarchyGraph { Map, HNode> mapCombineNodeSetToCombinationNode; Map, Set> mapCombineNodeSetToOutgoingNodeSet; - Set nodeSet; + Map> mapNormalNodeToSCNodeReachToSet; - public static int seed = 0; + Map, Set> mapCombineNodeSetToFirstNodeOfChainSet; + + Set nodeSet; // for the lattice generation Map mapHNodeToUniqueIndex; @@ -61,6 +67,21 @@ public class HierarchyGraph { mapHNodeToCurrentHNode = new HashMap(); + mapHNodeNameToCurrentHNode = new HashMap(); + + mapNormalNodeToSCNodeReachToSet = new HashMap>(); + + mapCombineNodeSetToFirstNodeOfChainSet = new HashMap, Set>(); + + isSCgraph = false; + } + + public void setSCGraph(boolean in) { + isSCgraph = in; + } + + public boolean isSCGraph() { + return isSCgraph; } public Descriptor getDesc() { @@ -97,10 +118,18 @@ public class HierarchyGraph { return mapHNodeToCurrentHNode; } + public Map getMapHNodeNameToCurrentHNode() { + return mapHNodeNameToCurrentHNode; + } + public void setMapHNodeToCurrentHNode(Map mapHNodeToCurrentHNode) { this.mapHNodeToCurrentHNode = mapHNodeToCurrentHNode; } + public void setMapHNodeNameToCurrentHNode(Map mapHNodeNameToCurrentHNode) { + this.mapHNodeNameToCurrentHNode = mapHNodeNameToCurrentHNode; + } + public Map getMapDescToHNode() { return mapDescToHNode; } @@ -128,22 +157,25 @@ public class HierarchyGraph { if (possibleCycleSet.size() > 0) { if (possibleCycleSet.size() == 1) { + // System.out.println("possibleCycleSet=" + possibleCycleSet + " from src=" + srcHNode + // + " dstHNode=" + dstHNode); if (dstHNode.isSharedNode()) { // it has already been assigned shared node. } else { dstHNode.setSharedNode(true); + // System.out.println("$$$setShared=" + dstHNode); } return; } - HNode newMergeNode = mergeNodes(possibleCycleSet, false); + // System.out.println("--- CYCLIC VALUE FLOW: " + srcHNode + " -> " + dstHNode); + HNode newMergeNode = mergeNodes(possibleCycleSet); newMergeNode.setSharedNode(true); - System.out.println("### INTRODUCE A NEW MERGE NODE: " + newMergeNode); - System.out.println("### CYCLIC VALUE FLOW: " + srcHNode + " -> " + dstHNode); + } else { getIncomingNodeSet(dstHNode).add(srcHNode); getOutgoingNodeSet(srcHNode).add(dstHNode); - System.out.println("add an edge " + srcHNode + " -> " + dstHNode); + // System.out.println("add an edge " + srcHNode + " -> " + dstHNode); } } @@ -153,10 +185,16 @@ public class HierarchyGraph { } public void addEdge(Descriptor src, Descriptor dst) { - HNode srcHNode = getHNode(src); - HNode dstHNode = getHNode(dst); - addEdge(srcHNode, dstHNode); + if (src.equals(LocationInference.LITERALDESC)) { + // in this case, we do not need to add a source hnode + // just add a destination hnode + getHNode(dst); + } else { + HNode srcHNode = getHNode(src); + HNode dstHNode = getHNode(dst); + addEdge(srcHNode, dstHNode); + } } @@ -167,9 +205,20 @@ public class HierarchyGraph { public HNode getHNode(Descriptor d) { if (!mapDescToHNode.containsKey(d)) { HNode newNode = new HNode(d); + if (d instanceof FieldDescriptor) { newNode.setSkeleton(true); } + + if (d.equals(LocationInference.TOPDESC)) { + newNode.setSkeleton(true); + } + + String symbol = d.getSymbol(); + if (symbol.startsWith(LocationInference.PCLOC) || symbol.startsWith(LocationInference.RLOC)) { + newNode.setSkeleton(true); + } + mappingDescriptorToHNode(d, newNode); nodeSet.add(newNode); } @@ -219,6 +268,7 @@ public class HierarchyGraph { skeletonGraph.setMapHNodeToDescSet(getMapHNodeToDescSet()); skeletonGraph.setMapHNodetoMergeSet(getMapHNodetoMergeSet()); skeletonGraph.setMapHNodeToCurrentHNode(getMapHNodeToCurrentHNode()); + skeletonGraph.setMapHNodeNameToCurrentHNode(getMapHNodeNameToCurrentHNode()); return skeletonGraph; @@ -264,21 +314,16 @@ public class HierarchyGraph { } - public void simplifyHierarchyGraph() { - removeRedundantEdges(); - combineRedundantNodes(false); - } - - public void simplifySkeletonCombinationHierarchyGraph() { + public void simplifyHierarchyGraph(LocationInference infer) { removeRedundantEdges(); - combineRedundantNodes(true); + combineRedundantNodes(infer); } - public void combineRedundantNodes(boolean onlyCombinationNodes) { + public void combineRedundantNodes(LocationInference infer) { // Combine field/parameter nodes who have the same set of incoming/outgoing edges. boolean isUpdated = false; do { - isUpdated = combineTwoRedundatnNodes(onlyCombinationNodes); + isUpdated = combineTwoRedundatnNodes(infer); } while (isUpdated); } @@ -296,12 +341,16 @@ public class HierarchyGraph { return mapHNodeToOutgoingSet.get(node); } - private boolean combineTwoRedundatnNodes(boolean onlyCombinationNodes) { + private boolean combineTwoRedundatnNodes(LocationInference infer) { for (Iterator iterator = nodeSet.iterator(); iterator.hasNext();) { HNode node1 = (HNode) iterator.next(); - if ((onlyCombinationNodes && (!node1.isCombinationNode())) - || (!onlyCombinationNodes && (!node1.isSkeleton()))) { + // if ((onlyCombinationNodes && (!node1.isCombinationNode())) + // || (!onlyCombinationNodes && (!node1.isSkeleton()))) { + // continue; + // } + + if (!node1.isSkeleton()) { continue; } @@ -311,11 +360,16 @@ public class HierarchyGraph { for (Iterator iterator2 = nodeSet.iterator(); iterator2.hasNext();) { HNode node2 = (HNode) iterator2.next(); - if ((onlyCombinationNodes && (!node2.isCombinationNode())) - || (!onlyCombinationNodes && (!node2.isSkeleton()))) { + // if ((onlyCombinationNodes && (!node2.isCombinationNode())) + // || (!onlyCombinationNodes && (!node2.isSkeleton()))) { + // continue; + // } + + if (!node2.isSkeleton()) { continue; } + // System.out.println("node1=" + node1 + " vs node2=" + node2); if (!isEligibleForMerging(node1, node2)) { continue; } @@ -325,14 +379,26 @@ public class HierarchyGraph { Set incomingNodeSet2 = getIncomingNodeSet(node2); Set outgoingNodeSet2 = getOutgoingNodeSet(node2); + // System.out.println(node1 + " " + node2 + " MERGING incoming?=" + incomingNodeSet1 + // + " vs " + incomingNodeSet2); + // System.out.println(node1 + " " + node2 + " MERGING outgoing?=" + outgoingNodeSet1 + // + " vs " + outgoingNodeSet2); + if (incomingNodeSet1.equals(incomingNodeSet2) && outgoingNodeSet1.equals(outgoingNodeSet2)) { // need to merge node1 and node2 - + // System.out.println("MERGE!!!!!!!!!!!!!"); + // /////////////// + // merge two nodes only if every hierarchy graph in the inheritance hierarchy + // that includes both nodes allows the merging of them... Set mergeSet = new HashSet(); mergeSet.add(node1); mergeSet.add(node2); - mergeNodes(mergeSet, onlyCombinationNodes); + infer.isValidMergeInheritanceCheck(desc, mergeSet); + + // /////////////// + + mergeNodes(mergeSet); return true; } @@ -345,8 +411,6 @@ public class HierarchyGraph { private boolean isEligibleForMerging(HNode node1, HNode node2) { - System.out.println("********isEligibleForMerging=" + node1 + " " + node2); - if (node1.isSharedNode() || node2.isSharedNode()) { // if either of nodes is a shared node, @@ -358,36 +422,22 @@ public class HierarchyGraph { for (Iterator iterator = descSet.iterator(); iterator.hasNext();) { Descriptor desc = (Descriptor) iterator.next(); - if (!isPrimitive(desc)) { + if (!LocationInference.isPrimitive(desc)) { return false; } } - System.out.println("******** true"); - return true; - } - return false; - } - - private boolean isPrimitive(Descriptor desc) { - - if (desc instanceof FieldDescriptor) { - return ((FieldDescriptor) desc).getType().isPrimitive(); - } else if (desc instanceof VarDescriptor) { - return ((VarDescriptor) desc).getType().isPrimitive(); - } else if (desc instanceof InterDescriptor) { return true; } - - return false; + return true; } private void addEdgeWithNoCycleCheck(HNode srcHNode, HNode dstHNode) { getIncomingNodeSet(dstHNode).add(srcHNode); getOutgoingNodeSet(srcHNode).add(dstHNode); - System.out.println("addEdgeWithNoCycleCheck src=" + srcHNode + " -> " + dstHNode); + // System.out.println("addEdgeWithNoCycleCheck src=" + srcHNode + " -> " + dstHNode); } - private HNode mergeNodes(Set set, boolean onlyCombinationNodes) { + private HNode mergeNodes(Set set) { Set incomingNodeSet = new HashSet(); Set outgoingNodeSet = new HashSet(); @@ -400,12 +450,9 @@ public class HierarchyGraph { String nodeName; boolean isMergeNode = false; - if (onlyCombinationNodes) { - nodeName = "Comb" + (seed++); - } else { - nodeName = "Node" + (seed++); - isMergeNode = true; - } + nodeName = "MNode" + (LocationInference.locSeed++); + isMergeNode = true; + HNode newMergeNode = new HNode(nodeName); newMergeNode.setMergeNode(isMergeNode); @@ -414,16 +461,22 @@ public class HierarchyGraph { // if the input set contains a skeleton node, need to set a new merge node as skeleton also boolean hasSkeleton = false; + boolean hasShared = false; for (Iterator iterator = set.iterator(); iterator.hasNext();) { HNode inNode = (HNode) iterator.next(); if (inNode.isSkeleton()) { hasSkeleton = true; - break; + } + if (inNode.isSharedNode()) { + hasShared = true; } } - System.out.println("--Set merging node=" + newMergeNode + " as a skeleton=" + set - + " hasSkeleton=" + hasSkeleton); + // System.out.println("-----Set merging node=" + newMergeNode + " as a skeleton=" + set + // + " hasSkeleton=" + hasSkeleton + " CUR DESC=" + desc); newMergeNode.setSkeleton(hasSkeleton); + newMergeNode.setSharedNode(hasShared); + + // System.out.println("-----MERGING NODE=" + set + " new node=" + newMergeNode); for (Iterator iterator = set.iterator(); iterator.hasNext();) { HNode node = (HNode) iterator.next(); @@ -459,35 +512,42 @@ public class HierarchyGraph { mergedSkeletonNode.add(merged); } } - mapMergeNodetoMergingSet.put(newMergeNode, mergedSkeletonNode); - for (Iterator iterator = mergedSkeletonNode.iterator(); iterator.hasNext();) { + + // mapMergeNodetoMergingSet.put(newMergeNode, mergedSkeletonNode); + // for (Iterator iterator = set.iterator(); iterator.hasNext();) { + mapMergeNodetoMergingSet.put(newMergeNode, set); + for (Iterator iterator = set.iterator(); iterator.hasNext();) { HNode mergedNode = (HNode) iterator.next(); addMapHNodeToCurrentHNode(mergedNode, newMergeNode); } - System.out.println("\n###mergedSkeletonNode=" + mergedSkeletonNode); - System.out.println("###MERGING NODE=" + set + " new node=" + newMergeNode); for (Iterator iterator = set.iterator(); iterator.hasNext();) { HNode hNode = (HNode) iterator.next(); - System.out.println("old=" + hNode + "----->newNode=" + getCurrentHNode(hNode)); + // System.out.println("old=" + hNode + "----->newNode=" + getCurrentHNode(hNode)); } + // System.out.println(); + return newMergeNode; } private void addMapHNodeToCurrentHNode(HNode curNode, HNode newNode) { + if (curNode.isMergeNode()) { Set mergingSet = getMergingSet(curNode); mergingSet.add(curNode); - System.out.println("addMapHNodeToCurrentHNode curNode=" + curNode + " meringSet=" - + mergingSet); + // System.out.println("-------addMapHNodeToCurrentHNode curNode=" + curNode + " meringSet=" + // + mergingSet + " newNode=" + newNode); for (Iterator iterator = mergingSet.iterator(); iterator.hasNext();) { HNode mergingNode = (HNode) iterator.next(); mapHNodeToCurrentHNode.put(mergingNode, newNode); + mapHNodeNameToCurrentHNode.put(mergingNode.getName(), newNode); } } else { mapHNodeToCurrentHNode.put(curNode, newNode); + mapHNodeNameToCurrentHNode.put(curNode.getName(), newNode); } + } public HNode getCurrentHNode(HNode node) { @@ -497,6 +557,10 @@ public class HierarchyGraph { return mapHNodeToCurrentHNode.get(node); } + public HNode getCurrentHNode(String nodeName) { + return mapHNodeNameToCurrentHNode.get(nodeName); + } + private Set getMergingSet(HNode mergeNode) { Set mergingSet = new HashSet(); Set mergedNode = mapMergeNodetoMergingSet.get(mergeNode); @@ -552,6 +616,68 @@ public class HierarchyGraph { } + public Set getReachableSCNodeSet(HNode startNode) { + // returns the set of hnodes which is reachable from the startNode and is either SC node or a + // node which is directly connected to the SC nodes + Set reachable = new HashSet(); + Set visited = new HashSet(); + visited.add(startNode); + recurReachableNodeSet(startNode, visited, reachable); + return reachable; + } + + public Set getSCNodeReachToSet(HNode node) { + if (!mapNormalNodeToSCNodeReachToSet.containsKey(node)) { + mapNormalNodeToSCNodeReachToSet.put(node, new HashSet()); + } + return mapNormalNodeToSCNodeReachToSet.get(node); + } + + private void recurReachableNodeSet(HNode node, Set visited, Set reachable) { + + Set outSet = getOutgoingNodeSet(node); + for (Iterator iterator = outSet.iterator(); iterator.hasNext();) { + HNode out = (HNode) iterator.next(); + + if (!visited.contains(out)) { + visited.add(out); + Set reachableFromSCNodeSet = reachableFromSCNode(out); + mapNormalNodeToSCNodeReachToSet.put(out, reachableFromSCNodeSet); + if (out.isSkeleton() || out.isCombinationNode() || reachableFromSCNodeSet.size() > 0) { + reachable.add(out); + } else { + visited.add(out); + recurReachableNodeSet(out, visited, reachable); + } + + } + + } + + } + + private Set reachableFromSCNode(HNode node) { + Set visited = new HashSet(); + visited.add(node); + Set reachable = new HashSet(); + recurReachableFromSCNode(node, reachable, visited); + return reachable; + } + + private void recurReachableFromSCNode(HNode node, Set reachable, Set visited) { + Set inNodeSet = getIncomingNodeSet(node); + for (Iterator iterator = inNodeSet.iterator(); iterator.hasNext();) { + HNode inNode = (HNode) iterator.next(); + if (inNode.isSkeleton() || inNode.isCombinationNode()) { + visited.add(inNode); + reachable.add(inNode); + } else if (!visited.contains(inNode)) { + visited.add(inNode); + recurReachableFromSCNode(inNode, reachable, visited); + } + } + } + public Set getDirectlyReachableSkeletonCombinationNodeFrom(HNode node, Set combinationNodeSet) { Set reachable = new HashSet(); @@ -655,8 +781,10 @@ public class HierarchyGraph { } public HNode getCombinationNode(Set combineSet) { + assert isSCGraph(); if (!mapCombineNodeSetToCombinationNode.containsKey(combineSet)) { - String name = "COMB" + (seed++); + String name = "COMB" + (LocationInference.locSeed++); + System.out.println("-NEW COMB NODE=" + name); HNode node = new HNode(name); node.setCombinationNode(true); nodeSet.add(node); @@ -683,9 +811,48 @@ public class HierarchyGraph { Set> keySet = simpleHierarchyGraph.getCombineNodeSet(); for (Iterator iterator = keySet.iterator(); iterator.hasNext();) { Set combineSet = (Set) iterator.next(); - System.out.println("--combineSet=" + combineSet); HNode combinationNode = getCombinationNode(combineSet); - System.out.println("--combinationNode=" + combinationNode); + System.out.println("\n@INSERT COMBINATION NODE FOR combineSet=" + combineSet + + " --combinationNode=" + combinationNode); + System.out.println(" --hierarchynodes=" + + simpleHierarchyGraph.getCombinationNodeSetByCombineNodeSet(combineSet)); + + Set simpleHNodeSet = + simpleHierarchyGraph.getCombinationNodeSetByCombineNodeSet(combineSet); + + // check whether a hnode in the simple hierarchy graph is the first node of the chain + // if all incoming combination nodes to the hnode have a different combination set from the + // hnode, it is the first node of the chain + for (Iterator iterator2 = simpleHNodeSet.iterator(); iterator2.hasNext();) { + HNode simpleHNode = (HNode) iterator2.next(); + boolean isFirstNodeOfChain = true; + Set incomingNodeSet = simpleHierarchyGraph.getIncomingNodeSet(simpleHNode); + for (Iterator iterator3 = incomingNodeSet.iterator(); iterator3.hasNext();) { + HNode inNode = (HNode) iterator3.next(); + if (inNode.isCombinationNode()) { + Set inNodeCombineSet = + simpleHierarchyGraph.getCombineSetByCombinationNode(inNode); + if (inNodeCombineSet.equals(combineSet)) { + isFirstNodeOfChain = false; + break; + } + } + } + simpleHNode.setDirectCombinationNode(isFirstNodeOfChain); + if (isFirstNodeOfChain) { + simpleHierarchyGraph.addFirstNodeOfChain(combineSet, simpleHNode); + System.out.println("IT IS THE FIRST NODE OF THE CHAIN:" + simpleHNode); + // System.out.println("--->INCOMING NODES="); + // Set inNodeSet = simpleHierarchyGraph.getIncomingNodeSet(simpleHNode); + // for (Iterator iterator3 = inNodeSet.iterator(); iterator3.hasNext();) { + // HNode inNode = (HNode) iterator3.next(); + // System.out.println(" inNode=" + inNode + " combineSet=" + // + simpleHierarchyGraph.getCombineSetByCombinationNode(inNode) + " SKELETON TO SET=" + // + simpleHierarchyGraph.getSkeleteNodeSetReachTo(inNode)); + // } + } + } + // add an edge from a skeleton node to a combination node for (Iterator iterator2 = combineSet.iterator(); iterator2.hasNext();) { HNode inSkeletonNode = (HNode) iterator2.next(); @@ -699,6 +866,7 @@ public class HierarchyGraph { srcNode = getHNode(inSkeletonNode.getDescriptor()); } // System.out.println("--srcNode=" + srcNode); + System.out.println(" ADD EDGE SRC=" + srcNode + " -> " + combinationNode); addEdgeWithNoCycleCheck(srcNode, combinationNode); } @@ -719,66 +887,43 @@ public class HierarchyGraph { } } - System.out.println("--"); + // System.out.println("--"); } } - private void addCombinationNode(HNode curNode, Set reachToSet, Set reachableSet) { - if (!mapSkeletonNodeSetToCombinationNode.containsKey(reachToSet)) { - // need to create a new combination node - String nodeName = "Comb" + (seed++); - HNode newCombinationNode = new HNode(nodeName); - newCombinationNode.setCombinationNode(true); - - nodeSet.add(newCombinationNode); - mapSkeletonNodeSetToCombinationNode.put(reachToSet, newCombinationNode); - - for (Iterator iterator = reachToSet.iterator(); iterator.hasNext();) { - HNode reachToNode = (HNode) iterator.next(); - addEdge(reachToNode, newCombinationNode); - } + public Set getSkeleteNodeSetReachToNoTransitive(HNode node) { - } + Set reachToSet = new HashSet(); + Set visited = new HashSet(); + // visited.add(node); + recurSkeletonReachTo(node, reachToSet, visited); - HNode combinationNode = mapSkeletonNodeSetToCombinationNode.get(reachToSet); - for (Iterator iterator = reachableSet.iterator(); iterator.hasNext();) { - HNode reachableNode = (HNode) iterator.next(); - addEdge(combinationNode, reachableNode); - } + // obsolete! + // if a node reaches to one of elements in the reachToSet, we do not need to keep it + // because the node is not directly connected to the combination node + // removeRedundantReachToNodes(reachToSet); + return removeTransitivelyReachToSet(reachToSet); + // return reachToSet; } - private Set getSkeleteNodeSetReachTo(HNode node) { + public Set getSkeleteNodeSetReachTo(HNode node) { Set reachToSet = new HashSet(); Set visited = new HashSet(); + // visited.add(node); recurSkeletonReachTo(node, reachToSet, visited); + // obsolete! // if a node reaches to one of elements in the reachToSet, we do not need to keep it // because the node is not directly connected to the combination node + // removeRedundantReachToNodes(reachToSet); - removeRedundantReachToNodes(reachToSet); - - return reachToSet; - } - - private void removeRedundantReachToNodes(Set reachToSet) { - - Set toberemoved = new HashSet(); - for (Iterator iterator = reachToSet.iterator(); iterator.hasNext();) { - HNode cur = (HNode) iterator.next(); - - for (Iterator iterator2 = reachToSet.iterator(); iterator2.hasNext();) { - HNode dst = (HNode) iterator2.next(); - if (!cur.equals(dst) && reachTo(cur, dst)) { - // it is redundant - toberemoved.add(cur); - } - } - } - reachToSet.removeAll(toberemoved); + // TODO + return removeTransitivelyReachToSet(reachToSet); + // return reachToSet; } private void recurSkeletonReachTo(HNode node, Set reachToSet, Set visited) { @@ -788,6 +933,7 @@ public class HierarchyGraph { HNode inNode = (HNode) iterator.next(); if (inNode.isSkeleton()) { + visited.add(inNode); reachToSet.add(inNode); } else if (!visited.contains(inNode)) { visited.add(inNode); @@ -845,9 +991,15 @@ public class HierarchyGraph { clone.setMapHNodeToDescSet(getMapHNodeToDescSet()); clone.setMapHNodetoMergeSet(getMapHNodetoMergeSet()); clone.setMapHNodeToCurrentHNode(getMapHNodeToCurrentHNode()); + clone.setMapHNodeNameToCurrentHNode(getMapHNodeNameToCurrentHNode()); + return clone; } + public void setMapCombineNodeSetToCombinationNode(Map, HNode> in) { + mapCombineNodeSetToCombinationNode = in; + } + public Map> getMapHNodetoMergeSet() { return mapMergeNodetoMergingSet; } @@ -871,12 +1023,48 @@ public class HierarchyGraph { HNode node = (HNode) iterator.next(); if (!node.isSkeleton()) { Set reachToSet = getSkeleteNodeSetReachTo(node); + // Set tempSet = removeTransitivelyReachToSet(reachToSet); + // System.out.println("ALL REACH SET=" + reachToSet); + // reachToSet = removeTransitivelyReachToSet(reachToSet); + + Set curReachToSet = new HashSet(); + for (Iterator iterator2 = reachToSet.iterator(); iterator2.hasNext();) { + HNode reachSkeletonNode = (HNode) iterator2.next(); + curReachToSet.add(getCurrentHNode(reachSkeletonNode)); + } + + // System.out.println("-curReachToSett=" + curReachToSet + " reachToSet=" + reachToSet); + + reachToSet = curReachToSet; + // System.out.println("$node=" + node + " reachToNodeSet=" + reachToSet + " tempSet=" + // + tempSet); if (reachToSet.size() > 1) { // if (countSkeletonNodes(reachToSet) > 1) { - System.out.println("-node=" + node + " reachToSet=" + reachToSet); + System.out.println("\n-node=" + node + " reachToSet=" + reachToSet); System.out.println("-set combinationnode=" + node); node.setCombinationNode(true); mapCombinationNodeToCombineNodeSet.put(node, reachToSet); + + // check if this node is the first node of the chain + // boolean isFirstNodeOfChain = false; + // Set inNodeSet = getIncomingNodeSet(node); + // for (Iterator iterator2 = inNodeSet.iterator(); iterator2.hasNext();) { + // HNode inNode = (HNode) iterator2.next(); + // if (inNode.isSkeleton()) { + // isFirstNodeOfChain = true; + // } else if (inNode.isCombinationNode()) { + // Set inNodeReachToSet = getSkeleteNodeSetReachTo(inNode); + // if (!reachToSet.equals(inNodeReachToSet)) { + // isFirstNodeOfChain = true; + // } + // } + // } + // + // if (isFirstNodeOfChain) { + // node.setDirectCombinationNode(true); + // addFirstNodeOfChain(reachToSet, node); + // } + } } } @@ -893,6 +1081,52 @@ public class HierarchyGraph { } + public void addFirstNodeOfChain(Set combineSet, HNode firstNode) { + + if (!mapCombineNodeSetToFirstNodeOfChainSet.containsKey(combineSet)) { + mapCombineNodeSetToFirstNodeOfChainSet.put(combineSet, new HashSet()); + } + + mapCombineNodeSetToFirstNodeOfChainSet.get(combineSet).add(firstNode); + + } + + public Set getFirstNodeOfCombinationNodeChainSet(Set combineNodeSet) { + return mapCombineNodeSetToFirstNodeOfChainSet.get(combineNodeSet); + } + + private Set removeTransitivelyReachToSet(Set reachToSet) { + + Set toberemoved = new HashSet(); + Set visited = new HashSet(); + for (Iterator iterator = reachToSet.iterator(); iterator.hasNext();) { + HNode node = (HNode) iterator.next(); + visited.add(node); + recurIsReachingTo(node, reachToSet, toberemoved, visited); + } + + Set rSet = new HashSet(); + rSet.addAll(reachToSet); + rSet.removeAll(toberemoved); + return rSet; + } + + private void recurIsReachingTo(HNode curNode, Set reachToSet, Set toberemoved, + Set visited) { + Set inNodeSet = getIncomingNodeSet(curNode); + + for (Iterator iterator = inNodeSet.iterator(); iterator.hasNext();) { + HNode inNode = (HNode) iterator.next(); + if (reachToSet.contains(inNode)) { + toberemoved.add(inNode); + } else if (!visited.contains(inNode)) { + visited.add(inNode); + recurIsReachingTo(inNode, reachToSet, toberemoved, visited); + } + } + + } + public Map> getMapCombinationNodeToCombineNodeSet() { return mapCombinationNodeToCombineNodeSet; } @@ -978,7 +1212,7 @@ public class HierarchyGraph { public void assignUniqueIndexToNode() { int idx = 1; - System.out.println("nodeSet=" + nodeSet); + // System.out.println("nodeSet=" + nodeSet); for (Iterator iterator = nodeSet.iterator(); iterator.hasNext();) { HNode node = (HNode) iterator.next(); mapHNodeToUniqueIndex.put(node, idx); @@ -991,7 +1225,7 @@ public class HierarchyGraph { } } - public BasisSet computeBasisSet() { + public BasisSet computeBasisSet(Set notGenerateSet) { // assign a unique index to a node assignUniqueIndexToNode(); @@ -1000,21 +1234,25 @@ public class HierarchyGraph { for (Iterator iterator = nodeSet.iterator(); iterator.hasNext();) { HNode node = (HNode) iterator.next(); + if (notGenerateSet.contains(node)) { + System.out.println("%%%SKIP =" + node); + continue; + } Set basis = new HashSet(); basis.addAll(BASISTOPELEMENT); Set reachableNodeSet = getReachableNodeSetFrom(node); - System.out.println("node=" + node + " reachableNodeSet=" + reachableNodeSet); - System.out.println("mapHNodeToUniqueIndex.get(node)=" + mapHNodeToUniqueIndex.get(node)); + // System.out.println("node=" + node + " reachableNodeSet=" + reachableNodeSet); + // System.out.println("mapHNodeToUniqueIndex.get(node)=" + mapHNodeToUniqueIndex.get(node)); // if a node is reachable from the current node // need to remove the index of the reachable node from the basis basis.remove(getHNodeIndex(node)); for (Iterator iterator2 = reachableNodeSet.iterator(); iterator2.hasNext();) { HNode reachableNode = (HNode) iterator2.next(); - System.out.println("reachableNode=" + reachableNode); - System.out.println("getHNodeIndex(reachableNode))=" - + mapHNodeToUniqueIndex.get(reachableNode)); + // System.out.println("reachableNode=" + reachableNode); + // System.out.println("getHNodeIndex(reachableNode))=" + // + mapHNodeToUniqueIndex.get(reachableNode)); int idx = getHNodeIndex(reachableNode); basis.remove(idx); } @@ -1065,10 +1303,20 @@ public class HierarchyGraph { } public void writeGraph() { + writeGraph(false); + } + + public void writeGraph(boolean isSimple) { String graphName = "hierarchy" + name; graphName = graphName.replaceAll("[\\W]", ""); + if (isSimple) { + graphName += "_PAPER"; + } + + // System.out.println("***graphName=" + graphName + " node siz=" + nodeSet.size()); + try { BufferedWriter bw = new BufferedWriter(new FileWriter(graphName + ".dot")); @@ -1085,18 +1333,30 @@ public class HierarchyGraph { if (outSet.size() == 0) { if (!addedNodeSet.contains(u)) { - drawNode(bw, u); + if (!isSimple) { + drawNode(bw, u); + } else { + drawNodeName(bw, u); + } addedNodeSet.add(u); } } else { for (Iterator iterator = outSet.iterator(); iterator.hasNext();) { HNode v = (HNode) iterator.next(); if (!addedNodeSet.contains(u)) { - drawNode(bw, u); + if (!isSimple) { + drawNode(bw, u); + } else { + drawNodeName(bw, u); + } addedNodeSet.add(u); } if (!addedNodeSet.contains(v)) { - drawNode(bw, v); + if (!isSimple) { + drawNode(bw, v); + } else { + drawNodeName(bw, v); + } addedNodeSet.add(v); } bw.write("" + u.getName() + " -> " + v.getName() + ";\n"); @@ -1134,11 +1394,17 @@ public class HierarchyGraph { return str; } + private void drawNodeName(BufferedWriter bw, HNode node) throws IOException { + String nodeName = node.getNamePropertyString(); + bw.write(node.getName() + " [label=\"" + nodeName + "\"]" + ";\n"); + } + private void drawNode(BufferedWriter bw, HNode node) throws IOException { String nodeName; if (node.isMergeNode()) { nodeName = node.getNamePropertyString(); Set mergeSet = mapMergeNodetoMergingSet.get(node); + // System.out.println("node=" + node + " mergeSet=" + mergeSet); nodeName += ":" + convertMergeSetToString(mergeSet); } else { nodeName = node.getNamePropertyString(); @@ -1173,4 +1439,205 @@ public class HierarchyGraph { return max; } + public Stack computeDistance2(HNode startNode, Set endNodeSet, + HierarchyGraph scGraph, Set combineSet) { + System.out + .println("#####computeDistanceance startNode=" + startNode + " endNode=" + endNodeSet); + Stack trace = new Stack(); + return recur_computeDistance2(startNode, endNodeSet, scGraph, 0, combineSet, trace); + } + + public Stack computeDistance(HNode startNode, Set endNodeSet, + HierarchyGraph scGraph, Set combineSet) { + System.out + .println("#####computeDistanceance startNode=" + startNode + " endNode=" + endNodeSet); + Stack trace = new Stack(); + return recur_computeDistance(startNode, endNodeSet, 0, combineSet, trace); + } + + private Stack recur_computeDistance(HNode curNode, Set endNodeSet, int count, + Set combineSet, Stack trace) { + + if (!curNode.isSkeleton()) { + if (curNode.isSharedNode()) { + trace.add("S"); + } else { + trace.add("N"); + } + } + + if (endNodeSet.contains(curNode)) { + // it reaches to one of endNodeSet + return trace; + } + + Set inNodeSet = getIncomingNodeSet(curNode); + + int curMaxDistance = 0; + Stack curMaxTrace = (Stack) trace.clone(); + ; + for (Iterator iterator = inNodeSet.iterator(); iterator.hasNext();) { + HNode inNode = (HNode) iterator.next(); + // traverse more... + + if (inNode.isCombinationNode() && combineSet != null) { + // check if inNode have the same combination set of the starting node + Set inNodeCombineSet = getCombineSetByCombinationNode(inNode); + if (!inNodeCombineSet.equals(combineSet)) { + continue; + } + } + + // System.out.println(" traverse more to" + inNode + " before-trace=" + trace); + Stack newTrace = (Stack) trace.clone(); + Stack curTrace = + recur_computeDistance(inNode, endNodeSet, count, combineSet, newTrace); + // System.out.println("curTracerTrace=" + curTrace); + + if (curTrace != null && curTrace.size() > curMaxDistance) { + curMaxTrace = curTrace; + curMaxDistance = curTrace.size(); + } + } + return curMaxTrace; + + } + + private Stack recur_computeDistance2(HNode curNode, Set endNodeSet, + HierarchyGraph scGraph, int count, Set combineSet, Stack trace) { + + if (!curNode.isSkeleton()) { + if (curNode.isSharedNode()) { + trace.add("S"); + } else { + trace.add("N"); + } + } + + System.out.println(" curNode=" + curNode + " curTrace=" + trace); + // System.out.println(" curNode=" + curNode + " curSCNode=" + // + scGraph.getCurrentHNode(curNode) + " contains=" + // + endNodeSet.contains(scGraph.getCurrentHNode(curNode))); + if (endNodeSet.contains(scGraph.getCurrentHNode(curNode))) { + // it reaches to one of endNodeSet + return trace; + } + + Set inNodeSet = getIncomingNodeSet(curNode); + + int curMaxDistance = 0; + Stack curMaxTrace = (Stack) trace.clone(); + ; + for (Iterator iterator = inNodeSet.iterator(); iterator.hasNext();) { + HNode inNode = (HNode) iterator.next(); + // traverse more... + + if (inNode.isCombinationNode() && combineSet != null) { + // check if inNode have the same combination set of the starting node + Set inNodeCombineSet = getCombineSetByCombinationNode(inNode); + if (!inNodeCombineSet.equals(combineSet)) { + continue; + } + } + + // Stack newTrace = (Stack) trace.clone(); + // Stack curTrace = + // recur_computeDistance(inNode, endNodeSet, scGraph, count, combineSet, newTrace); + // if (curTrace != null) { + // return curTrace; + // } + + Set inReachToNodeSet = getSkeleteNodeSetReachToNoTransitive(inNode); + Set inCurReachToNodeSet = new HashSet(); + for (Iterator iterator2 = inReachToNodeSet.iterator(); iterator2.hasNext();) { + HNode aboveNode = (HNode) iterator2.next(); + inCurReachToNodeSet.add(getCurrentHNode(aboveNode)); + } + + if (combineSet != null || inCurReachToNodeSet.equals(endNodeSet)) { + System.out + .println(" traverse to incomingNode=" + inNode + " before-trace=" + trace); + + Stack newTrace = (Stack) trace.clone(); + Stack curTrace = + recur_computeDistance2(inNode, endNodeSet, scGraph, count, combineSet, newTrace); + + if (curTrace != null && curTrace.size() > curMaxDistance) { + curMaxTrace = curTrace; + curMaxDistance = curTrace.size(); + } + } else { + System.out.println("NOT TRAVERSE a new inNode=" + inNode + " inReachToNodeSet=" + + inCurReachToNodeSet); + } + + } + return curMaxTrace; + } + + public int countNonSharedNode(HNode startNode, Set endNodeSet) { + System.out.println("countNonSharedNode startNode=" + startNode + " endNode=" + endNodeSet); + return recur_countNonSharedNode(startNode, endNodeSet, 0); + } + + private int recur_countNonSharedNode(HNode startNode, Set endNodeSet, int count) { + + Set inNodeSet = getIncomingNodeSet(startNode); + + for (Iterator iterator = inNodeSet.iterator(); iterator.hasNext();) { + HNode inNode = (HNode) iterator.next(); + if (endNodeSet.contains(inNode)) { + count++; + return count; + } else { + if (!inNode.isSharedNode()) { + count++; + } + return recur_countNonSharedNode2(inNode, endNodeSet, count); + } + } + + return 0; + } + + public int countNonSharedNode2(HNode startNode, Set endNodeSet) { + System.out.println("countNonSharedNode startNode=" + startNode + " endNode=" + endNodeSet); + return recur_countNonSharedNode2(startNode, endNodeSet, 0); + } + + private int recur_countNonSharedNode2(HNode startNode, Set endNodeSet, int count) { + + Set inNodeSet = getIncomingNodeSet(startNode); + + if (inNodeSet.size() == 0) { + // it is directly connected to the TOP node + } + + for (Iterator iterator = inNodeSet.iterator(); iterator.hasNext();) { + HNode inNode = (HNode) iterator.next(); + if (endNodeSet.contains(inNode)) { + return count; + } else { + if (!inNode.isSharedNode()) { + count++; + } + return recur_countNonSharedNode2(inNode, endNodeSet, count); + } + } + + // System.out.println("startNode=" + startNode + " inNodeSet=" + inNodeSet); + // HNode inNode = inNodeSet.iterator().next(); + return -1; + } + + public void removeIsolatedNodes() { + Set toberemoved = new HashSet(); + for (Iterator iterator = nodeSet.iterator(); iterator.hasNext();) { + HNode node = (HNode) iterator.next(); + if (getIncomingNodeSet(node).isEmpty() && getOutgoingNodeSet(node).isEmpty()) { + toberemoved.add(node); + } + } + nodeSet.removeAll(toberemoved); + } }