private void remove(LinkableEvaluation eval) { LinkableEvaluation prev = eval.previous; LinkableEvaluation next = eval.next; if (prev != null) prev.next = next; else pendingEvaluationHead = next; if (next != null) next.previous = prev; else pendingEvaluationTail = prev; }
private void finished() { if (!finished) { finished = true; for (LinkableEvaluation pendingEval = pendingEvaluationHead; pendingEval != null; pendingEval = pendingEval.next) pendingEval.removeListener(this); pendingEvaluationHead = pendingEvaluationTail = null; fireFinished(); } }
@Override protected void dispose() { if (nodeSetListener != null) { for (LongTreeMap.Entry<Object> entry = result.firstEntry(); entry != null; entry = entry.next()) nodeSetListener.discard(entry.getKey()); } manuallyExpired = true; for (LinkableEvaluation pendingEval = pendingEvaluationHead; pendingEval != null; pendingEval = pendingEval.next) pendingEval.removeListener(this); pendingEvaluationHead = pendingEvaluationTail = null; if (predicateResult == null) predicateEvaluation.removeListener(this); }
private void resultPrepared() { if (!resultPrepared) { manuallyExpired = true; resultPrepared = true; for (LinkableEvaluation pendingEval = pendingEvaluationHead; pendingEval != null; pendingEval = pendingEval.next) pendingEval.removeListener(this); pendingEvaluationHead = pendingEvaluationTail = null; } if (predicateResult != null && (index != 0 || (stringEvaluations == null || stringEvaluations.size() == 0))) finished(); else if (result.size() == 0 && predicateResult == null) { // when result is empty, there is no need to wait for predicateEvaluation to // finish Expression predicate = predicateEvaluation.expression; if (predicate.scope() != Scope.DOCUMENT) predicateEvaluation.removeListener(this); else event.removeListener(predicate, this); finished(); } }
@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()); } }
@Override public void onHit(EventID eventID) { assert !finished : "getting events even after finish"; final LocationExpression expression = this.expression; if (!lastStep) { if (eventID.isEmpty(expression.locationPath.steps[index + 1].axis)) return; } final Event event = this.event; if (positionTracker != null) { event.positionTrackerStack.addFirst(positionTracker); positionTracker.addEvaluation(event); } LinkableEvaluation childEval = null; Expression predicate = currentStep.predicateSet.getPredicate(); Object predicateResult = predicate == null ? Boolean.TRUE : event.evaluate(predicate); if (predicateResult == Boolean.TRUE) { if (lastStep) consume(event); else childEval = new LocationEvaluation(expression, index + 1, event, eventID); } else if (predicateResult == null) { Evaluation predicateEvaluation = event.evaluation; if (lastStep) { childEval = new PredicateEvaluation( expression, event.order(), expression.getResultItem(event), event, predicate, predicateEvaluation); if (nodeSetListener != null) nodeSetListener.mayHit(); } else childEval = new LocationEvaluation( expression, index + 1, event, eventID, predicate, predicateEvaluation); } if (childEval != null) { if (childEval instanceof LocationEvaluation) ((LocationEvaluation) childEval).nodeSetListener = nodeSetListener; else ((PredicateEvaluation) childEval).nodeSetListener = nodeSetListener; childEval.addListener(this); if (pendingEvaluationTail != null) { pendingEvaluationTail.next = childEval; childEval.previous = pendingEvaluationTail; pendingEvaluationTail = childEval; } else pendingEvaluationHead = pendingEvaluationTail = childEval; childEval.start(); } if (positionTracker != null) { positionTracker.startEvaluation(); event.positionTrackerStack.pollFirst(); } if (exactPosition && predicateResult == Boolean.TRUE) { manuallyExpired = true; expired(); } }