/* *************************************************************************************** * Copyright (C) 2006 EsperTech, Inc. All rights reserved. * * http://www.espertech.com/esper * * http://www.espertech.com * * ---------------------------------------------------------------------------------- * * The software in this package is published under the terms of the GPL license * * a copy of which has been included with this distribution in the license.txt file. * *************************************************************************************** */ package com.espertech.esper.type; import com.espertech.esper.client.EventBean; import com.espertech.esper.epl.expression.core.ExprEvaluator; import com.espertech.esper.epl.expression.core.ExprEvaluatorContext; import com.espertech.esper.util.SimpleNumberBigDecimalCoercer; import com.espertech.esper.util.SimpleNumberBigIntegerCoercer; import java.math.BigDecimal; import java.math.BigInteger; /** * Enumeration for the type of arithmatic to use. */ public enum MinMaxTypeEnum { /** * Max. */ MAX("max"), /** * Min. */ MIN("min"); private String expressionText; private MinMaxTypeEnum(String expressionText) { this.expressionText = expressionText; } /** * Returns textual representation of enum. * * @return text for enum */ public String getExpressionText() { return expressionText; } /** * Executes child expression nodes and compares results. */ public interface Computer { /** * Executes child expression nodes and compares results, returning the min/max. * * @param eventsPerStream events per stream * @param isNewData true if new data * @param exprEvaluatorContext expression evaluation context * @return result */ public Number execute(EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext exprEvaluatorContext); } /** * Determines minimum using Number.doubleValue(). */ public static class MinComputerDoubleCoerce implements Computer { private ExprEvaluator[] childNodes; /** * Ctor. * * @param childNodes array of expression nodes */ public MinComputerDoubleCoerce(ExprEvaluator[] childNodes) { this.childNodes = childNodes; } public Number execute(EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext exprEvaluatorContext) { Number valueChildOne = (Number) childNodes[0].evaluate(eventsPerStream, isNewData, exprEvaluatorContext); Number valueChildTwo = (Number) childNodes[1].evaluate(eventsPerStream, isNewData, exprEvaluatorContext); if ((valueChildOne == null) || (valueChildTwo == null)) { return null; } Number result; if (valueChildOne.doubleValue() > valueChildTwo.doubleValue()) { result = valueChildTwo; } else { result = valueChildOne; } for (int i = 2; i < childNodes.length; i++) { Number valueChild = (Number) childNodes[i].evaluate(eventsPerStream, isNewData, exprEvaluatorContext); if (valueChild == null) { return null; } if (valueChild.doubleValue() < result.doubleValue()) { result = valueChild; } } return result; } } /** * Determines maximum using Number.doubleValue(). */ public static class MaxComputerDoubleCoerce implements Computer { private ExprEvaluator[] childNodes; /** * Ctor. * * @param childNodes array of expression nodes */ public MaxComputerDoubleCoerce(ExprEvaluator[] childNodes) { this.childNodes = childNodes; } public Number execute(EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext exprEvaluatorContext) { Number valueChildOne = (Number) childNodes[0].evaluate(eventsPerStream, isNewData, exprEvaluatorContext); Number valueChildTwo = (Number) childNodes[1].evaluate(eventsPerStream, isNewData, exprEvaluatorContext); if ((valueChildOne == null) || (valueChildTwo == null)) { return null; } Number result; if (valueChildOne.doubleValue() > valueChildTwo.doubleValue()) { result = valueChildOne; } else { result = valueChildTwo; } for (int i = 2; i < childNodes.length; i++) { Number valueChild = (Number) childNodes[i].evaluate(eventsPerStream, isNewData, exprEvaluatorContext); if (valueChild == null) { return null; } if (valueChild.doubleValue() > result.doubleValue()) { result = valueChild; } } return result; } } /** * Determines minimum/maximum using BigInteger.compareTo. */ public static class ComputerBigIntCoerce implements Computer { private ExprEvaluator[] childNodes; private SimpleNumberBigIntegerCoercer[] convertors; private boolean isMax; /** * Ctor. * * @param childNodes expressions * @param convertors convertors to BigInteger * @param isMax true if max, false if min */ public ComputerBigIntCoerce(ExprEvaluator[] childNodes, SimpleNumberBigIntegerCoercer[] convertors, boolean isMax) { this.childNodes = childNodes; this.convertors = convertors; this.isMax = isMax; } public Number execute(EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext exprEvaluatorContext) { Number valueChildOne = (Number) childNodes[0].evaluate(eventsPerStream, isNewData, exprEvaluatorContext); Number valueChildTwo = (Number) childNodes[1].evaluate(eventsPerStream, isNewData, exprEvaluatorContext); if ((valueChildOne == null) || (valueChildTwo == null)) { return null; } BigInteger bigIntOne = convertors[0].coerceBoxedBigInt(valueChildOne); BigInteger bigIntTwo = convertors[1].coerceBoxedBigInt(valueChildTwo); BigInteger result; if ((isMax && (bigIntOne.compareTo(bigIntTwo) > 0)) || (!isMax && (bigIntOne.compareTo(bigIntTwo) < 0))) { result = bigIntOne; } else { result = bigIntTwo; } for (int i = 2; i < childNodes.length; i++) { Number valueChild = (Number) childNodes[i].evaluate(eventsPerStream, isNewData, exprEvaluatorContext); if (valueChild == null) { return null; } BigInteger bigInt = convertors[i].coerceBoxedBigInt(valueChild); if ((isMax && (result.compareTo(bigInt) < 0)) || (!isMax && (result.compareTo(bigInt) > 0))) { result = bigInt; } } return result; } } /** * Determines minimum/maximum using BigDecimal.compareTo. */ public static class ComputerBigDecCoerce implements Computer { private ExprEvaluator[] childNodes; private SimpleNumberBigDecimalCoercer[] convertors; private boolean isMax; /** * Ctor. * * @param childNodes expressions * @param convertors convertors to BigDecimal * @param isMax true if max, false if min */ public ComputerBigDecCoerce(ExprEvaluator[] childNodes, SimpleNumberBigDecimalCoercer[] convertors, boolean isMax) { this.childNodes = childNodes; this.convertors = convertors; this.isMax = isMax; } public Number execute(EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext exprEvaluatorContext) { Number valueChildOne = (Number) childNodes[0].evaluate(eventsPerStream, isNewData, exprEvaluatorContext); Number valueChildTwo = (Number) childNodes[1].evaluate(eventsPerStream, isNewData, exprEvaluatorContext); if ((valueChildOne == null) || (valueChildTwo == null)) { return null; } BigDecimal bigDecOne = convertors[0].coerceBoxedBigDec(valueChildOne); BigDecimal bigDecTwo = convertors[1].coerceBoxedBigDec(valueChildTwo); BigDecimal result; if ((isMax && (bigDecOne.compareTo(bigDecTwo) > 0)) || (!isMax && (bigDecOne.compareTo(bigDecTwo) < 0))) { result = bigDecOne; } else { result = bigDecTwo; } for (int i = 2; i < childNodes.length; i++) { Number valueChild = (Number) childNodes[i].evaluate(eventsPerStream, isNewData, exprEvaluatorContext); if (valueChild == null) { return null; } BigDecimal bigDec = convertors[i].coerceBoxedBigDec(valueChild); if ((isMax && (result.compareTo(bigDec) < 0)) || (!isMax && (result.compareTo(bigDec) > 0))) { result = bigDec; } } return result; } } }