import Analysis.Disjoint.HeapAnalysis;
import Analysis.CallGraph.CallGraph;
import Analysis.OoOJava.RBlockRelationAnalysis;
+import Analysis.OoOJava.Accessible;
import Analysis.Disjoint.ExistPred;
import Analysis.Disjoint.ReachGraph;
import Analysis.Disjoint.EffectsAnalysis;
HashMap<FlatCall, Set<BBlock>> callMap;
HashMap<BBlock, Set<PPoint>> returnMap;
HashMap<BBlock, Set<TempDescriptor>> bblivetemps;
+ HashSet<FlatNode> mustProcess;
private boolean OoOJava=false;
CallGraph callGraph;
TempDescriptor returntmp;
RBlockRelationAnalysis taskAnalysis;
EffectsAnalysis effectsAnalysis;
+ Accessible accessible;
- public Pointer(State state, TypeUtil typeUtil, CallGraph callGraph, RBlockRelationAnalysis taskAnalysis) {
+ public Pointer(State state, TypeUtil typeUtil, CallGraph callGraph, RBlockRelationAnalysis taskAnalysis, Liveness liveness, BuildStateMachines bsm) {
this(state, typeUtil);
this.callGraph=callGraph;
this.OoOJava=true;
this.taskAnalysis=taskAnalysis;
this.effectsAnalysis=new EffectsAnalysis();
effectsAnalysis.state=state;
- effectsAnalysis.buildStateMachines=new BuildStateMachines();
+ effectsAnalysis.buildStateMachines=bsm;
+ accessible=new Accessible(state, callGraph, taskAnalysis, liveness);
+ accessible.doAnalysis();
+ State.logEvent("Done Writing Accessible Analysis");
}
public Pointer(State state, TypeUtil typeUtil) {
this.toprocess=new LinkedList<Delta>();
ClassDescriptor stringcd=typeUtil.getClass(TypeUtil.ObjectClass);
this.returntmp=new TempDescriptor("RETURNVAL", stringcd);
+ this.mustProcess=new HashSet<FlatNode>();
}
public EffectsAnalysis getEffectsAnalysis() {
}
public void doAnalysis() {
- double timeStartAnalysis = (double) System.nanoTime();
toprocess.add(buildInitialContext());
nextdelta:
if (!init&&delta.isEmpty())
continue nextdelta;
+ int lasti=-1;
//Compute delta at exit of each node
for(int i=startindex; i<nodes.size();i++) {
FlatNode currNode=nodes.get(i);
//System.out.println("Start Processing "+currNode);
+
if (!graphMap.containsKey(currNode)) {
- if (isNEEDED(currNode))
+ if (isNEEDED(currNode)) {
graphMap.put(currNode, new Graph(graph));
- else {
- if (i==0) {
- //base graph works for us
- graphMap.put(currNode, new Graph(graph));
- } else {
- //just use previous graph
- graphMap.put(currNode, graphMap.get(nodes.get(i-1)));
+ } else {
+ boolean fallthru=true;
+ if (isINACC(currNode)&&((lasti==-1)||(lasti==i))) {
+ if (lasti==-1) {
+ for(lasti=nodes.size()-1;lasti>=i;lasti--) {
+ FlatNode scurrNode=nodes.get(lasti);
+ if (isNEEDED(scurrNode)||isINACC(scurrNode)) {
+ break;
+ }
+ }
+ }
+ if (i==lasti) {
+ mustProcess.add(currNode);
+ graphMap.put(currNode, new Graph(graph));
+ fallthru=false;
+ }
+ }
+ if (fallthru) {
+ if (i==0) {
+ //base graph works for us
+ graphMap.put(currNode, new Graph(graph));
+ } else {
+ //just use previous graph
+ graphMap.put(currNode, graphMap.get(nodes.get(i-1)));
+ }
}
}
}
+
nodeGraph=graphMap.get(currNode);
delta=processNode(bblock, i, currNode, delta, nodeGraph);
//System.out.println("Processing "+currNode+" and generating delta:");
}
//DEBUG
- if (true) {
+ if (false) {
int debugindex=0;
for(Map.Entry<BBlock, Graph> e:bbgraphMap.entrySet()) {
Graph g=e.getValue();
}
}
- double timeEndAnalysis = (double) System.nanoTime();
- double dt = (timeEndAnalysis - timeStartAnalysis)/(Math.pow( 10.0, 9.0 ) );
- System.out.println("Time taken: "+dt);
+ State.logEvent("Done With Pointer Analysis");
+
if (OoOJava) {
effectsAnalysis.buildStateMachines.writeStateMachines();
+ State.logEvent("Done Writing State Machines");
}
}
/* Compute ages */
if (graph.oldNodes.containsKey(node)) {
-
+ if (graph.oldNodes.get(node).booleanValue())
+ newDelta.addOldNodes.put(node, Boolean.TRUE);
} else if (graph.parent.oldNodes.containsKey(node)) {
//parent graphs only contain true...no need to check
newDelta.addOldNodes.put(node, Boolean.TRUE);
}
}
- for(AllocNode node:graph.oldNodes.keySet()) {
- if (graph.oldNodes.get(node).booleanValue())
- newDelta.addOldNodes.put(node, Boolean.TRUE);
- }
-
- for(AllocNode node:graph.parent.oldNodes.keySet()) {
- //make sure child doesn't override
- if (!graph.oldNodes.containsKey(node))
- newDelta.addOldNodes.put(node, Boolean.TRUE);
- }
-
newDelta.addNodeAges.addAll(graph.nodeAges);
newDelta.addNodeAges.addAll(graph.parent.nodeAges);
}
if (delta.getInit()) {
removeInitTaints(null, delta, graph);
for (TempDescriptor tmp:sese.getInVarSet()) {
- System.out.println("TMP variable:"+tmp);
- Taint taint=Taint.factory(sese, null, tmp, AllocFactory.dummyNode, sese, ReachGraph.predsEmpty);
+ Taint taint=Taint.factory(sese, null, tmp, AllocFactory.dummySite, null, ReachGraph.predsEmpty);
MySet<Edge> edges=GraphManip.getEdges(graph, delta, tmp);
for(Edge e:edges) {
Edge newe=e.addTaint(taint);
delta.addVarEdge(newe);
- System.out.println("Adding Edge:"+newe);
}
}
} else {
removeDiffTaints(null, delta);
for (TempDescriptor tmp:sese.getInVarSet()) {
- System.out.println("TMP variable:"+tmp);
- Taint taint=Taint.factory(sese, null, tmp, AllocFactory.dummyNode, sese, ReachGraph.predsEmpty);
+ Taint taint=Taint.factory(sese, null, tmp, AllocFactory.dummySite, null, ReachGraph.predsEmpty);
MySet<Edge> edges=GraphManip.getDiffEdges(delta, tmp);
for(Edge e:edges) {
Edge newe=e.addTaint(taint);
delta.addVarEdge(newe);
- System.out.println("DAdding Edge:"+newe);
}
}
}
AllocNode node=tovisit.pop();
MySet<Edge> edges=GraphManip.getEdges(graph, delta, node);
if (!edges.isEmpty()) {
- newDelta.heapedgeadd.put(node, edges);
+ newDelta.heapedgeadd.put(node, Edge.makeOld(edges));
edgeset.addAll(edges);
for(Edge e:edges) {
if (!nodeset.contains(e.dst)&&(oldnodeset==null||!oldnodeset.contains(e.dst))) {
TempDescriptor tmpthis=fcall.getThis();
MethodDescriptor md=fcall.getMethod();
HashSet<MethodDescriptor> targets=new HashSet<MethodDescriptor>();
- if (md.isStatic()) {
+ if (md.isStatic()||fcall.getSuper()) {
targets.add(md);
} else {
//Compute Edges
graph.callTargets=newtargets;
graph.callNodeAges=new HashSet<AllocNode>();
graph.callOldNodes=new HashSet<AllocNode>();
+ graph.callNewEdges=new HashMap<AllocNode, MySet<Edge>>();
+ graph.callOldEdges=new HashMap<Edge,MySet<Edge>>();
//Apply diffs to graph
applyDiffs(graph, delta, true);
if (!newDelta.heapedgeadd.containsKey(src)) {
newDelta.heapedgeadd.put(src, new MySet<Edge>());
}
- newDelta.heapedgeadd.get(src).add(e);
+ newDelta.heapedgeadd.get(src).add(e.makeOld());
if (!nodeset.contains(e.dst)&&!oldnodeset.contains(e.dst)) {
nodeset.add(e.dst);
tovisit.add(e.dst);
//Compute call targets
HashSet<MethodDescriptor> newtargets=computeTargets(fcall, newDelta);
graph.callTargets.addAll(newtargets);
+
//add in new nodeset and edgeset
oldnodeset.addAll(nodeset);
oldedgeset.addAll(edgeset);
//Move new edges that should be summarized
processSummarization(graph, delta);
-
+
+ Set<FlatSESEEnterNode> seseCallers=OoOJava?taskAnalysis.getTransitiveExecutingRBlocks(fcall):null;
+ //Check if the new nodes allow us to insert a new edge
+ for(AllocNode node:nodeset) {
+ if (graph.callNewEdges.containsKey(node)) {
+ for(Iterator<Edge> eit=graph.callNewEdges.get(node).iterator();eit.hasNext();) {
+ Edge e=eit.next();
+ if ((graph.callNodeAges.contains(e.src)||graph.reachNode.contains(e.src))&&
+ (graph.callNodeAges.contains(e.dst)||graph.reachNode.contains(e.dst))) {
+ Edge edgetoadd=e.copy();//we need our own copy to modify below
+ eit.remove();
+ if (seseCallers!=null)
+ edgetoadd.taintModify(seseCallers);
+ mergeCallEdge(graph, delta, edgetoadd);
+ }
+ }
+ }
+ }
+
+ for(Edge e:edgeset) {
+ //See if these edges would allow an old edge to be added
+ if (graph.callOldEdges.containsKey(e)) {
+ for(Edge adde:graph.callOldEdges.get(e)) {
+ Edge ecopy=adde.copy();
+ ecopy.statuspredicate=e.statuspredicate;
+ mergeCallEdge(graph, delta, ecopy);
+ }
+ }
+ }
+
//Add in new external edges
graph.externalEdgeSet.addAll(externaledgeset);
//Apply diffs to graph
}
}
for(Edge e:edgestoremove) {
- delta.removeVarEdge(e);
+ if (!graph.callerEdges.contains(e))
+ delta.removeVarEdge(e);
}
for(Edge e:edgestoadd) {
delta.addVarEdge(e);
}
}
-
+
public Alloc getAllocationSiteFromFlatNew(FlatNew node) {
- return allocFactory.getAllocNode(node, false);
+ return allocFactory.getAllocNode(node, false).getAllocSite();
}
void processSumHeapEdgeSet(HashMap<AllocNode, MySet<Edge>> map, Delta delta, Graph graph) {
}
}
for(Edge e:edgestoremove) {
- delta.removeHeapEdge(e);
+ if (!graph.callerEdges.contains(e))
+ delta.removeHeapEdge(e);
}
for(Edge e:edgestoadd) {
delta.addHeapEdge(e);
/* Need to age node in existing graph*/
summarizeInGraph(graph, newDelta, node);
}
+ if (graph.callNewEdges.containsKey(node)) {
+ for(Iterator<Edge> eit=graph.callNewEdges.get(node).iterator();eit.hasNext();) {
+ Edge e=eit.next();
+ if ((graph.callNodeAges.contains(e.src)||graph.reachNode.contains(e.src))&&
+ (graph.callNodeAges.contains(e.dst)||graph.reachNode.contains(e.dst))) {
+ Edge edgetoadd=e.copy();//we need our own copy to modify below
+ eit.remove();
+ if (seseCallers!=null)
+ edgetoadd.taintModify(seseCallers);
+ mergeCallEdge(graph, newDelta, edgetoadd);
+ }
+ }
+ }
}
+
//Add heap edges in
for(Map.Entry<AllocNode, MySet<Edge>> entry:delta.heapedgeadd.entrySet()) {
for(Edge e:entry.getValue()) {
boolean addedge=false;
Edge edgetoadd=null;
if (e.statuspredicate==Edge.NEW) {
- edgetoadd=e;
+ if ((graph.callNodeAges.contains(e.src)||graph.reachNode.contains(e.src))&&
+ (graph.callNodeAges.contains(e.dst)||graph.reachNode.contains(e.dst))) {
+ edgetoadd=e.copy();//we need our own copy to modify below
+ } else {
+ graph.addCallEdge(e);
+ }
} else {
- Edge origEdgeKey=e.makeStatus(allocFactory);
- if (oldgraph.nodeMap.containsKey(origEdgeKey.src)&&
- oldgraph.nodeMap.get(origEdgeKey.src).contains(origEdgeKey)) {
- Edge origEdge=oldgraph.nodeMap.get(origEdgeKey.src).get(origEdgeKey);
- //copy the predicate
- origEdgeKey.statuspredicate=origEdge.statuspredicate;
- edgetoadd=origEdgeKey;
+ Edge[] edgeArray=e.makeStatus(allocFactory);
+
+ int statuspredicate=0;
+ for(int i=0;i<edgeArray.length;i++) {
+ Edge origEdgeKey=edgeArray[i];
+ if (graph.reachEdge.contains(origEdgeKey)) {
+ Edge origEdge=graph.reachEdge.get(origEdgeKey);
+ //copy the predicate
+ statuspredicate=statuspredicate|origEdge.statuspredicate;
+ }
+ if (!graph.callOldEdges.containsKey(origEdgeKey)) {
+ graph.callOldEdges.put(origEdgeKey, new MySet<Edge>());
+ }
+ if (graph.callOldEdges.get(origEdgeKey).contains(e)) {
+ Edge olde=graph.callOldEdges.get(origEdgeKey).get(e);
+ graph.callOldEdges.get(origEdgeKey).add(olde.merge(e));
+ } else {
+ graph.callOldEdges.get(origEdgeKey).add(e);
+ }
+ }
+ if (statuspredicate!=0) {
+ Edge newe=e.copy();
+ newe.statuspredicate=statuspredicate;
+ edgetoadd=newe;
}
}
if (seseCallers!=null&&edgetoadd!=null)
public void mergeCallEdge(Graph graph, Delta newDelta, Edge edgetoadd) {
if (edgetoadd!=null) {
- Edge match=graph.getMatch(edgetoadd);
+ newDelta.addEdgeClear(edgetoadd);
+ Edge match=graph.getMatch(edgetoadd);
+
if (match==null||!match.subsumes(edgetoadd)) {
Edge mergededge=edgetoadd.merge(match);
newDelta.addEdge(mergededge);
graph.callerEdges.add(mergededge);
- //System.out.println("ADDING: "+ mergededge);
}
}
}
for(Map.Entry<TempDescriptor, MySet<Edge>> e: delta.varedgeadd.entrySet()) {
TempDescriptor tmp=e.getKey();
MySet<Edge> edgestoadd=e.getValue();
- System.out.println("ADDING:"+edgestoadd);
if (graph.varMap.containsKey(tmp)) {
Edge.mergeEdgesInto(graph.varMap.get(tmp), edgestoadd);
} else
}
}
+ boolean isINACC(FlatNode node) {
+ if (!OoOJava)
+ return false;
+ switch(node.kind()) {
+ case FKind.FlatSetFieldNode: {
+ FlatSetFieldNode n=(FlatSetFieldNode)node;
+ return !accessible.isAccessible(n, n.getDst());
+ }
+ case FKind.FlatSetElementNode: {
+ FlatSetElementNode n=(FlatSetElementNode)node;
+ return !accessible.isAccessible(n, n.getDst());
+ }
+ case FKind.FlatFieldNode: {
+ FlatFieldNode n=(FlatFieldNode)node;
+ return !accessible.isAccessible(n, n.getSrc());
+ }
+ case FKind.FlatElementNode: {
+ FlatElementNode n=(FlatElementNode)node;
+ return !accessible.isAccessible(n, n.getSrc());
+ }
+ }
+ return false;
+ }
+
Delta processSetFieldElementNode(FlatNode node, Delta delta, Graph graph) {
TempDescriptor src;
FieldDescriptor fd;
fd=ffn.getField();
dst=ffn.getDst();
}
- //Do nothing for non pointers
- if (!src.getType().isPtr())
- return delta;
if (delta.getInit()) {
- MySet<Edge> srcEdges=GraphManip.getEdges(graph, delta, src);
MySet<Edge> dstEdges=GraphManip.getEdges(graph, delta, dst);
+
+ if (OoOJava&&!accessible.isAccessible(node, dst)) {
+ Taint dstStallTaint=Taint.factory(node, dst, AllocFactory.dummySite, null, ReachGraph.predsEmpty);
+ dstEdges=Edge.taintAll(dstEdges, dstStallTaint);
+ updateVarDelta(graph, delta, dst, dstEdges, null);
+ }
+ if (OoOJava) {
+ effectsAnalysis.analyzeFlatSetFieldNode(dstEdges, fd, node);
+ }
+
+ //Do nothing for non pointers
+ if (!src.getType().isPtr()) {
+ if (mustProcess.contains(node)) {
+ applyDiffs(graph, delta);
+ }
+ return delta;
+ }
+
+ MySet<Edge> srcEdges=GraphManip.getEdges(graph, delta, src);
+ if (OoOJava&&!accessible.isAccessible(node, src)) {
+ Taint srcStallTaint=Taint.factory(node, src, AllocFactory.dummySite, null, ReachGraph.predsEmpty);
+ srcEdges=Edge.taintAll(srcEdges, srcStallTaint);
+ updateVarDelta(graph, delta, src, srcEdges, null);
+ }
+
MySet<Edge> edgesToAdd=GraphManip.genEdges(dstEdges, fd, srcEdges);
MySet<Edge> edgesToRemove=null;
if (dstEdges.size()==1&&!dstEdges.iterator().next().dst.isSummary()&&fd!=null) {
} else
graph.strongUpdateSet=new MySet<Edge>();
- if (OoOJava) {
- effectsAnalysis.analyzeFlatSetFieldNode(dstEdges, fd, node);
- }
-
/* Update diff */
updateHeapDelta(graph, delta, edgesToAdd, edgesToRemove);
applyDiffs(graph, delta);
} else {
- /* First look at new sources */
+ MySet<Edge> newDstEdges=GraphManip.getDiffEdges(delta, dst);
+
+ if (OoOJava&&!accessible.isAccessible(node, dst)) {
+ Taint dstStallTaint=Taint.factory(node, dst, AllocFactory.dummySite, null, ReachGraph.predsEmpty);
+ newDstEdges=Edge.taintAll(newDstEdges, dstStallTaint);
+ updateVarDelta(graph, delta, dst, newDstEdges, null);
+ }
+
+ if (OoOJava) {
+ effectsAnalysis.analyzeFlatSetFieldNode(newDstEdges, fd, node);
+ }
+
+ if (!src.getType().isPtr()) {
+ if (mustProcess.contains(node)) {
+ applyDiffs(graph, delta);
+ }
+ return delta;
+ }
+
+ /* Next look at new sources */
+
MySet<Edge> edgesToAdd=new MySet<Edge>();
MySet<Edge> newSrcEdges=GraphManip.getDiffEdges(delta, src);
MySet<Edge> srcEdges=GraphManip.getEdges(graph, delta, src);
HashSet<AllocNode> dstNodes=GraphManip.getNodes(graph, delta, dst);
- MySet<Edge> newDstEdges=GraphManip.getDiffEdges(delta, dst);
- if (OoOJava) {
- effectsAnalysis.analyzeFlatSetFieldNode(newDstEdges, fd, node);
+ if (OoOJava&&!accessible.isAccessible(node, src)) {
+ Taint srcStallTaint=Taint.factory(node, src, AllocFactory.dummySite, null, ReachGraph.predsEmpty);
+ newSrcEdges=Edge.taintAll(newSrcEdges, srcStallTaint);
+ updateVarDelta(graph, delta, src, newSrcEdges, null);
}
MySet<Edge> edgesToRemove=null;
fd=ffn.getField();
dst=ffn.getDst();
}
- if (OoOJava&&taskAnalysis.isPotentialStallSite(node)) {
- taint=TaintSet.factory(Taint.factory(node, src, AllocFactory.dummyNode, null, ReachGraph.predsEmpty));
+ if (OoOJava&&!accessible.isAccessible(node, src)) {
+ taint=TaintSet.factory(Taint.factory(node, src, AllocFactory.dummySite, null, ReachGraph.predsEmpty));
}
//Do nothing for non pointers
- if (!dst.getType().isPtr())
- return delta;
if (delta.getInit()) {
MySet<Edge> srcedges=GraphManip.getEdges(graph, delta, src);
- MySet<Edge> edgesToAdd=GraphManip.dereference(graph, delta, dst, srcedges, fd, node, taint);
- MySet<Edge> edgesToRemove=GraphManip.getEdges(graph, delta, dst);
- if (OoOJava)
+ if (OoOJava) {
+ if (taint!=null) {
+ srcedges=Edge.taintAll(srcedges, taint);
+ updateVarDelta(graph, delta, src, srcedges, null);
+ }
effectsAnalysis.analyzeFlatFieldNode(srcedges, fd, node);
+ }
+ if (!dst.getType().isPtr()) {
+ if (mustProcess.contains(node)) {
+ applyDiffs(graph, delta);
+ }
+ return delta;
+ }
+
+ MySet<Edge> edgesToAdd=GraphManip.dereference(graph, delta, dst, srcedges, fd, node);
+ MySet<Edge> edgesToRemove=GraphManip.getEdges(graph, delta, dst);
updateVarDelta(graph, delta, dst, edgesToAdd, edgesToRemove);
applyDiffs(graph, delta);
} else {
+ MySet<Edge> newsrcedges=GraphManip.getDiffEdges(delta, src);
+ if (OoOJava) {
+ if (taint!=null) {
+ newsrcedges=Edge.taintAll(newsrcedges, taint);
+ updateVarDelta(graph, delta, src, newsrcedges, null);
+ }
+ effectsAnalysis.analyzeFlatFieldNode(newsrcedges, fd, node);
+ }
+ if (!dst.getType().isPtr()) {
+ if (mustProcess.contains(node)) {
+ applyDiffs(graph, delta);
+ }
+ return delta;
+ }
/* First compute new objects we read fields of */
MySet<Edge> allsrcedges=GraphManip.getEdges(graph, delta, src);
- MySet<Edge> edgesToAdd=GraphManip.diffDereference(delta, dst, allsrcedges, fd, node, taint);
+ MySet<Edge> edgesToAdd=GraphManip.diffDereference(delta, dst, allsrcedges, fd, node);
/* Next compute new targets of fields */
- MySet<Edge> newsrcedges=GraphManip.getDiffEdges(delta, src);
- MySet<Edge> newfdedges=GraphManip.dereference(graph, delta, dst, newsrcedges, fd, node, taint);
+ MySet<Edge> newfdedges=GraphManip.dereference(graph, delta, dst, newsrcedges, fd, node);
/* Compute the union, and then the set of edges */
Edge.mergeEdgesInto(edgesToAdd, newfdedges);
/* Compute set of edges to remove */
MySet<Edge> edgesToRemove=GraphManip.getDiffEdges(delta, dst);
- if (OoOJava)
- effectsAnalysis.analyzeFlatFieldNode(newsrcedges, fd, node);
/* Update diff */
updateVarDelta(graph, delta, dst, edgesToAdd, edgesToRemove);
MySet<Edge> edgeAdd=delta.varedgeadd.get(tmp);
MySet<Edge> edgeRemove=delta.varedgeremove.get(tmp);
MySet<Edge> existingEdges=graph.getEdges(tmp);
- for(Edge e: edgestoRemove) {
- //remove edge from delta
- if (edgeAdd!=null)
- edgeAdd.remove(e);
- //if the edge is already in the graph, add an explicit remove to the delta
- if (existingEdges.contains(e))
- delta.removeVarEdge(e);
- }
+ if (edgestoRemove!=null)
+ for(Edge e: edgestoRemove) {
+ //remove edge from delta
+ if (edgeAdd!=null)
+ edgeAdd.remove(e);
+ //if the edge is already in the graph, add an explicit remove to the delta
+ if (existingEdges.contains(e))
+ delta.removeVarEdge(e);
+ }
for(Edge e: edgestoAdd) {
//Remove the edge from the remove set
if (edgeRemove!=null)
edgeRemove.remove(e);
//Explicitly add it to the add set unless it is already in the graph
- if (!existingEdges.contains(e)&&typeUtil.isSuperorType(tmp.getType(),e.dst.getType()))
- delta.addVarEdge(e);
+ if (typeUtil.isSuperorType(tmp.getType(), e.dst.getType())) {
+ if (!existingEdges.contains(e)) {
+ delta.addVarEdge(e);
+ } else {
+ //See if the old edge subsumes the new one
+ Edge olde=existingEdges.get(e);
+ if (!olde.subsumes(e)) {
+ delta.addVarEdge(olde.merge(e));
+ }
+ }
+ }
}
}
if (edgeRemove!=null)
edgeRemove.remove(e);
//Explicitly add it to the add set unless it is already in the graph
- if (!existingEdges.contains(e)||!existingEdges.get(e).isNew()) {
+ if (!existingEdges.contains(e)) {
delta.addHeapEdge(e);
+ } else {
+ //See if the old edge subsumes the new one
+ Edge olde=existingEdges.get(e);
+ if (!olde.subsumes(e)) {
+ delta.addHeapEdge(olde.merge(e));
+ }
}
}
}
delta.addOldNodes.put(single, Boolean.FALSE);
}
- //Apply incoming diffs to graph
- applyDiffs(graph, delta);
}
+ //Apply incoming diffs to graph
+ applyDiffs(graph, delta);
+
return delta;
}