示例#1
0
 @Override
 @SuppressWarnings({"unchecked"})
 public void finished(Evaluation evaluation) {
   LongTreeMap.Entry<EvaluationInfo> entry = evaluations.getEntry(evaluation.order);
   assert entry.value.eval == evaluation;
   if (evaluation instanceof PredicateEvaluation) {
     PredicateEvaluation predicateEvaluation = (PredicateEvaluation) evaluation;
     if (predicateEvaluation.result != null) {
       if (predicateEvaluation.result instanceof Evaluation) {
         entry.value.eval = (Evaluation) predicateEvaluation.result;
         entry.value.eval.addListener(this);
         return;
       } else {
         entry.value.setResult(predicateEvaluation.result);
         entry.value.eval = null;
         pendingCount--;
       }
     } else {
       entry.value.doDiscards();
       evaluations.deleteEntry(entry);
       if (entry.value.eval != null) pendingCount--;
     }
   } else {
     entry.value.setResult(evaluation.getResult());
     entry.value.eval = null;
     pendingCount--;
   }
   tryToFinish();
 }
示例#2
0
 private void fireInstantResult(LongTreeMap<Object> result) {
   LongTreeMap.Entry<Object> entry = result.firstEntry();
   while (entry != null) {
     if (entry.value instanceof NodeItem) {
       event.onInstantResult(expression, (NodeItem) entry.value);
       entry.value = Event.DUMMY_VALUE;
     }
     entry = entry.next();
   }
   result.clear(); // to avoid memory leak
 }
示例#3
0
 @Override
 public void discard(long order) {
   LongTreeMap.Entry<EvaluationInfo> entry = evaluations.getEntry(order);
   if (entry != null) {
     if (entry.value.discard() == 0) {
       evaluations.deleteEntry(entry);
       if (entry.value.eval != null) {
         pendingCount--;
         entry.value.eval.removeListener(this);
       }
     }
   }
 }
示例#4
0
 private void consumedResult() {
   int resultSize = result.size();
   if (resultSize > 0 && !expression.many) {
     if (resultSize > 1) result.deleteEntry(result.lastEntry());
     if (expression.first) {
       if (pendingEvaluationHead == null
           || result.firstEntry().getKey() <= pendingEvaluationHead.order) resultPrepared();
       else if (!expired) {
         manuallyExpired = true;
         expired = true;
       }
     } else resultPrepared();
   } else if (expired && pendingEvaluationHead == null) resultPrepared();
 }
示例#5
0
 @SuppressWarnings({"unchecked"})
 public Object computeResult() {
   if (expression.forEach) {
     List<Object> result = new ArrayList<Object>(evaluations.size());
     for (LongTreeMap.Entry entry = evaluations.firstEntry(); entry != null; entry = entry.next())
       result.add(computeResultItem(((EvaluationInfo) entry.value).result));
     return result;
   } else {
     LongTreeMap result = new LongTreeMap();
     for (LongTreeMap.Entry<EvaluationInfo> entry = evaluations.firstEntry();
         entry != null;
         entry = entry.next()) result.putAll(entry.value.result);
     return computeResultItem(result);
   }
 }
示例#6
0
  private void consumeChildEvaluation(LongTreeMap<Object> childResult) {
    boolean prepareResult = false;
    int size = childResult.size();
    if (size == 1 && expression.resultType == DataType.NUMBER) {
      Object resultItem = childResult.firstEntry().value;
      if (resultItem instanceof Double && ((Double) resultItem).isNaN()) {
        result.clear();
        prepareResult = true;
      }
    }

    if (size > 0) {
      if (predicateChain == 0) fireInstantResult(childResult);
      if (result.size() > 0) {
        if (nodeSetListener != null) {
          for (LongTreeMap.Entry<Object> entry = childResult.firstEntry();
              entry != null;
              entry = entry.next()) {
            if (result.put(entry.getKey(), entry.value) != null)
              nodeSetListener.discard(entry.getKey());
          }
        } else result.putAll(childResult);
      } else result = childResult;
    }
    consumedResult();

    if (prepareResult) resultPrepared();
  }
示例#7
0
  private void consumeChildEvaluation(long order, Object resultItem) {
    boolean prepareResult = false;
    if (expression.resultType == DataType.NUMBER) {
      if (resultItem instanceof Double && ((Double) resultItem).isNaN()) {
        result.clear();
        prepareResult = true;
      }
    }

    if (predicateChain == 0) {
      event.onInstantResult(expression, (NodeItem) resultItem);
      resultItem = Event.DUMMY_VALUE;
    }
    result.put(order, resultItem);
    consumedResult();

    if (prepareResult) resultPrepared();
  }
示例#8
0
 private int pendingCount() {
   int count = 0;
   for (LongTreeMap.Entry<EvaluationInfo> entry = evaluations.firstEntry();
       entry != null;
       entry = entry.next()) {
     if (entry.value.eval != null) count++;
   }
   return count;
 }
示例#9
0
 @Override
 public void finished() {
   contextsPending--;
   if (contextsPending == 0) {
     if (expression.union.hitExpression != null) {
       for (EvaluationInfo evalInfo : new ArrayList<EvaluationInfo>(evaluations.values()))
         evalInfo.doFinish();
       if (positionTracker != null) positionTracker.expired();
     }
   }
   tryToFinish();
 }
示例#10
0
 private void consume(Event event) {
   assert lastStep;
   Object resultItem = expression.getResultItem(event);
   if (resultItem instanceof Evaluation) {
     Evaluation eval = (Evaluation) resultItem;
     stringEvaluations.add(eval);
     eval.addListener(this);
     eval.start();
   } else if (predicateChain == 0) {
     event.onInstantResult(expression, (NodeItem) resultItem);
     resultItem = Event.DUMMY_VALUE;
   }
   assert resultItem != null : "ResultItem should be non-null";
   result.put(event.order(), resultItem);
   consumedResult();
   if (nodeSetListener != null) nodeSetListener.mayHit();
 }
