/** 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); } } }
/** * Compile all the rules in a table. initially just indexed on predicate but want to add better * indexing for the particular cases of wildcard rules and type rules. */ protected void compileAll() { isCompiled = true; predicateToCodeMap = new HashMap<>(); allRuleClauseCodes = new ArrayList<>(); indexPredicateToCodeMap = new HashMap<>(); for (Rule r : getAllRules()) { ClauseEntry term = r.getHeadElement(0); if (term instanceof TriplePattern) { RuleClauseCode code = new RuleClauseCode(r); allRuleClauseCodes.add(code); Node predicate = ((TriplePattern) term).getPredicate(); if (predicate.isVariable()) { predicate = Node_RuleVariable.WILD; } List<RuleClauseCode> predicateCode = predicateToCodeMap.get(predicate); if (predicateCode == null) { predicateCode = new ArrayList<>(); predicateToCodeMap.put(predicate, predicateCode); } predicateCode.add(code); if (predicateCode.size() > INDEX_THRESHOLD) { indexPredicateToCodeMap.put(predicate, new HashMap<Node, List<RuleClauseCode>>()); } } } // Now add the wild card rules into the list for each non-wild predicate) List<RuleClauseCode> wildRules = predicateToCodeMap.get(Node_RuleVariable.WILD); if (wildRules != null) { for (Map.Entry<Node, List<RuleClauseCode>> entry : predicateToCodeMap.entrySet()) { Node predicate = entry.getKey(); List<RuleClauseCode> predicateCode = entry.getValue(); if (predicate != Node_RuleVariable.WILD) { predicateCode.addAll(wildRules); } } } indexPredicateToCodeMap.put(Node_RuleVariable.WILD, new HashMap<Node, List<RuleClauseCode>>()); // Now built any required two level indices for (Map.Entry<Node, Map<Node, List<RuleClauseCode>>> entry : indexPredicateToCodeMap.entrySet()) { Node predicate = entry.getKey(); Map<Node, List<RuleClauseCode>> predicateMap = entry.getValue(); List<RuleClauseCode> wildRulesForPredicate = new ArrayList<>(); List<RuleClauseCode> allRulesForPredicate = predicate.isVariable() ? allRuleClauseCodes : predicateToCodeMap.get(predicate); for (Iterator<RuleClauseCode> j = allRulesForPredicate.iterator(); j.hasNext(); ) { RuleClauseCode code = j.next(); ClauseEntry head = code.getRule().getHeadElement(0); boolean indexed = false; if (head instanceof TriplePattern) { Node objectPattern = ((TriplePattern) head).getObject(); if (!objectPattern.isVariable() && !Functor.isFunctor(objectPattern)) { // Index against object List<RuleClauseCode> indexedCode = predicateMap.get(objectPattern); if (indexedCode == null) { indexedCode = new ArrayList<>(); predicateMap.put(objectPattern, indexedCode); } indexedCode.add(code); indexed = true; } } if (!indexed) { wildRulesForPredicate.add(code); } } // Now fold the rules that apply to any index entry into all the indexed entries for (Iterator<Map.Entry<Node, List<RuleClauseCode>>> k = predicateMap.entrySet().iterator(); k.hasNext(); ) { Map.Entry<Node, List<RuleClauseCode>> ent = k.next(); List<RuleClauseCode> predicateCode = ent.getValue(); predicateCode.addAll(wildRulesForPredicate); } } // Now compile all the clauses for (RuleClauseCode code : allRuleClauseCodes) { code.compile(this); } }