Пример #1
0
  public PathIteration(
      StrictEvaluationStrategy evaluationStrategyImpl,
      Scope scope,
      Var startVar,
      TupleExpr pathExpression,
      Var endVar,
      Var contextVar,
      long minLength,
      BindingSet bindings)
      throws QueryEvaluationException {
    this.evaluationStrategyImpl = evaluationStrategyImpl;
    this.scope = scope;
    this.startVar = startVar;
    this.endVar = endVar;

    this.startVarFixed = startVar.hasValue() || bindings.hasBinding(startVar.getName());
    this.endVarFixed = endVar.hasValue() || bindings.hasBinding(endVar.getName());

    this.pathExpression = pathExpression;
    this.contextVar = contextVar;

    this.currentLength = minLength;
    this.bindings = bindings;

    this.reportedValues = makeSet();
    this.unreportedValues = makeSet();
    this.valueQueue = makeQueue();

    createIteration();
  }
Пример #2
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;
    }
  }