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(); }
@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); }
@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()); } }