예제 #1
0
  @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;
    }
  }
예제 #2
0
  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++;
    }
  }