Beispiel #1
0
 /** Propagate the results of adding a link from this node to the target node. */
 public void propagateAdd(GraphNode target) {
   Set<GraphNode> sc = new HashSet<>(target.succClosed);
   sc.add(target);
   visitPredecessors(
       new Visitor<Set<GraphNode>, GraphNode>() {
         @Override
         public List<GraphNode> visit(
             GraphNode node, GraphNode processing, Set<GraphNode> sc, GraphNode target) {
           // Add closure
           node.succClosed.addAll(sc);
           // Scan for redundant links
           List<GraphNode> kill = null;
           for (Iterator<GraphNode> i = node.succ.iterator(); i.hasNext(); ) {
             GraphNode s = i.next();
             if (sc.contains(s)) {
               i.remove();
               if (s == processing) {
                 // Can't remove immediately w/o beaking the visitor loop
                 if (kill == null) kill = new ArrayList<>();
                 kill.add(node);
               } else {
                 s.pred.remove(node);
               }
             }
           }
           return kill;
         }
       },
       sc,
       target);
 }
Beispiel #2
0
 /** Propagate the results of creating a new SCC with this node as lead. */
 public void propagateSCC() {
   Set<GraphNode> visited = new HashSet<>();
   visited.add(this);
   // Scan predecessors not including ourselves
   doVisitPredecessors(
       new Visitor<Set<GraphNode>, Object>() {
         @Override
         public List<GraphNode> visit(
             GraphNode node, GraphNode processing, Set<GraphNode> sc, Object ignored) {
           // Add closure
           node.succClosed.addAll(sc);
           // Scan for redundant links
           List<GraphNode> kill = null;
           for (Iterator<GraphNode> i = node.succ.iterator(); i.hasNext(); ) {
             GraphNode s = i.next();
             if (sc.contains(s)) {
               i.remove();
               //                            s.pred.remove(node);
               if (s == processing) {
                 // Can't remove immediately w/o beaking the visitor loop
                 if (kill == null) kill = new ArrayList<>();
                 kill.add(node);
               } else {
                 s.pred.remove(node);
               }
             }
           }
           return kill;
         }
       },
       succClosed,
       null,
       visited);
 }
Beispiel #3
0
 /** Create a list of triples for a given set of successors to this node. */
 private List<Triple> triplesForSuccessors(Node base, boolean closed, TransitiveGraphCache tgc) {
   Set<GraphNode> successors = closed ? succClosed : succ;
   ArrayList<Triple> result = new ArrayList<>(successors.size() + 10);
   result.add(new Triple(base, tgc.closedPredicate, base)); // implicit reflexive case
   for (GraphNode s : successors) {
     result.add(new Triple(base, tgc.closedPredicate, s.rdfNode));
     s.siblings.addSuccessors(base, tgc, result);
   }
   siblings.addSuccessors(base, tgc, result);
   return result;
 }
Beispiel #4
0
  /**
   * Given a set of SCC nodes make this the lead member of the SCC and reroute all incoming and
   * outgoing links accordingly. This eager rewrite is based on the assumption that there are few
   * cycles so it is better to rewrite once and keep the graph easy to traverse.
   */
  public void makeLeadNodeFor(Set<GraphNode> members) {
    // Accumulate all successors
    Set<GraphNode> newSucc = new HashSet<>();
    Set<GraphNode> newSuccClosed = new HashSet<>();
    for (GraphNode n : members) {
      newSucc.addAll(n.succ);
      newSuccClosed.addAll(n.succClosed);
    }
    newSucc.removeAll(members);
    newSuccClosed.removeAll(members);
    succ = newSucc;
    succClosed = newSuccClosed;

    // Rewrite all direct successors to have us as predecessor
    for (GraphNode n : succ) {
      n.pred.removeAll(members);
      n.pred.add(this);
    }

    // Find all predecessor nodes and relink link them to point to us
    Set<GraphNode> done = new HashSet<>();
    Set<GraphNode> newAliases = new HashSet<>();
    for (GraphNode member : members) {
      addSiblings(newAliases, member);
    }
    becomeLeaderOf(newAliases);
    for (GraphNode n : members) {
      if (n != this) {
        pred.addAll(n.pred);
        n.relocateAllRefTo(this, done);
        n.becomeSubordinateOf(this);
      }
    }
    pred.removeAll(members);
  }
Beispiel #5
0
 /** Visit each predecessor of this node applying the given visitor. Breadth first. */
 private <Alpha, Beta> void doVisitPredecessors(
     Visitor<Alpha, Beta> visitor, Alpha arg1, Beta arg2, Set<GraphNode> seen) {
   if (seen.add(this)) {
     Collection<GraphNode> allKill = null;
     for (Iterator<GraphNode> i = pred.iterator(); i.hasNext(); ) {
       GraphNode pred = i.next();
       List<GraphNode> kill = visitor.visit(pred, this, arg1, arg2);
       if (kill != null) {
         if (allKill == null) allKill = new ArrayList<GraphNode>();
         allKill.addAll(kill);
       }
     }
     if (allKill != null) pred.removeAll(allKill);
     for (Iterator<GraphNode> i = pred.iterator(); i.hasNext(); ) {
       GraphNode pred = i.next();
       pred.doVisitPredecessors(visitor, arg1, arg2, seen);
     }
   }
 }
Beispiel #6
0
 @Override
 void addInto(Set<GraphNode> nodes, GraphNode ignored) {
   nodes.addAll(components);
 }
Beispiel #7
0
 void addInto(Set<GraphNode> nodes, GraphNode m) {
   nodes.add(m);
 }
Beispiel #8
0
 /** Assert an inferred indirect link from this node to the given traget */
 public void assertIndirectLinkTo(GraphNode target) {
   //            if (this == target) return;
   succClosed.add(target);
   clearTripleCache();
 }
Beispiel #9
0
 /**
  * Remove a direct link currently from this node to the given target. Does not update the closed
  * successor cache.
  */
 public void retractLinkTo(GraphNode target) {
   if (this == target) return;
   succ.remove(target);
   target.pred.remove(this);
   clearTripleCache();
 }
Beispiel #10
0
 /**
  * Assert a direct link between this node and this given target. Does not update the closed
  * successor cache
  */
 public void assertLinkTo(GraphNode target) {
   if (this == target) return;
   succ.add(target);
   target.pred.add(this);
   clearTripleCache();
 }
Beispiel #11
0
 /**
  * Return an iterator over all the indirect successors of this node. This does NOT include aliases
  * of successors and is used for graph maintenance.
  */
 public Iterator<GraphNode> iteratorOverSuccessors() {
   return succClosed.iterator();
 }
Beispiel #12
0
 /** Visit each predecessor of this node applying the given visitor. */
 public <Alpha, Beta> void visitPredecessors(Visitor<Alpha, Beta> visitor, Alpha arg1, Beta arg2) {
   List<GraphNode> kill = visitor.visit(this, null, arg1, arg2);
   if (kill != null) pred.removeAll(kill);
   doVisitPredecessors(visitor, arg1, arg2, new HashSet<GraphNode>());
 }
Beispiel #13
0
 /** Return true if there is a direct path from this node to the argument node. */
 public boolean directPathTo(GraphNode A) {
   if (this == A) return true;
   return succ.contains(A);
 }
Beispiel #14
0
 /** Return true if there is a path from this node to the argument node. */
 public boolean pathTo(GraphNode A) {
   if (this == A) return true;
   return succClosed.contains(A);
 }
Beispiel #15
0
 @Override
 Iterator<GraphNode> siblingIterator() {
   return components.iterator();
 }