@Override protected BindingSet getNextElement() throws QueryEvaluationException { again: while (true) { while (!currentIter.hasNext()) { Iterations.closeCloseable(currentIter); createIteration(); // stop condition: if the iter is an EmptyIteration if (currentIter instanceof EmptyIteration<?, ?>) { break; } } while (currentIter.hasNext()) { BindingSet nextElement = currentIter.next(); if (!startVarFixed && !endVarFixed && currentVp != null) { Value startValue = currentVp.getStartValue(); if (startValue != null) { nextElement = new QueryBindingSet(nextElement); ((QueryBindingSet) nextElement).addBinding(startVar.getName(), startValue); } } Value v1, v2; if (startVarFixed && endVarFixed && currentLength > 2) { v1 = getVarValue(startVar, startVarFixed, nextElement); v2 = nextElement.getValue("END_" + JOINVAR_PREFIX + pathExpression.hashCode()); } else if (startVarFixed && endVarFixed && currentLength == 2) { v1 = getVarValue(startVar, startVarFixed, nextElement); v2 = nextElement.getValue( JOINVAR_PREFIX + (currentLength - 1) + "-" + pathExpression.hashCode()); } else { v1 = getVarValue(startVar, startVarFixed, nextElement); v2 = getVarValue(endVar, endVarFixed, nextElement); } if (!isCyclicPath(v1, v2)) { ValuePair vp = new ValuePair(v1, v2); if (reportedValues.contains(vp)) { // new arbitrary-length path semantics: filter out // duplicates if (currentIter.hasNext()) { continue; } else { // if the current iter is exhausted, we need to check // that no further paths of greater length still exists. continue again; } } if (startVarFixed && endVarFixed) { Value endValue = getVarValue(endVar, endVarFixed, nextElement); if (endValue.equals(v2)) { add(reportedValues, vp); if (!v1.equals(v2)) { addToQueue(valueQueue, vp); } if (!nextElement.hasBinding(startVar.getName())) { ((QueryBindingSet) nextElement).addBinding(startVar.getName(), v1); } if (!nextElement.hasBinding(endVar.getName())) { ((QueryBindingSet) nextElement).addBinding(endVar.getName(), v2); } return nextElement; } else { if (add(unreportedValues, vp)) { if (!v1.equals(v2)) { addToQueue(valueQueue, vp); } } continue again; } } else { add(reportedValues, vp); if (!v1.equals(v2)) { addToQueue(valueQueue, vp); } if (!nextElement.hasBinding(startVar.getName())) { ((QueryBindingSet) nextElement).addBinding(startVar.getName(), v1); } if (!nextElement.hasBinding(endVar.getName())) { ((QueryBindingSet) nextElement).addBinding(endVar.getName(), v2); } return nextElement; } } else { continue again; } } // if we're done, throw away the cached lists of values to avoid // hogging resources reportedValues.clear(); unreportedValues.clear(); valueQueue.clear(); return null; } }
private void createIteration() throws QueryEvaluationException { if (currentLength == 0L) { ZeroLengthPath zlp = new ZeroLengthPath(scope, startVar, endVar, contextVar); currentIter = this.evaluationStrategyImpl.evaluate(zlp, bindings); currentLength++; } else if (currentLength == 1) { TupleExpr pathExprClone = pathExpression.clone(); if (startVarFixed && endVarFixed) { Var replacement = createAnonVar(JOINVAR_PREFIX + currentLength + "-" + pathExpression.hashCode()); VarReplacer replacer = new VarReplacer(endVar, replacement, 0, false); pathExprClone.visit(replacer); } currentIter = this.evaluationStrategyImpl.evaluate(pathExprClone, bindings); currentLength++; } else { currentVp = valueQueue.poll(); if (currentVp != null) { TupleExpr pathExprClone = pathExpression.clone(); if (startVarFixed && endVarFixed) { Var startReplacement = createAnonVar(JOINVAR_PREFIX + currentLength + "-" + pathExpression.hashCode()); Var endReplacement = createAnonVar("END_" + JOINVAR_PREFIX + pathExpression.hashCode()); startReplacement.setAnonymous(false); endReplacement.setAnonymous(false); Value v = currentVp.getEndValue(); startReplacement.setValue(v); VarReplacer replacer = new VarReplacer(startVar, startReplacement, 0, false); pathExprClone.visit(replacer); replacer = new VarReplacer(endVar, endReplacement, 0, false); pathExprClone.visit(replacer); } else { Var toBeReplaced; Value v; if (!endVarFixed) { toBeReplaced = startVar; v = currentVp.getEndValue(); } else { toBeReplaced = endVar; v = currentVp.getStartValue(); } Var replacement = createAnonVar(JOINVAR_PREFIX + currentLength + "-" + pathExpression.hashCode()); replacement.setValue(v); VarReplacer replacer = new VarReplacer(toBeReplaced, replacement, 0, false); pathExprClone.visit(replacer); } currentIter = this.evaluationStrategyImpl.evaluate(pathExprClone, bindings); } else { currentIter = new EmptyIteration<BindingSet, QueryEvaluationException>(); } currentLength++; } }