示例#11
0
 @SuppressWarnings({"unchecked", "UnnecessaryBoxing"})
 private Object computeResultItem(LongTreeMap result) {
   switch (expression.resultType) {
     case NODESET:
     case STRINGS:
     case NUMBERS:
       return new ArrayList(result.values());
     case NUMBER:
       if (expression.relativeExpression instanceof Count) return new Double(result.size());
       else {
         double d = 0;
         for (LongTreeMap.Entry entry = result.firstEntry(); entry != null; entry = entry.next())
           d += (Double) entry.value;
         return d;
       }
     case BOOLEAN:
       return !result.isEmpty();
     default:
       if (result.isEmpty()) return expression.resultType.defaultValue;
       else return result.firstEntry().value;
   }
 }
示例#12
0
  @Override
  public final void finished(Evaluation evaluation) {
    assert !finished : "can't consume evaluation result after finish";

    if (evaluation == predicateEvaluation) {
      predicateResult = (Boolean) evaluation.getResult();
      assert predicateResult != null : "evaluation result should be non-null";
      if (predicateResult == Boolean.FALSE) {
        if (nodeSetListener != null) {
          for (LongTreeMap.Entry<Object> entry = result.firstEntry();
              entry != null;
              entry = entry.next()) nodeSetListener.discard(entry.getKey());
        }
        result.clear();
        if (stringEvaluations != null) {
          for (Evaluation stringEval : stringEvaluations) stringEval.removeListener(this);
          stringEvaluations = null;
        }
        resultPrepared();
      } else {
        if (predicateChain != -1) decreasePredicateChain();
        if (resultPrepared) finished();
      }
    } else if (evaluation instanceof PredicateEvaluation) {
      PredicateEvaluation predicateEvaluation = (PredicateEvaluation) evaluation;
      remove(predicateEvaluation);

      if (predicateEvaluation.result != null) {
        Object resultItem = predicateEvaluation.result;
        if (resultItem instanceof Evaluation) {
          Evaluation stringEval = (Evaluation) resultItem;
          stringEvaluations.add(stringEval);
          stringEval.addListener(this);
        }
        consumeChildEvaluation(predicateEvaluation.order, resultItem);
      } else {
        if (nodeSetListener != null) nodeSetListener.discard(predicateEvaluation.order);
        consumedResult();
      }
    } else if (evaluation instanceof LocationEvaluation) {
      LocationEvaluation locEval = (LocationEvaluation) evaluation;
      remove(locEval);

      if (locEval.stringEvaluations != null) {
        for (Evaluation stringEval : locEval.stringEvaluations) stringEval.addListener(this);
        stringEvaluations.addAll(locEval.stringEvaluations);
      }
      boolean wasExpired = expired;
      consumeChildEvaluation(locEval.result);
      if (!wasExpired && expired) {
        assert !finished;
        LinkableEvaluation eval = locEval.next;
        while (eval != null) {
          eval.removeListener(this);
          remove(eval);
          eval = eval.next;
        }
        if (pendingEvaluationHead == null) resultPrepared();
      }
    } else {
      stringEvaluations.remove(evaluation);
      consumeChildEvaluation(evaluation.order, evaluation.getResult());
    }
  }
示例#13
0
  @Override
  public void mayHit() {
    long order = event.order();
    EvaluationInfo evalInfo = evaluations.get(order);
    if (evalInfo == null) {
      evaluations.put(
          order,
          evalInfo =
              new EvaluationInfo(event, expression.union.hitExpression, order, nodeSetListener));

      if (positionTracker != null) {
        event.positionTrackerStack.addFirst(positionTracker);
        positionTracker.addEvaluation(event);
      }
      Expression predicate = expression.union.predicateSet.getPredicate();
      Object predicateResult = predicate == null ? Boolean.TRUE : event.evaluate(predicate);
      if (predicateResult == Boolean.TRUE) {
        Object r = event.evaluate(expression.relativeExpression);
        if (r == null) {
          event.evaluation.addListener(this);
          event.evaluation.start();
          evalInfo.eval = event.evaluation;
          pendingCount++;
          if (nodeSetListener != null) {
            if (event.evaluation instanceof LocationEvaluation)
              ((LocationEvaluation) event.evaluation).nodeSetListener = evalInfo;
            else ((PathEvaluation) event.evaluation).nodeSetListener = evalInfo;
          }
        } else {
          if (nodeSetListener != null) nodeSetListener.mayHit();
          evalInfo.setResult(r);
        }
      } else if (predicateResult == null) {
        Evaluation predicateEvaluation = event.evaluation;
        Object resultItem = expression.relativeExpression.getResult(event);
        if (nodeSetListener != null
            && !(nodeSetListener
                instanceof Event)) { // nodeSetListener will be event if xmlBuilder is set
          if (resultItem instanceof LocationEvaluation)
            ((LocationEvaluation) resultItem).nodeSetListener = evalInfo;
          else ((PathEvaluation) resultItem).nodeSetListener = evalInfo;
        }
        Evaluation childEval =
            new PredicateEvaluation(
                expression.relativeExpression,
                event.order(),
                resultItem,
                event,
                predicate,
                predicateEvaluation);
        childEval.addListener(this);
        childEval.start();
        evalInfo.eval = childEval;
        pendingCount++;
      } else throw new ImpossibleException();
    }
    evalInfo.hitCount++;

    if (evalInfo.hitCount == 1 && positionTracker != null) {
      positionTracker.startEvaluation();
      event.positionTrackerStack.pollFirst();
    }
  }