diff --git a/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlExpressionBenchmark.java b/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlExpressionBenchmark.java index 46036fcc64ff..b1f626295e08 100644 --- a/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlExpressionBenchmark.java +++ b/benchmarks/src/test/java/org/apache/druid/benchmark/query/SqlExpressionBenchmark.java @@ -139,7 +139,23 @@ public class SqlExpressionBenchmark extends SqlBaseQueryBenchmark "SELECT ARRAY_OVERLAP(\"multi-string3\", ARRAY[1, 2, 10, 11, 20, 22, 30, 33, 40, 44, 50, 55, 100]) FROM expressions", // 46: filters with random orders "SELECT string2, SUM(long1) FROM expressions WHERE string5 LIKE '%1%' AND string1 = '1000' GROUP BY 1 ORDER BY 2", - "SELECT string2, SUM(long1) FROM expressions WHERE string5 LIKE '%1%' AND (string3 in ('1', '10', '20', '22', '32') AND long2 IN (1, 19, 21, 23, 25, 26, 46) AND double3 < 1010.0 AND double3 > 1000.0 AND (string4 = '1' OR REGEXP_EXTRACT(string1, '^1') IS NOT NULL OR REGEXP_EXTRACT('Z' || string2, '^Z2') IS NOT NULL)) AND string1 = '1000' GROUP BY 1 ORDER BY 2" + "SELECT string2, SUM(long1) FROM expressions WHERE string5 LIKE '%1%' AND (string3 in ('1', '10', '20', '22', '32') AND long2 IN (1, 19, 21, 23, 25, 26, 46) AND double3 < 1010.0 AND double3 > 1000.0 AND (string4 = '1' OR REGEXP_EXTRACT(string1, '^1') IS NOT NULL OR REGEXP_EXTRACT('Z' || string2, '^Z2') IS NOT NULL)) AND string1 = '1000' GROUP BY 1 ORDER BY 2", + // 48-57 nvl tests + // lower cardinality + "SELECT NVL(string2, string1), SUM(double1) FROM expressions GROUP BY 1 ORDER BY 2", + "SELECT NVL(string2, CONCAT(string1, '-', long2)), SUM(double1) FROM expressions GROUP BY 1 ORDER BY 2", + // higher cardinality + "SELECT NVL(string5, string3), SUM(double1) FROM expressions GROUP BY 1 ORDER BY 2", + "SELECT NVL(string5, CONCAT(string3, '-', long2)), SUM(double1) FROM expressions GROUP BY 1 ORDER BY 2", + // no lhs nulls + "SELECT NVL(string1, string3), SUM(double1) FROM expressions GROUP BY 1 ORDER BY 2", + "SELECT NVL(string1, CONCAT(string3, '-', long2)), SUM(double1) FROM expressions GROUP BY 1 ORDER BY 2", + // numeric + "SELECT NVL(long5, long3), SUM(double1) FROM expressions GROUP BY 1 ORDER BY 2", + "SELECT NVL(long5, long1 + long3), SUM(double1) FROM expressions GROUP BY 1 ORDER BY 2", + // numeric no lhs null + "SELECT NVL(long1, long3), SUM(double1) FROM expressions GROUP BY 1 ORDER BY 2", + "SELECT NVL(long1, long5 + long3), SUM(double1) FROM expressions GROUP BY 1 ORDER BY 2" ); @Param({ @@ -200,7 +216,17 @@ public class SqlExpressionBenchmark extends SqlBaseQueryBenchmark "44", "45", "46", - "47" + "47", + "48", + "49", + "50", + "51", + "52", + "53", + "54", + "55", + "56", + "57" }) private String query; diff --git a/processing/src/main/java/org/apache/druid/math/expr/BinaryLogicalOperatorExpr.java b/processing/src/main/java/org/apache/druid/math/expr/BinaryLogicalOperatorExpr.java index 13bb4e7f52f1..adff99ea7cda 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/BinaryLogicalOperatorExpr.java +++ b/processing/src/main/java/org/apache/druid/math/expr/BinaryLogicalOperatorExpr.java @@ -80,7 +80,7 @@ protected final boolean evalDouble(double left, double right) @Override public ExprVectorProcessor asVectorProcessor(VectorInputBindingInspector inspector) { - return VectorComparisonProcessors.lessThan(inspector, left, right); + return VectorComparisonProcessors.lessThan().asProcessor(inspector, left, right); } } @@ -128,7 +128,7 @@ protected final boolean evalDouble(double left, double right) @Override public ExprVectorProcessor asVectorProcessor(VectorInputBindingInspector inspector) { - return VectorComparisonProcessors.lessThanOrEqual(inspector, left, right); + return VectorComparisonProcessors.lessThanOrEquals().asProcessor(inspector, left, right); } } @@ -176,7 +176,7 @@ protected final boolean evalDouble(double left, double right) @Override public ExprVectorProcessor asVectorProcessor(VectorInputBindingInspector inspector) { - return VectorComparisonProcessors.greaterThan(inspector, left, right); + return VectorComparisonProcessors.greaterThan().asProcessor(inspector, left, right); } } @@ -224,7 +224,7 @@ protected final boolean evalDouble(double left, double right) @Override public ExprVectorProcessor asVectorProcessor(VectorInputBindingInspector inspector) { - return VectorComparisonProcessors.greaterThanOrEqual(inspector, left, right); + return VectorComparisonProcessors.greaterThanOrEquals().asProcessor(inspector, left, right); } } @@ -271,7 +271,7 @@ protected final boolean evalDouble(double left, double right) @Override public ExprVectorProcessor asVectorProcessor(VectorInputBindingInspector inspector) { - return VectorComparisonProcessors.equal(inspector, left, right); + return VectorComparisonProcessors.equals().asProcessor(inspector, left, right); } } @@ -318,7 +318,7 @@ protected final boolean evalDouble(double left, double right) @Override public ExprVectorProcessor asVectorProcessor(VectorInputBindingInspector inspector) { - return VectorComparisonProcessors.notEqual(inspector, left, right); + return VectorComparisonProcessors.notEquals().asProcessor(inspector, left, right); } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/BinaryMathOperatorExpr.java b/processing/src/main/java/org/apache/druid/math/expr/BinaryMathOperatorExpr.java index a11b48af541b..6fa739687ce2 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/BinaryMathOperatorExpr.java +++ b/processing/src/main/java/org/apache/druid/math/expr/BinaryMathOperatorExpr.java @@ -85,7 +85,7 @@ public ExprVectorProcessor asVectorProcessor(VectorInputBindingInspector if (Types.is(type, ExprType.STRING)) { return VectorStringProcessors.concat(inspector, left, right); } - return VectorMathProcessors.plus(inspector, left, right); + return VectorMathProcessors.plus().asProcessor(inspector, left, right); } } @@ -124,7 +124,7 @@ public boolean canVectorize(InputBindingInspector inspector) @Override public ExprVectorProcessor asVectorProcessor(VectorInputBindingInspector inspector) { - return VectorMathProcessors.minus(inspector, left, right); + return VectorMathProcessors.subtract().asProcessor(inspector, left, right); } } @@ -163,7 +163,7 @@ public boolean canVectorize(InputBindingInspector inspector) @Override public ExprVectorProcessor asVectorProcessor(VectorInputBindingInspector inspector) { - return VectorMathProcessors.multiply(inspector, left, right); + return VectorMathProcessors.multiply().asProcessor(inspector, left, right); } } @@ -202,7 +202,7 @@ public boolean canVectorize(InputBindingInspector inspector) @Override public ExprVectorProcessor asVectorProcessor(VectorInputBindingInspector inspector) { - return VectorMathProcessors.divide(inspector, left, right); + return VectorMathProcessors.divide().asProcessor(inspector, left, right); } } @@ -241,7 +241,7 @@ public boolean canVectorize(InputBindingInspector inspector) @Override public ExprVectorProcessor asVectorProcessor(VectorInputBindingInspector inspector) { - return VectorMathProcessors.power(inspector, left, right); + return VectorMathProcessors.power().asProcessor(inspector, left, right); } } @@ -280,6 +280,6 @@ public boolean canVectorize(InputBindingInspector inspector) @Override public ExprVectorProcessor asVectorProcessor(VectorInputBindingInspector inspector) { - return VectorMathProcessors.modulo(inspector, left, right); + return VectorMathProcessors.modulo().asProcessor(inspector, left, right); } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/Expr.java b/processing/src/main/java/org/apache/druid/math/expr/Expr.java index 104cc5b1457d..9355447340ad 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/Expr.java +++ b/processing/src/main/java/org/apache/druid/math/expr/Expr.java @@ -468,7 +468,7 @@ interface ObjectBinding extends InputBindingInspector */ interface VectorInputBinding extends VectorInputBindingInspector { - T[] getObjectVector(String name); + Object[] getObjectVector(String name); long[] getLongVector(String name); diff --git a/processing/src/main/java/org/apache/druid/math/expr/ExpressionValidationException.java b/processing/src/main/java/org/apache/druid/math/expr/ExpressionValidationException.java index c63f853301fa..9e1832215df4 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/ExpressionValidationException.java +++ b/processing/src/main/java/org/apache/druid/math/expr/ExpressionValidationException.java @@ -29,8 +29,18 @@ public ExpressionValidationException(NamedFunction fn, String msg, Object... for super("Function[%s] %s", fn.name(), StringUtils.format(msg, formatArgs)); } + public ExpressionValidationException(String name, String msg, Object... formatArgs) + { + super("Function[%s] %s", name, StringUtils.format(msg, formatArgs)); + } + public ExpressionValidationException(NamedFunction fn, Throwable e, String msg, Object... formatArgs) { super(e, "Function[%s] %s", fn.name(), StringUtils.format(msg, formatArgs)); } + + public ExpressionValidationException(String name, Throwable e, String msg, Object... formatArgs) + { + super(e, "Function[%s] %s", name, StringUtils.format(msg, formatArgs)); + } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/Function.java b/processing/src/main/java/org/apache/druid/math/expr/Function.java index a4171cc8b35c..b17fa36b31cf 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/Function.java +++ b/processing/src/main/java/org/apache/druid/math/expr/Function.java @@ -30,6 +30,7 @@ import org.apache.druid.java.util.common.UOE; import org.apache.druid.math.expr.vector.CastToTypeVectorProcessor; import org.apache.druid.math.expr.vector.ExprVectorProcessor; +import org.apache.druid.math.expr.vector.VectorConditionalProcessors; import org.apache.druid.math.expr.vector.VectorMathProcessors; import org.apache.druid.math.expr.vector.VectorProcessors; import org.apache.druid.math.expr.vector.VectorStringProcessors; @@ -799,7 +800,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.abs(inspector, args.get(0)); + return VectorMathProcessors.abs().asProcessor(inspector, args.get(0)); } } @@ -820,7 +821,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.acos(inspector, args.get(0)); + return VectorMathProcessors.acos().asProcessor(inspector, args.get(0)); } } @@ -841,7 +842,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.asin(inspector, args.get(0)); + return VectorMathProcessors.asin().asProcessor(inspector, args.get(0)); } } @@ -862,16 +863,18 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.atan(inspector, args.get(0)); + return VectorMathProcessors.atan().asProcessor(inspector, args.get(0)); } } class BitwiseComplement extends UnivariateMathFunction { + public static final String NAME = "bitwiseComplement"; + @Override public String name() { - return "bitwiseComplement"; + return NAME; } @Nullable @@ -890,7 +893,7 @@ protected ExprEval eval(long param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.bitwiseComplement(inspector, args.get(0)); + return VectorMathProcessors.bitwiseComplement().asProcessor(inspector, args.get(0)); } } @@ -922,7 +925,7 @@ protected ExprEval eval(long param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.bitwiseConvertLongBitsToDouble(inspector, args.get(0)); + return VectorMathProcessors.bitwiseConvertLongBitsToDouble().asProcessor(inspector, args.get(0)); } } @@ -954,7 +957,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.bitwiseConvertDoubleToLongBits(inspector, args.get(0)); + return VectorMathProcessors.bitwiseConvertDoubleToLongBits().asProcessor(inspector, args.get(0)); } } @@ -975,7 +978,7 @@ protected ExprEval eval(long x, long y) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.bitwiseAnd(inspector, args.get(0), args.get(1)); + return VectorMathProcessors.bitwiseAnd().asProcessor(inspector, args.get(0), args.get(1)); } } @@ -996,7 +999,7 @@ protected ExprEval eval(long x, long y) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.bitwiseOr(inspector, args.get(0), args.get(1)); + return VectorMathProcessors.bitwiseOr().asProcessor(inspector, args.get(0), args.get(1)); } } @@ -1017,7 +1020,7 @@ protected ExprEval eval(long x, long y) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.bitwiseShiftLeft(inspector, args.get(0), args.get(1)); + return VectorMathProcessors.bitwiseShiftLeft().asProcessor(inspector, args.get(0), args.get(1)); } } @@ -1038,7 +1041,7 @@ protected ExprEval eval(long x, long y) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.bitwiseShiftRight(inspector, args.get(0), args.get(1)); + return VectorMathProcessors.bitwiseShiftRight().asProcessor(inspector, args.get(0), args.get(1)); } } @@ -1059,7 +1062,7 @@ protected ExprEval eval(long x, long y) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.bitwiseXor(inspector, args.get(0), args.get(1)); + return VectorMathProcessors.bitwiseXor().asProcessor(inspector, args.get(0), args.get(1)); } } @@ -1080,7 +1083,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.cbrt(inspector, args.get(0)); + return VectorMathProcessors.cbrt().asProcessor(inspector, args.get(0)); } } @@ -1101,7 +1104,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.ceil(inspector, args.get(0)); + return VectorMathProcessors.ceil().asProcessor(inspector, args.get(0)); } } @@ -1122,7 +1125,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.cos(inspector, args.get(0)); + return VectorMathProcessors.cos().asProcessor(inspector, args.get(0)); } } @@ -1143,7 +1146,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.cosh(inspector, args.get(0)); + return VectorMathProcessors.cosh().asProcessor(inspector, args.get(0)); } } @@ -1164,7 +1167,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.cot(inspector, args.get(0)); + return VectorMathProcessors.cot().asProcessor(inspector, args.get(0)); } } @@ -1239,7 +1242,7 @@ public ExpressionType getOutputType(Expr.InputBindingInspector inspector, List ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.longDivide(inspector, args.get(0), args.get(1)); + return VectorMathProcessors.longDivide().asProcessor(inspector, args.get(0), args.get(1)); } } @@ -1260,7 +1263,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.exp(inspector, args.get(0)); + return VectorMathProcessors.exp().asProcessor(inspector, args.get(0)); } } @@ -1281,7 +1284,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.expm1(inspector, args.get(0)); + return VectorMathProcessors.expm1().asProcessor(inspector, args.get(0)); } } @@ -1302,7 +1305,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.floor(inspector, args.get(0)); + return VectorMathProcessors.floor().asProcessor(inspector, args.get(0)); } } @@ -1330,7 +1333,7 @@ public ExpressionType getOutputType(Expr.InputBindingInspector inspector, List ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.getExponent(inspector, args.get(0)); + return VectorMathProcessors.getExponent().asProcessor(inspector, args.get(0)); } } @@ -1351,7 +1354,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.log(inspector, args.get(0)); + return VectorMathProcessors.log().asProcessor(inspector, args.get(0)); } } @@ -1372,7 +1375,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.log10(inspector, args.get(0)); + return VectorMathProcessors.log10().asProcessor(inspector, args.get(0)); } } @@ -1393,7 +1396,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.log1p(inspector, args.get(0)); + return VectorMathProcessors.log1p().asProcessor(inspector, args.get(0)); } } @@ -1414,7 +1417,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.nextUp(inspector, args.get(0)); + return VectorMathProcessors.nextUp().asProcessor(inspector, args.get(0)); } } @@ -1435,7 +1438,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.rint(inspector, args.get(0)); + return VectorMathProcessors.rint().asProcessor(inspector, args.get(0)); } } @@ -1546,7 +1549,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.signum(inspector, args.get(0)); + return VectorMathProcessors.signum().asProcessor(inspector, args.get(0)); } } @@ -1567,7 +1570,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.sin(inspector, args.get(0)); + return VectorMathProcessors.sin().asProcessor(inspector, args.get(0)); } } @@ -1588,7 +1591,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.sinh(inspector, args.get(0)); + return VectorMathProcessors.sinh().asProcessor(inspector, args.get(0)); } } @@ -1609,7 +1612,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.sqrt(inspector, args.get(0)); + return VectorMathProcessors.sqrt().asProcessor(inspector, args.get(0)); } } @@ -1630,7 +1633,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.tan(inspector, args.get(0)); + return VectorMathProcessors.tan().asProcessor(inspector, args.get(0)); } } @@ -1651,7 +1654,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.tanh(inspector, args.get(0)); + return VectorMathProcessors.tanh().asProcessor(inspector, args.get(0)); } } @@ -1672,7 +1675,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.toDegrees(inspector, args.get(0)); + return VectorMathProcessors.toDegrees().asProcessor(inspector, args.get(0)); } } @@ -1693,7 +1696,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.toRadians(inspector, args.get(0)); + return VectorMathProcessors.toRadians().asProcessor(inspector, args.get(0)); } } @@ -1714,7 +1717,7 @@ protected ExprEval eval(double param) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.ulp(inspector, args.get(0)); + return VectorMathProcessors.ulp().asProcessor(inspector, args.get(0)); } } @@ -1735,7 +1738,7 @@ protected ExprEval eval(double y, double x) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.atan2(inspector, args.get(0), args.get(1)); + return VectorMathProcessors.atan2().asProcessor(inspector, args.get(0), args.get(1)); } } @@ -1756,7 +1759,7 @@ protected ExprEval eval(double x, double y) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.copySign(inspector, args.get(0), args.get(1)); + return VectorMathProcessors.copySign().asProcessor(inspector, args.get(0), args.get(1)); } } @@ -1777,7 +1780,7 @@ protected ExprEval eval(double x, double y) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.hypot(inspector, args.get(0), args.get(1)); + return VectorMathProcessors.hypot().asProcessor(inspector, args.get(0), args.get(1)); } } @@ -1798,7 +1801,7 @@ protected ExprEval eval(double x, double y) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.remainder(inspector, args.get(0), args.get(1)); + return VectorMathProcessors.remainder().asProcessor(inspector, args.get(0), args.get(1)); } } @@ -1825,7 +1828,7 @@ protected ExprEval eval(double x, double y) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.max(inspector, args.get(0), args.get(1)); + return VectorMathProcessors.max().asProcessor(inspector, args.get(0), args.get(1)); } } @@ -1852,7 +1855,7 @@ protected ExprEval eval(double x, double y) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.min(inspector, args.get(0), args.get(1)); + return VectorMathProcessors.min().asProcessor(inspector, args.get(0), args.get(1)); } } @@ -1873,7 +1876,7 @@ protected ExprEval eval(double x, double y) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.nextAfter(inspector, args.get(0), args.get(1)); + return VectorMathProcessors.nextAfter().asProcessor(inspector, args.get(0), args.get(1)); } } @@ -1894,7 +1897,7 @@ protected ExprEval eval(double x, double y) @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.doublePower(inspector, args.get(0), args.get(1)); + return VectorMathProcessors.doublePower().asProcessor(inspector, args.get(0), args.get(1)); } } @@ -1938,7 +1941,7 @@ public boolean canVectorize(Expr.InputBindingInspector inspector, List arg @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorMathProcessors.scalb(inspector, args.get(0), args.get(1)); + return VectorMathProcessors.scalb().asProcessor(inspector, args.get(0), args.get(1)); } } @@ -2026,8 +2029,7 @@ public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspe { return CastToTypeVectorProcessor.cast( args.get(0).asVectorProcessor(inspector), - ExpressionType.fromString(StringUtils.toUpperCase(args.get(1).getLiteralValue().toString())), - inspector.getMaxVectorSize() + ExpressionType.fromString(StringUtils.toUpperCase(args.get(1).getLiteralValue().toString())) ); } } @@ -2558,7 +2560,7 @@ public boolean canVectorize(Expr.InputBindingInspector inspector, List arg @Override public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) { - return VectorProcessors.nvl(inspector, args.get(0), args.get(1)); + return VectorConditionalProcessors.nvl(inspector, args.get(0), args.get(1)); } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/UnaryOperatorExpr.java b/processing/src/main/java/org/apache/druid/math/expr/UnaryOperatorExpr.java index f9f2c5bbcc28..2a5181f07fdf 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/UnaryOperatorExpr.java +++ b/processing/src/main/java/org/apache/druid/math/expr/UnaryOperatorExpr.java @@ -116,6 +116,7 @@ public String toString() @SuppressWarnings("ClassName") class UnaryMinusExpr extends UnaryExpr { + UnaryMinusExpr(String op, Expr expr) { super(op, expr); @@ -156,7 +157,7 @@ public boolean canVectorize(InputBindingInspector inspector) @Override public ExprVectorProcessor asVectorProcessor(VectorInputBindingInspector inspector) { - return VectorMathProcessors.negate(inspector, expr); + return VectorMathProcessors.negate().asProcessor(inspector, expr); } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/BaseExprEvalVector.java b/processing/src/main/java/org/apache/druid/math/expr/vector/BaseExprEvalVector.java new file mode 100644 index 000000000000..f1ce76cd93fd --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/BaseExprEvalVector.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import javax.annotation.Nullable; + +public abstract class BaseExprEvalVector implements ExprEvalVector +{ + final T values; + @Nullable + final boolean[] nulls; + + public BaseExprEvalVector(T values, @Nullable boolean[] nulls) + { + this.values = values; + this.nulls = nulls; + } + + @Override + public T values() + { + return values; + } + + @Override + @Nullable + public boolean[] getNullVector() + { + return nulls; + } +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/BivariateFunctionVectorProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/BivariateFunctionVectorProcessor.java index 0e5f92bc4197..e1502de27014 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/BivariateFunctionVectorProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/BivariateFunctionVectorProcessor.java @@ -26,8 +26,8 @@ /** * Basic vector processor that processes 2 inputs and works for both primitive value vectors and object vectors. - * Different from {@link BivariateLongFunctionVectorValueProcessor}, {@link BivariateDoubleFunctionVectorValueProcessor} - * and {@link BivariateFunctionVectorObjectProcessor} in that subclasses of this class must check for and directly + * Different from {@link LongBivariateFunctionVectorProcessor}, {@link DoubleBivariateFunctionVectorProcessor} + * and {@link BivariateObjectsFunctionVectorProcessor} in that subclasses of this class must check for and directly * decide how to handle null values. */ public abstract class BivariateFunctionVectorProcessor @@ -54,8 +54,8 @@ public ExprEvalVector evalVector(Expr.VectorInputBinding bindings) final ExprEvalVector lhs = left.evalVector(bindings); final ExprEvalVector rhs = right.evalVector(bindings); - TLeftInput leftValues = lhs.values; - TRightInput rightValues = rhs.values; + TLeftInput leftValues = lhs.values(); + TRightInput rightValues = rhs.values(); final boolean[] leftNulls = outputType.isNumeric() ? lhs.getNullVector() : null; final boolean[] rightNulls = outputType.isNumeric() ? rhs.getNullVector() : null; @@ -80,4 +80,10 @@ public ExpressionType getOutputType() { return outputType; } + + @Override + public int maxVectorSize() + { + return left.maxVectorSize(); + } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/BivariateFunctionVectorProcessorFactory.java b/processing/src/main/java/org/apache/druid/math/expr/vector/BivariateFunctionVectorProcessorFactory.java new file mode 100644 index 000000000000..1a32255becfe --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/BivariateFunctionVectorProcessorFactory.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.math.expr.Expr; + +public interface BivariateFunctionVectorProcessorFactory +{ + ExprVectorProcessor asProcessor(Expr.VectorInputBindingInspector inspector, Expr left, Expr right); +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/BivariateFunctionVectorObjectProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/BivariateObjectsFunctionVectorProcessor.java similarity index 92% rename from processing/src/main/java/org/apache/druid/math/expr/vector/BivariateFunctionVectorObjectProcessor.java rename to processing/src/main/java/org/apache/druid/math/expr/vector/BivariateObjectsFunctionVectorProcessor.java index 2f7ae4f079bb..7f853b57f501 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/BivariateFunctionVectorObjectProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/BivariateObjectsFunctionVectorProcessor.java @@ -30,7 +30,7 @@ * In SQL compatible null handling mode, for a row with either left or right input as a null value, it will be handled * by {@link #processNull(int)} instead of {@link #processIndex(Object, Object, int)}. */ -public abstract class BivariateFunctionVectorObjectProcessor +public abstract class BivariateObjectsFunctionVectorProcessor implements ExprVectorProcessor { final ExprVectorProcessor left; @@ -38,7 +38,7 @@ public abstract class BivariateFunctionVectorObjectProcessor left, ExprVectorProcessor right, TOutput outValues @@ -76,6 +76,12 @@ public ExprEvalVector evalVector(Expr.VectorInputBinding bindings) return asEval(); } + @Override + public int maxVectorSize() + { + return left.maxVectorSize(); + } + abstract void processIndex(TLeftInput leftInput, TRightInput rightInput, int i); abstract void processNull(int i); diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/CastToObjectVectorProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/CastToObjectVectorProcessor.java index 32d72d4b4bcd..5fee4f9e3fc8 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/CastToObjectVectorProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/CastToObjectVectorProcessor.java @@ -31,14 +31,13 @@ public class CastToObjectVectorProcessor extends CastToTypeVectorProcessor delegate, - ExpressionType outputType, - int maxVectorSize + ExpressionType outputType ) { super(delegate); this.delegateType = delegate.getOutputType(); this.outputType = outputType; - this.output = new Object[maxVectorSize]; + this.output = new Object[delegate.maxVectorSize()]; } @Override diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/CastToTypeVectorProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/CastToTypeVectorProcessor.java index 62f2cf505ff1..64d768d9a6d3 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/CastToTypeVectorProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/CastToTypeVectorProcessor.java @@ -32,8 +32,7 @@ protected CastToTypeVectorProcessor(ExprVectorProcessor delegate) public static ExprVectorProcessor cast( ExprVectorProcessor castInput, - ExpressionType castToType, - int maxVectorSize + ExpressionType castToType ) { final ExprVectorProcessor caster; @@ -49,9 +48,15 @@ public static ExprVectorProcessor cast( caster = new CastToDoubleVectorProcessor(castInput); break; default: - caster = new CastToObjectVectorProcessor(castInput, castToType, maxVectorSize); + caster = new CastToObjectVectorProcessor(castInput, castToType); } } return (ExprVectorProcessor) caster; } + + @Override + public int maxVectorSize() + { + return delegate.maxVectorSize(); + } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleOutDoubleLongInFunctionVectorValueProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleBivariateDoubleLongFunctionVectorProcessor.java similarity index 63% rename from processing/src/main/java/org/apache/druid/math/expr/vector/DoubleOutDoubleLongInFunctionVectorValueProcessor.java rename to processing/src/main/java/org/apache/druid/math/expr/vector/DoubleBivariateDoubleLongFunctionVectorProcessor.java index ae3a0a5d8da1..81a11255fae4 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleOutDoubleLongInFunctionVectorValueProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleBivariateDoubleLongFunctionVectorProcessor.java @@ -20,28 +20,29 @@ package org.apache.druid.math.expr.vector; import org.apache.druid.math.expr.ExpressionType; +import org.apache.druid.math.expr.vector.functional.DoubleBivariateDoubleLongFunction; /** - * specialized {@link BivariateDoubleFunctionVectorValueProcessor} for processing (double[], long[]) -> double[] + * specialized {@link DoubleBivariateFunctionVectorProcessor} for processing (double[], long[]) -> double[] */ -public abstract class DoubleOutDoubleLongInFunctionVectorValueProcessor - extends BivariateDoubleFunctionVectorValueProcessor +public final class DoubleBivariateDoubleLongFunctionVectorProcessor + extends DoubleBivariateFunctionVectorProcessor { - public DoubleOutDoubleLongInFunctionVectorValueProcessor( + private final DoubleBivariateDoubleLongFunction doubleLongFunction; + + public DoubleBivariateDoubleLongFunctionVectorProcessor( ExprVectorProcessor left, ExprVectorProcessor right, - int maxVectorSize + DoubleBivariateDoubleLongFunction doubleLongFunction ) { super( - CastToTypeVectorProcessor.cast(left, ExpressionType.DOUBLE, maxVectorSize), - CastToTypeVectorProcessor.cast(right, ExpressionType.LONG, maxVectorSize), - maxVectorSize + CastToTypeVectorProcessor.cast(left, ExpressionType.DOUBLE), + CastToTypeVectorProcessor.cast(right, ExpressionType.LONG) ); + this.doubleLongFunction = doubleLongFunction; } - public abstract double apply(double left, long right); - @Override public ExpressionType getOutputType() { @@ -49,8 +50,8 @@ public ExpressionType getOutputType() } @Override - final void processIndex(double[] leftInput, long[] rightInput, int i) + void processIndex(double[] leftInput, long[] rightInput, int i) { - outValues[i] = apply(leftInput[i], rightInput[i]); + outValues[i] = doubleLongFunction.process(leftInput[i], rightInput[i]); } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleOutDoublesInFunctionVectorValueProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleBivariateDoublesFunctionVectorProcessor.java similarity index 64% rename from processing/src/main/java/org/apache/druid/math/expr/vector/DoubleOutDoublesInFunctionVectorValueProcessor.java rename to processing/src/main/java/org/apache/druid/math/expr/vector/DoubleBivariateDoublesFunctionVectorProcessor.java index 8033b267cae6..31d21d8a042a 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleOutDoublesInFunctionVectorValueProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleBivariateDoublesFunctionVectorProcessor.java @@ -20,28 +20,29 @@ package org.apache.druid.math.expr.vector; import org.apache.druid.math.expr.ExpressionType; +import org.apache.druid.math.expr.vector.functional.DoubleBivariateDoublesFunction; /** - * specialized {@link BivariateDoubleFunctionVectorValueProcessor} for processing (double[], double[]) -> double[] + * specialized {@link DoubleBivariateFunctionVectorProcessor} for processing (double[], double[]) -> double[] */ -public abstract class DoubleOutDoublesInFunctionVectorValueProcessor - extends BivariateDoubleFunctionVectorValueProcessor +public final class DoubleBivariateDoublesFunctionVectorProcessor + extends DoubleBivariateFunctionVectorProcessor { - public DoubleOutDoublesInFunctionVectorValueProcessor( + private final DoubleBivariateDoublesFunction doublesFunction; + + public DoubleBivariateDoublesFunctionVectorProcessor( ExprVectorProcessor left, ExprVectorProcessor right, - int maxVectorSize + DoubleBivariateDoublesFunction doublesFunction ) { super( - CastToTypeVectorProcessor.cast(left, ExpressionType.DOUBLE, maxVectorSize), - CastToTypeVectorProcessor.cast(right, ExpressionType.DOUBLE, maxVectorSize), - maxVectorSize + CastToTypeVectorProcessor.cast(left, ExpressionType.DOUBLE), + CastToTypeVectorProcessor.cast(right, ExpressionType.DOUBLE) ); + this.doublesFunction = doublesFunction; } - public abstract double apply(double left, double right); - @Override public ExpressionType getOutputType() { @@ -49,8 +50,8 @@ public ExpressionType getOutputType() } @Override - final void processIndex(double[] leftInput, double[] rightInput, int i) + void processIndex(double[] leftInput, double[] rightInput, int i) { - outValues[i] = apply(leftInput[i], rightInput[i]); + outValues[i] = doublesFunction.process(leftInput[i], rightInput[i]); } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/BivariateDoubleFunctionVectorValueProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleBivariateFunctionVectorProcessor.java similarity index 85% rename from processing/src/main/java/org/apache/druid/math/expr/vector/BivariateDoubleFunctionVectorValueProcessor.java rename to processing/src/main/java/org/apache/druid/math/expr/vector/DoubleBivariateFunctionVectorProcessor.java index f23ee5aa38ff..a5628f5a655e 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/BivariateDoubleFunctionVectorValueProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleBivariateFunctionVectorProcessor.java @@ -26,10 +26,10 @@ * output, and are backed by a primitive values instead of an object values (and need to use the null vectors instead of * checking the vector themselves for nulls) * - * this one is specialized for producing double[], see {@link BivariateLongFunctionVectorValueProcessor} for + * this one is specialized for producing double[], see {@link LongBivariateFunctionVectorProcessor} for * long[] primitives. */ -public abstract class BivariateDoubleFunctionVectorValueProcessor +public abstract class DoubleBivariateFunctionVectorProcessor implements ExprVectorProcessor { final ExprVectorProcessor left; @@ -37,16 +37,15 @@ public abstract class BivariateDoubleFunctionVectorValueProcessor left, - ExprVectorProcessor right, - int maxVectorSize + ExprVectorProcessor right ) { this.left = left; this.right = right; - this.outValues = new double[maxVectorSize]; - this.outNulls = new boolean[maxVectorSize]; + this.outValues = new double[left.maxVectorSize()]; + this.outNulls = new boolean[left.maxVectorSize()]; } @Override @@ -89,4 +88,10 @@ final ExprEvalVector asEval() { return new ExprEvalDoubleVector(outValues, outNulls); } + + @Override + public int maxVectorSize() + { + return outValues.length; + } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleOutLongDoubleInFunctionVectorValueProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleBivariateLongDoubleFunctionVectorProcessor.java similarity index 63% rename from processing/src/main/java/org/apache/druid/math/expr/vector/DoubleOutLongDoubleInFunctionVectorValueProcessor.java rename to processing/src/main/java/org/apache/druid/math/expr/vector/DoubleBivariateLongDoubleFunctionVectorProcessor.java index b98004d4774a..6dc02ca0a4c5 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleOutLongDoubleInFunctionVectorValueProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleBivariateLongDoubleFunctionVectorProcessor.java @@ -20,28 +20,29 @@ package org.apache.druid.math.expr.vector; import org.apache.druid.math.expr.ExpressionType; +import org.apache.druid.math.expr.vector.functional.DoubleBivariateLongDoubleFunction; /** - * specialized {@link BivariateDoubleFunctionVectorValueProcessor} for processing (long[], double[]) -> double[] + * specialized {@link DoubleBivariateFunctionVectorProcessor} for processing (long[], double[]) -> double[] */ -public abstract class DoubleOutLongDoubleInFunctionVectorValueProcessor - extends BivariateDoubleFunctionVectorValueProcessor +public final class DoubleBivariateLongDoubleFunctionVectorProcessor + extends DoubleBivariateFunctionVectorProcessor { - public DoubleOutLongDoubleInFunctionVectorValueProcessor( + private final DoubleBivariateLongDoubleFunction longDoubleFunction; + + public DoubleBivariateLongDoubleFunctionVectorProcessor( ExprVectorProcessor left, ExprVectorProcessor right, - int maxVectorSize + DoubleBivariateLongDoubleFunction longDoubleFunction ) { super( - CastToTypeVectorProcessor.cast(left, ExpressionType.LONG, maxVectorSize), - CastToTypeVectorProcessor.cast(right, ExpressionType.DOUBLE, maxVectorSize), - maxVectorSize + CastToTypeVectorProcessor.cast(left, ExpressionType.LONG), + CastToTypeVectorProcessor.cast(right, ExpressionType.DOUBLE) ); + this.longDoubleFunction = longDoubleFunction; } - public abstract double apply(long left, double right); - @Override public ExpressionType getOutputType() { @@ -49,8 +50,8 @@ public ExpressionType getOutputType() } @Override - final void processIndex(long[] leftInput, double[] rightInput, int i) + void processIndex(long[] leftInput, double[] rightInput, int i) { - outValues[i] = apply(leftInput[i], rightInput[i]); + outValues[i] = longDoubleFunction.process(leftInput[i], rightInput[i]); } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleOutLongsInFunctionVectorValueProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleBivariateLongsFunctionVectorProcessor.java similarity index 65% rename from processing/src/main/java/org/apache/druid/math/expr/vector/DoubleOutLongsInFunctionVectorValueProcessor.java rename to processing/src/main/java/org/apache/druid/math/expr/vector/DoubleBivariateLongsFunctionVectorProcessor.java index 507abf2c0e3f..9071c12fa977 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleOutLongsInFunctionVectorValueProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleBivariateLongsFunctionVectorProcessor.java @@ -20,28 +20,29 @@ package org.apache.druid.math.expr.vector; import org.apache.druid.math.expr.ExpressionType; +import org.apache.druid.math.expr.vector.functional.DoubleBivariateLongsFunction; /** - * specialized {@link BivariateDoubleFunctionVectorValueProcessor} for processing (long[], long[]) -> double[] + * specialized {@link DoubleBivariateFunctionVectorProcessor} for processing (long[], long[]) -> double[] */ -public abstract class DoubleOutLongsInFunctionVectorValueProcessor - extends BivariateDoubleFunctionVectorValueProcessor +public final class DoubleBivariateLongsFunctionVectorProcessor + extends DoubleBivariateFunctionVectorProcessor { - public DoubleOutLongsInFunctionVectorValueProcessor( + private final DoubleBivariateLongsFunction longsFunction; + + public DoubleBivariateLongsFunctionVectorProcessor( ExprVectorProcessor left, ExprVectorProcessor right, - int maxVectorSize + DoubleBivariateLongsFunction longsFunction ) { super( - CastToTypeVectorProcessor.cast(left, ExpressionType.LONG, maxVectorSize), - CastToTypeVectorProcessor.cast(right, ExpressionType.LONG, maxVectorSize), - maxVectorSize + CastToTypeVectorProcessor.cast(left, ExpressionType.LONG), + CastToTypeVectorProcessor.cast(right, ExpressionType.LONG) ); + this.longsFunction = longsFunction; } - public abstract double apply(long left, long right); - @Override public ExpressionType getOutputType() { @@ -49,8 +50,8 @@ public ExpressionType getOutputType() } @Override - final void processIndex(long[] leftInput, long[] rightInput, int i) + void processIndex(long[] leftInput, long[] rightInput, int i) { - outValues[i] = apply(leftInput[i], rightInput[i]); + outValues[i] = longsFunction.process(leftInput[i], rightInput[i]); } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleOutDoubleInFunctionVectorValueProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleUnivariateDoubleFunctionVectorProcessor.java similarity index 61% rename from processing/src/main/java/org/apache/druid/math/expr/vector/DoubleOutDoubleInFunctionVectorValueProcessor.java rename to processing/src/main/java/org/apache/druid/math/expr/vector/DoubleUnivariateDoubleFunctionVectorProcessor.java index 8edcae53c36b..c0424c2a29ec 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleOutDoubleInFunctionVectorValueProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleUnivariateDoubleFunctionVectorProcessor.java @@ -20,20 +20,25 @@ package org.apache.druid.math.expr.vector; import org.apache.druid.math.expr.ExpressionType; +import org.apache.druid.math.expr.vector.functional.DoubleUnivariateDoubleFunction; /** - * specialized {@link UnivariateDoubleFunctionVectorValueProcessor} for processing (double[]) -> double[] + * specialized {@link DoubleUnivariateFunctionVectorProcessor} for processing (double[]) -> double[] */ -public abstract class DoubleOutDoubleInFunctionVectorValueProcessor - extends UnivariateDoubleFunctionVectorValueProcessor +public final class DoubleUnivariateDoubleFunctionVectorProcessor + extends DoubleUnivariateFunctionVectorProcessor { - public DoubleOutDoubleInFunctionVectorValueProcessor(ExprVectorProcessor processor, int maxVectorSize) + private final DoubleUnivariateDoubleFunction doubleFunction; + + public DoubleUnivariateDoubleFunctionVectorProcessor( + ExprVectorProcessor processor, + DoubleUnivariateDoubleFunction doubleFunction + ) { - super(CastToTypeVectorProcessor.cast(processor, ExpressionType.DOUBLE, maxVectorSize), maxVectorSize); + super(CastToTypeVectorProcessor.cast(processor, ExpressionType.DOUBLE)); + this.doubleFunction = doubleFunction; } - public abstract double apply(double input); - @Override public ExpressionType getOutputType() { @@ -41,8 +46,8 @@ public ExpressionType getOutputType() } @Override - final void processIndex(double[] input, int i) + void processIndex(double[] input, int i) { - outValues[i] = apply(input[i]); + outValues[i] = doubleFunction.process(input[i]); } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/UnivariateDoubleFunctionVectorValueProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleUnivariateFunctionVectorProcessor.java similarity index 81% rename from processing/src/main/java/org/apache/druid/math/expr/vector/UnivariateDoubleFunctionVectorValueProcessor.java rename to processing/src/main/java/org/apache/druid/math/expr/vector/DoubleUnivariateFunctionVectorProcessor.java index 65ad076fea12..b778fe8b9741 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/UnivariateDoubleFunctionVectorValueProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleUnivariateFunctionVectorProcessor.java @@ -26,23 +26,22 @@ * output, and are backed by a primitive value instead of an object value (and need to use the null vector instead of * checking the vector itself for nulls) * - * this one is specialized for producing double[], see {@link UnivariateLongFunctionVectorValueProcessor} for + * this one is specialized for producing double[], see {@link LongUnivariateFunctionVectorProcessor} for * long[] primitives. */ -public abstract class UnivariateDoubleFunctionVectorValueProcessor implements ExprVectorProcessor +public abstract class DoubleUnivariateFunctionVectorProcessor implements ExprVectorProcessor { final ExprVectorProcessor processor; final boolean[] outNulls; final double[] outValues; - public UnivariateDoubleFunctionVectorValueProcessor( - ExprVectorProcessor processor, - int maxVectorSize + public DoubleUnivariateFunctionVectorProcessor( + ExprVectorProcessor processor ) { this.processor = processor; - this.outNulls = new boolean[maxVectorSize]; - this.outValues = new double[maxVectorSize]; + this.outNulls = new boolean[processor.maxVectorSize()]; + this.outValues = new double[processor.maxVectorSize()]; } @Override @@ -74,6 +73,12 @@ public final ExprEvalVector evalVector(Expr.VectorInputBinding binding return asEval(); } + @Override + public int maxVectorSize() + { + return processor.maxVectorSize(); + } + abstract void processIndex(TInput input, int i); final ExprEvalVector asEval() diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleOutLongInFunctionVectorValueProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleUnivariateLongFunctionVectorProcessor.java similarity index 62% rename from processing/src/main/java/org/apache/druid/math/expr/vector/DoubleOutLongInFunctionVectorValueProcessor.java rename to processing/src/main/java/org/apache/druid/math/expr/vector/DoubleUnivariateLongFunctionVectorProcessor.java index 123ebcd67abc..b3cde00e1a93 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleOutLongInFunctionVectorValueProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/DoubleUnivariateLongFunctionVectorProcessor.java @@ -20,20 +20,25 @@ package org.apache.druid.math.expr.vector; import org.apache.druid.math.expr.ExpressionType; +import org.apache.druid.math.expr.vector.functional.DoubleUnivariateLongFunction; /** - * specialized {@link UnivariateDoubleFunctionVectorValueProcessor} for processing (long[]) -> double[] + * specialized {@link DoubleUnivariateFunctionVectorProcessor} for processing (long[]) -> double[] */ -public abstract class DoubleOutLongInFunctionVectorValueProcessor - extends UnivariateDoubleFunctionVectorValueProcessor +public final class DoubleUnivariateLongFunctionVectorProcessor + extends DoubleUnivariateFunctionVectorProcessor { - public DoubleOutLongInFunctionVectorValueProcessor(ExprVectorProcessor processor, int maxVectorSize) + private final DoubleUnivariateLongFunction longFunction; + + public DoubleUnivariateLongFunctionVectorProcessor( + ExprVectorProcessor processor, + DoubleUnivariateLongFunction longFunction + ) { - super(CastToTypeVectorProcessor.cast(processor, ExpressionType.LONG, maxVectorSize), maxVectorSize); + super(CastToTypeVectorProcessor.cast(processor, ExpressionType.LONG)); + this.longFunction = longFunction; } - public abstract double apply(long input); - @Override public ExpressionType getOutputType() { @@ -41,8 +46,8 @@ public ExpressionType getOutputType() } @Override - final void processIndex(long[] input, int i) + void processIndex(long[] input, int i) { - outValues[i] = apply(input[i]); + outValues[i] = longFunction.process(input[i]); } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/ExprEvalBindingVector.java b/processing/src/main/java/org/apache/druid/math/expr/vector/ExprEvalBindingVector.java new file mode 100644 index 000000000000..a357a1a1e5f9 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/ExprEvalBindingVector.java @@ -0,0 +1,172 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.common.config.NullHandling; +import org.apache.druid.math.expr.Evals; +import org.apache.druid.math.expr.Expr; +import org.apache.druid.math.expr.ExprEval; +import org.apache.druid.math.expr.ExprType; +import org.apache.druid.math.expr.ExpressionType; + +import javax.annotation.Nullable; + +/** + * {@link ExprEvalVector} backed directly by an underlying {@link Expr.VectorInputBinding} + */ +public class ExprEvalBindingVector implements ExprEvalVector +{ + private final ExpressionType expressionType; + private final Expr.VectorInputBinding bindings; + private final String bindingName; + + @Nullable + private long[] longs; + @Nullable + private double[] doubles; + + @Nullable + private boolean[] numericNulls; + + public ExprEvalBindingVector( + ExpressionType expressionType, + Expr.VectorInputBinding bindings, + String name + ) + { + this.expressionType = expressionType; + this.bindings = bindings; + this.bindingName = name; + } + + @Override + public ExpressionType getType() + { + return expressionType; + } + + @Override + public T values() + { + if (expressionType.is(ExprType.LONG)) { + return (T) getLongVector(); + } else if (expressionType.is(ExprType.DOUBLE)) { + return (T) getDoubleVector(); + } + return (T) bindings.getObjectVector(bindingName); + } + + @Override + public long[] getLongVector() + { + if (expressionType.isNumeric()) { + return bindings.getLongVector(bindingName); + } + computeNumbers(); + return longs; + } + + @Override + public double[] getDoubleVector() + { + if (expressionType.isNumeric()) { + return bindings.getDoubleVector(bindingName); + } + computeNumbers(); + return doubles; + } + + @Nullable + @Override + public boolean[] getNullVector() + { + if (expressionType.isNumeric()) { + return bindings.getNullVector(bindingName); + } + computeNumbers(); + return numericNulls; + } + + @Override + public Object[] getObjectVector() + { + if (expressionType.is(ExprType.LONG)) { + final long[] values = bindings.getLongVector(bindingName); + final boolean[] nulls = bindings.getNullVector(bindingName); + final Long[] objects = new Long[values.length]; + if (nulls != null) { + for (int i = 0; i < values.length; i++) { + objects[i] = nulls[i] ? null : values[i]; + } + } else { + for (int i = 0; i < values.length; i++) { + objects[i] = values[i]; + } + } + return objects; + } else if (expressionType.is(ExprType.DOUBLE)) { + final double[] values = bindings.getDoubleVector(bindingName); + final boolean[] nulls = bindings.getNullVector(bindingName); + Double[] objects = new Double[values.length]; + if (nulls != null) { + for (int i = 0; i < values.length; i++) { + objects[i] = nulls[i] ? null : values[i]; + } + } else { + for (int i = 0; i < values.length; i++) { + objects[i] = values[i]; + } + } + return objects; + } + return bindings.getObjectVector(bindingName); + } + + private void computeNumbers() + { + final Object[] values = getObjectVector(); + if (longs == null) { + longs = new long[values.length]; + doubles = new double[values.length]; + numericNulls = new boolean[values.length]; + boolean isString = expressionType.is(ExprType.STRING); + for (int i = 0; i < values.length; i++) { + if (isString) { + Number n = ExprEval.computeNumber(Evals.asString(values[i])); + if (n != null) { + longs[i] = n.longValue(); + doubles[i] = n.doubleValue(); + numericNulls[i] = false; + } else { + longs[i] = 0L; + doubles[i] = 0.0; + numericNulls[i] = NullHandling.sqlCompatible(); + } + } else { + // ARRAY, COMPLEX + final ExprEval valueEval = ExprEval.ofType(expressionType, values[i]); + longs[i] = valueEval.asLong(); + doubles[i] = valueEval.asDouble(); + numericNulls[i] = valueEval.isNumericNull(); + } + } + } + } +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/ExprEvalDoubleVector.java b/processing/src/main/java/org/apache/druid/math/expr/vector/ExprEvalDoubleVector.java index ef13ffa9918d..877a3a4f726d 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/ExprEvalDoubleVector.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/ExprEvalDoubleVector.java @@ -23,7 +23,7 @@ import java.util.Arrays; -public final class ExprEvalDoubleVector extends ExprEvalVector +public final class ExprEvalDoubleVector extends BaseExprEvalVector { public ExprEvalDoubleVector(double[] values, boolean[] nulls) { diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/ExprEvalLongVector.java b/processing/src/main/java/org/apache/druid/math/expr/vector/ExprEvalLongVector.java index aa38b172da02..b33eb968f17f 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/ExprEvalLongVector.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/ExprEvalLongVector.java @@ -24,7 +24,7 @@ import javax.annotation.Nullable; import java.util.Arrays; -public final class ExprEvalLongVector extends ExprEvalVector +public final class ExprEvalLongVector extends BaseExprEvalVector { public ExprEvalLongVector(long[] values, @Nullable boolean[] nulls) { diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/ExprEvalObjectVector.java b/processing/src/main/java/org/apache/druid/math/expr/vector/ExprEvalObjectVector.java index 05dba92ebd7f..908412a6eb50 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/ExprEvalObjectVector.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/ExprEvalObjectVector.java @@ -28,7 +28,7 @@ import javax.annotation.Nullable; -public final class ExprEvalObjectVector extends ExprEvalVector +public final class ExprEvalObjectVector extends BaseExprEvalVector { @Nullable private long[] longs; diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/ExprEvalVector.java b/processing/src/main/java/org/apache/druid/math/expr/vector/ExprEvalVector.java index f723ada4f7a5..6f65ce31fdf7 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/ExprEvalVector.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/ExprEvalVector.java @@ -29,34 +29,15 @@ * * The generic parameter T should be the native java array type of the vector result (long[], Object[], etc.) */ -public abstract class ExprEvalVector +public interface ExprEvalVector { - final T values; - @Nullable - final boolean[] nulls; - - public ExprEvalVector(T values, @Nullable boolean[] nulls) - { - this.values = values; - this.nulls = nulls; - } - - public T values() - { - return values; - } + ExpressionType getType(); + T values(); @Nullable - public boolean[] getNullVector() - { - return nulls; - } - - public abstract ExpressionType getType(); - - public abstract long[] getLongVector(); - - public abstract double[] getDoubleVector(); + boolean[] getNullVector(); - public abstract Object[] getObjectVector(); + long[] getLongVector(); + double[] getDoubleVector(); + Object[] getObjectVector(); } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/ExprVectorProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/ExprVectorProcessor.java index be0e4284270b..dfe38ff2a9b4 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/ExprVectorProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/ExprVectorProcessor.java @@ -31,4 +31,6 @@ public interface ExprVectorProcessor ExprEvalVector evalVector(Expr.VectorInputBinding bindings); ExpressionType getOutputType(); + + int maxVectorSize(); } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/FallbackVectorProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/FallbackVectorProcessor.java index 4c6732747528..115c9eed397d 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/FallbackVectorProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/FallbackVectorProcessor.java @@ -205,6 +205,12 @@ public ExprEvalVector evalVector(Expr.VectorInputBinding vectorBinding return new ExprEvalObjectVector(outValues, getOutputType()); } + + @Override + public int maxVectorSize() + { + return outValues.length; + } } /** @@ -250,6 +256,12 @@ public ExprEvalVector evalVector(Expr.VectorInputBinding vectorBindings) return new ExprEvalLongVector(outValues, anyNulls ? outNulls : null); } + + @Override + public int maxVectorSize() + { + return outValues.length; + } } /** @@ -295,6 +307,12 @@ public ExprEvalVector evalVector(Expr.VectorInputBinding vectorBinding return new ExprEvalDoubleVector(outValues, anyNulls ? outNulls : null); } + + @Override + public int maxVectorSize() + { + return outValues.length; + } } /** diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/FilteredVectorInputBinding.java b/processing/src/main/java/org/apache/druid/math/expr/vector/FilteredVectorInputBinding.java new file mode 100644 index 000000000000..73757b1e8cfc --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/FilteredVectorInputBinding.java @@ -0,0 +1,145 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.math.expr.Expr; +import org.apache.druid.math.expr.ExpressionType; +import org.apache.druid.query.filter.vector.VectorMatch; + +import javax.annotation.Nullable; +import java.util.HashMap; +import java.util.Map; + +public class FilteredVectorInputBinding implements Expr.VectorInputBinding +{ + private Expr.VectorInputBinding delegate; + // caches of re-usable vectors + private final Map cachedObjects; + private final Map cachedLongs; + private final Map cachedDoubles; + private final Map cachedNulls; + private final VectorMatch vectorMatch; + + public FilteredVectorInputBinding(int maxVectorSize) + { + final int[] match = new int[maxVectorSize]; + for (int i = 0; i < maxVectorSize; ++i) { + match[i] = i; + } + vectorMatch = VectorMatch.wrap(match); + // these caches exist so we do not need to allocate new vectors for each time the match changes, but they are not + // currently wired up as a true cache for re-using the values for calls to the get vector methods (so they + // recompute into re-used arrays for every call to the get methods). This is fine for current usage patterns, where + // we call the filtered bindings once per input per match, but if this ever changes we might want to consider + // caching per match too. this would involve moving match manipulation inside of this class instead of allowing + // callers to do it with getVectorMatch + this.cachedObjects = new HashMap<>(); + this.cachedLongs = new HashMap<>(); + this.cachedDoubles = new HashMap<>(); + this.cachedNulls = new HashMap<>(); + } + + public void setBindings(Expr.VectorInputBinding bindings) + { + this.delegate = bindings; + } + + public VectorMatch getVectorMatch() + { + return vectorMatch; + } + + @Nullable + @Override + public ExpressionType getType(String name) + { + return delegate.getType(name); + } + + @Override + public int getMaxVectorSize() + { + return delegate.getMaxVectorSize(); + } + + @Override + public Object[] getObjectVector(String name) + { + final Object[] baseVector = delegate.getObjectVector(name); + final Object[] matchVector = cachedObjects.computeIfAbsent(name, k -> new Object[delegate.getMaxVectorSize()]); + final int[] selection = vectorMatch.getSelection(); + for (int i = 0; i < vectorMatch.getSelectionSize(); i++) { + matchVector[i] = baseVector[selection[i]]; + } + return matchVector; + } + + @Override + public long[] getLongVector(String name) + { + final long[] baseVector = delegate.getLongVector(name); + final long[] matchVector = cachedLongs.computeIfAbsent(name, k -> new long[delegate.getMaxVectorSize()]); + final int[] selection = vectorMatch.getSelection(); + for (int i = 0; i < vectorMatch.getSelectionSize(); i++) { + matchVector[i] = baseVector[selection[i]]; + } + return matchVector; + } + + @Override + public double[] getDoubleVector(String name) + { + final double[] baseVector = delegate.getDoubleVector(name); + final double[] matchVector = cachedDoubles.computeIfAbsent(name, k -> new double[delegate.getMaxVectorSize()]); + final int[] selection = vectorMatch.getSelection(); + for (int i = 0; i < vectorMatch.getSelectionSize(); i++) { + matchVector[i] = baseVector[selection[i]]; + } + return matchVector; + } + + @Nullable + @Override + public boolean[] getNullVector(String name) + { + final boolean[] baseVector = delegate.getNullVector(name); + if (baseVector == null) { + return null; + } + final boolean[] matchVector = cachedNulls.computeIfAbsent(name, k -> new boolean[delegate.getMaxVectorSize()]); + final int[] selection = vectorMatch.getSelection(); + for (int i = 0; i < vectorMatch.getSelectionSize(); i++) { + matchVector[i] = baseVector[selection[i]]; + } + return matchVector; + } + + @Override + public int getCurrentVectorSize() + { + return vectorMatch.getSelectionSize(); + } + + @Override + public int getCurrentVectorId() + { + return delegate.getCurrentVectorId(); + } +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/LongOutDoubleLongInFunctionVectorValueProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/LongBivariateDoubleLongFunctionVectorProcessor.java similarity index 64% rename from processing/src/main/java/org/apache/druid/math/expr/vector/LongOutDoubleLongInFunctionVectorValueProcessor.java rename to processing/src/main/java/org/apache/druid/math/expr/vector/LongBivariateDoubleLongFunctionVectorProcessor.java index f3a58691e687..693b11dc1ea5 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/LongOutDoubleLongInFunctionVectorValueProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/LongBivariateDoubleLongFunctionVectorProcessor.java @@ -20,28 +20,29 @@ package org.apache.druid.math.expr.vector; import org.apache.druid.math.expr.ExpressionType; +import org.apache.druid.math.expr.vector.functional.LongBivariateDoubleLongFunction; /** - * specialized {@link BivariateLongFunctionVectorValueProcessor} for processing (double[], long[]) -> long[] + * specialized {@link LongBivariateFunctionVectorProcessor} for processing (double[], long[]) -> long[] */ -public abstract class LongOutDoubleLongInFunctionVectorValueProcessor - extends BivariateLongFunctionVectorValueProcessor +public final class LongBivariateDoubleLongFunctionVectorProcessor + extends LongBivariateFunctionVectorProcessor { - public LongOutDoubleLongInFunctionVectorValueProcessor( + private final LongBivariateDoubleLongFunction doubleLongFunction; + + public LongBivariateDoubleLongFunctionVectorProcessor( ExprVectorProcessor left, ExprVectorProcessor right, - int maxVectorSize + LongBivariateDoubleLongFunction doubleLongFunction ) { super( - CastToTypeVectorProcessor.cast(left, ExpressionType.DOUBLE, maxVectorSize), - CastToTypeVectorProcessor.cast(right, ExpressionType.LONG, maxVectorSize), - maxVectorSize + CastToTypeVectorProcessor.cast(left, ExpressionType.DOUBLE), + CastToTypeVectorProcessor.cast(right, ExpressionType.LONG) ); + this.doubleLongFunction = doubleLongFunction; } - public abstract long apply(double left, long right); - @Override public ExpressionType getOutputType() { @@ -49,8 +50,8 @@ public ExpressionType getOutputType() } @Override - final void processIndex(double[] leftInput, long[] rightInput, int i) + void processIndex(double[] leftInput, long[] rightInput, int i) { - outValues[i] = apply(leftInput[i], rightInput[i]); + outValues[i] = doubleLongFunction.process(leftInput[i], rightInput[i]); } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/LongOutDoublesInFunctionVectorValueProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/LongBivariateDoublesFunctionVectorProcessor.java similarity index 65% rename from processing/src/main/java/org/apache/druid/math/expr/vector/LongOutDoublesInFunctionVectorValueProcessor.java rename to processing/src/main/java/org/apache/druid/math/expr/vector/LongBivariateDoublesFunctionVectorProcessor.java index cf2193c1a02c..98cf1a076406 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/LongOutDoublesInFunctionVectorValueProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/LongBivariateDoublesFunctionVectorProcessor.java @@ -20,28 +20,29 @@ package org.apache.druid.math.expr.vector; import org.apache.druid.math.expr.ExpressionType; +import org.apache.druid.math.expr.vector.functional.LongBivariateDoublesFunction; /** - * specialized {@link BivariateLongFunctionVectorValueProcessor} for processing (double[], double[]) -> long[] + * specialized {@link LongBivariateFunctionVectorProcessor} for processing (double[], double[]) -> long[] */ -public abstract class LongOutDoublesInFunctionVectorValueProcessor - extends BivariateLongFunctionVectorValueProcessor +public final class LongBivariateDoublesFunctionVectorProcessor + extends LongBivariateFunctionVectorProcessor { - public LongOutDoublesInFunctionVectorValueProcessor( + private final LongBivariateDoublesFunction doublesFunction; + + public LongBivariateDoublesFunctionVectorProcessor( ExprVectorProcessor left, ExprVectorProcessor right, - int maxVectorSize + LongBivariateDoublesFunction doublesFunction ) { super( - CastToTypeVectorProcessor.cast(left, ExpressionType.DOUBLE, maxVectorSize), - CastToTypeVectorProcessor.cast(right, ExpressionType.DOUBLE, maxVectorSize), - maxVectorSize + CastToTypeVectorProcessor.cast(left, ExpressionType.DOUBLE), + CastToTypeVectorProcessor.cast(right, ExpressionType.DOUBLE) ); + this.doublesFunction = doublesFunction; } - public abstract long apply(double left, double right); - @Override public ExpressionType getOutputType() { @@ -49,8 +50,8 @@ public ExpressionType getOutputType() } @Override - final void processIndex(double[] leftInput, double[] rightInput, int i) + void processIndex(double[] leftInput, double[] rightInput, int i) { - outValues[i] = apply(leftInput[i], rightInput[i]); + outValues[i] = doublesFunction.process(leftInput[i], rightInput[i]); } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/BivariateLongFunctionVectorValueProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/LongBivariateFunctionVectorProcessor.java similarity index 85% rename from processing/src/main/java/org/apache/druid/math/expr/vector/BivariateLongFunctionVectorValueProcessor.java rename to processing/src/main/java/org/apache/druid/math/expr/vector/LongBivariateFunctionVectorProcessor.java index fb68317bec27..3a71e8437861 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/BivariateLongFunctionVectorValueProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/LongBivariateFunctionVectorProcessor.java @@ -26,10 +26,10 @@ * output, and are backed by a primitive values instead of an object values (and need to use the null vectors instead of * checking the vector themselves for nulls) * - * this one is specialized for producing long[], see {@link BivariateDoubleFunctionVectorValueProcessor} for + * this one is specialized for producing long[], see {@link DoubleBivariateFunctionVectorProcessor} for * double[] primitives. */ -public abstract class BivariateLongFunctionVectorValueProcessor +public abstract class LongBivariateFunctionVectorProcessor implements ExprVectorProcessor { final ExprVectorProcessor left; @@ -37,16 +37,15 @@ public abstract class BivariateLongFunctionVectorValueProcessor left, - ExprVectorProcessor right, - int maxVectorSize + ExprVectorProcessor right ) { this.left = left; this.right = right; - this.outValues = new long[maxVectorSize]; - this.outNulls = new boolean[maxVectorSize]; + this.outValues = new long[left.maxVectorSize()]; + this.outNulls = new boolean[left.maxVectorSize()]; } @Override @@ -89,4 +88,10 @@ final ExprEvalVector asEval() { return new ExprEvalLongVector(outValues, outNulls); } + + @Override + public int maxVectorSize() + { + return outValues.length; + } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/LongOutLongDoubleInFunctionVectorValueProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/LongBivariateLongDoubleFunctionVectorProcessor.java similarity index 64% rename from processing/src/main/java/org/apache/druid/math/expr/vector/LongOutLongDoubleInFunctionVectorValueProcessor.java rename to processing/src/main/java/org/apache/druid/math/expr/vector/LongBivariateLongDoubleFunctionVectorProcessor.java index e91213e2396b..63977131fa74 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/LongOutLongDoubleInFunctionVectorValueProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/LongBivariateLongDoubleFunctionVectorProcessor.java @@ -20,28 +20,29 @@ package org.apache.druid.math.expr.vector; import org.apache.druid.math.expr.ExpressionType; +import org.apache.druid.math.expr.vector.functional.LongBivariateLongDoubleFunction; /** - * specialized {@link BivariateLongFunctionVectorValueProcessor} for processing (long[], double[]) -> long[] + * specialized {@link LongBivariateFunctionVectorProcessor} for processing (long[], double[]) -> long[] */ -public abstract class LongOutLongDoubleInFunctionVectorValueProcessor - extends BivariateLongFunctionVectorValueProcessor +public final class LongBivariateLongDoubleFunctionVectorProcessor + extends LongBivariateFunctionVectorProcessor { - public LongOutLongDoubleInFunctionVectorValueProcessor( + private final LongBivariateLongDoubleFunction longDoubleFunction; + + public LongBivariateLongDoubleFunctionVectorProcessor( ExprVectorProcessor left, ExprVectorProcessor right, - int maxVectorSize + LongBivariateLongDoubleFunction longDoubleFunction ) { super( - CastToTypeVectorProcessor.cast(left, ExpressionType.LONG, maxVectorSize), - CastToTypeVectorProcessor.cast(right, ExpressionType.DOUBLE, maxVectorSize), - maxVectorSize + CastToTypeVectorProcessor.cast(left, ExpressionType.LONG), + CastToTypeVectorProcessor.cast(right, ExpressionType.DOUBLE) ); + this.longDoubleFunction = longDoubleFunction; } - public abstract long apply(long left, double right); - @Override public ExpressionType getOutputType() { @@ -49,8 +50,8 @@ public ExpressionType getOutputType() } @Override - final void processIndex(long[] leftInput, double[] rightInput, int i) + void processIndex(long[] leftInput, double[] rightInput, int i) { - outValues[i] = apply(leftInput[i], rightInput[i]); + outValues[i] = longDoubleFunction.process(leftInput[i], rightInput[i]); } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/LongOutLongsInFunctionVectorValueProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/LongBivariateLongsFunctionVectorProcessor.java similarity index 62% rename from processing/src/main/java/org/apache/druid/math/expr/vector/LongOutLongsInFunctionVectorValueProcessor.java rename to processing/src/main/java/org/apache/druid/math/expr/vector/LongBivariateLongsFunctionVectorProcessor.java index befabea3f1c8..2a21cae73233 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/LongOutLongsInFunctionVectorValueProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/LongBivariateLongsFunctionVectorProcessor.java @@ -20,28 +20,29 @@ package org.apache.druid.math.expr.vector; import org.apache.druid.math.expr.ExpressionType; +import org.apache.druid.math.expr.vector.functional.LongBivariateLongsFunction; /** - * specialized {@link BivariateLongFunctionVectorValueProcessor} for processing (long[], long[]) -> long[] + * specialized {@link LongBivariateFunctionVectorProcessor} for processing (long[], long[]) -> long[] */ -public abstract class LongOutLongsInFunctionVectorValueProcessor - extends BivariateLongFunctionVectorValueProcessor +public final class LongBivariateLongsFunctionVectorProcessor + extends LongBivariateFunctionVectorProcessor { - public LongOutLongsInFunctionVectorValueProcessor( - ExprVectorProcessor left, - ExprVectorProcessor right, - int maxVectorSize + private final LongBivariateLongsFunction longsFunction; + + public LongBivariateLongsFunctionVectorProcessor( + ExprVectorProcessor left, + ExprVectorProcessor right, + LongBivariateLongsFunction longsFunction ) { super( - CastToTypeVectorProcessor.cast(left, ExpressionType.LONG, maxVectorSize), - CastToTypeVectorProcessor.cast(right, ExpressionType.LONG, maxVectorSize), - maxVectorSize + CastToTypeVectorProcessor.cast(left, ExpressionType.LONG), + CastToTypeVectorProcessor.cast(right, ExpressionType.LONG) ); + this.longsFunction = longsFunction; } - public abstract long apply(long left, long right); - @Override public ExpressionType getOutputType() { @@ -49,8 +50,8 @@ public ExpressionType getOutputType() } @Override - final void processIndex(long[] leftInput, long[] rightInput, int i) + void processIndex(long[] leftInput, long[] rightInput, int i) { - outValues[i] = apply(leftInput[i], rightInput[i]); + outValues[i] = longsFunction.process(leftInput[i], rightInput[i]); } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/LongOutObjectsInFunctionVectorProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/LongBivariateObjectsFunctionVectorProcessor.java similarity index 69% rename from processing/src/main/java/org/apache/druid/math/expr/vector/LongOutObjectsInFunctionVectorProcessor.java rename to processing/src/main/java/org/apache/druid/math/expr/vector/LongBivariateObjectsFunctionVectorProcessor.java index 89caa4cf0a15..457892109c33 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/LongOutObjectsInFunctionVectorProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/LongBivariateObjectsFunctionVectorProcessor.java @@ -21,36 +21,34 @@ import org.apache.druid.common.config.NullHandling; import org.apache.druid.math.expr.ExpressionType; +import org.apache.druid.math.expr.vector.functional.LongBivariateObjectsFunction; -import javax.annotation.Nullable; - -public abstract class LongOutObjectsInFunctionVectorProcessor - extends BivariateFunctionVectorObjectProcessor +public final class LongBivariateObjectsFunctionVectorProcessor + extends BivariateObjectsFunctionVectorProcessor { + private final LongBivariateObjectsFunction objectsFunction; private final boolean[] outNulls; - protected LongOutObjectsInFunctionVectorProcessor( + public LongBivariateObjectsFunctionVectorProcessor( ExprVectorProcessor left, ExprVectorProcessor right, - int maxVectorSize, - ExpressionType inputType + ExpressionType inputType, + LongBivariateObjectsFunction objectsFunction ) { super( - CastToTypeVectorProcessor.cast(left, inputType, maxVectorSize), - CastToTypeVectorProcessor.cast(right, inputType, maxVectorSize), - new long[maxVectorSize] + CastToTypeVectorProcessor.cast(left, inputType), + CastToTypeVectorProcessor.cast(right, inputType), + new long[left.maxVectorSize()] ); - this.outNulls = new boolean[maxVectorSize]; + this.objectsFunction = objectsFunction; + this.outNulls = new boolean[left.maxVectorSize()]; } - @Nullable - abstract Long processValue(@Nullable Object leftVal, @Nullable Object rightVal); - @Override void processIndex(Object[] in1, Object[] in2, int i) { - final Long outVal = processValue(in1[i], in2[i]); + final Long outVal = objectsFunction.process(in1[i], in2[i]); if (outVal == null) { outValues[i] = 0L; outNulls[i] = NullHandling.sqlCompatible(); diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/LongOutDoubleInFunctionVectorValueProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/LongUnivariateDoubleFunctionVectorProcessor.java similarity index 62% rename from processing/src/main/java/org/apache/druid/math/expr/vector/LongOutDoubleInFunctionVectorValueProcessor.java rename to processing/src/main/java/org/apache/druid/math/expr/vector/LongUnivariateDoubleFunctionVectorProcessor.java index 13a907faa654..8ddcef04bd26 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/LongOutDoubleInFunctionVectorValueProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/LongUnivariateDoubleFunctionVectorProcessor.java @@ -20,20 +20,25 @@ package org.apache.druid.math.expr.vector; import org.apache.druid.math.expr.ExpressionType; +import org.apache.druid.math.expr.vector.functional.LongUnivariateDoubleFunction; /** - * specialized {@link UnivariateLongFunctionVectorValueProcessor} for processing (long[]) -> long[] + * specialized {@link LongUnivariateFunctionVectorProcessor} for processing (long[]) -> long[] */ -public abstract class LongOutDoubleInFunctionVectorValueProcessor - extends UnivariateLongFunctionVectorValueProcessor +public final class LongUnivariateDoubleFunctionVectorProcessor + extends LongUnivariateFunctionVectorProcessor { - public LongOutDoubleInFunctionVectorValueProcessor(ExprVectorProcessor processor, int maxVectorSize) + private final LongUnivariateDoubleFunction doubleFunction; + + public LongUnivariateDoubleFunctionVectorProcessor( + ExprVectorProcessor processor, + LongUnivariateDoubleFunction doubleFunction + ) { - super(CastToTypeVectorProcessor.cast(processor, ExpressionType.DOUBLE, maxVectorSize), maxVectorSize); + super(CastToTypeVectorProcessor.cast(processor, ExpressionType.DOUBLE)); + this.doubleFunction = doubleFunction; } - public abstract long apply(double input); - @Override public ExpressionType getOutputType() { @@ -41,8 +46,8 @@ public ExpressionType getOutputType() } @Override - final void processIndex(double[] input, int i) + void processIndex(double[] input, int i) { - outValues[i] = apply(input[i]); + outValues[i] = doubleFunction.process(input[i]); } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/UnivariateLongFunctionVectorValueProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/LongUnivariateFunctionVectorProcessor.java similarity index 81% rename from processing/src/main/java/org/apache/druid/math/expr/vector/UnivariateLongFunctionVectorValueProcessor.java rename to processing/src/main/java/org/apache/druid/math/expr/vector/LongUnivariateFunctionVectorProcessor.java index d24a5e9f1482..a35edce8e1ad 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/UnivariateLongFunctionVectorValueProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/LongUnivariateFunctionVectorProcessor.java @@ -26,23 +26,22 @@ * output, and are backed by a primitive value instead of an object value (and need to use the null vector instead of * checking the vector itself for nulls) * - * this one is specialized for producing long[], see {@link UnivariateDoubleFunctionVectorValueProcessor} for + * this one is specialized for producing long[], see {@link DoubleUnivariateFunctionVectorProcessor} for * double[] primitives. */ -public abstract class UnivariateLongFunctionVectorValueProcessor implements ExprVectorProcessor +public abstract class LongUnivariateFunctionVectorProcessor implements ExprVectorProcessor { final ExprVectorProcessor processor; final boolean[] outNulls; final long[] outValues; - public UnivariateLongFunctionVectorValueProcessor( - ExprVectorProcessor processor, - int maxVectorSize + public LongUnivariateFunctionVectorProcessor( + ExprVectorProcessor processor ) { this.processor = processor; - this.outNulls = new boolean[maxVectorSize]; - this.outValues = new long[maxVectorSize]; + this.outNulls = new boolean[processor.maxVectorSize()]; + this.outValues = new long[processor.maxVectorSize()]; } @Override @@ -74,6 +73,12 @@ public final ExprEvalVector evalVector(Expr.VectorInputBinding bindings) return asEval(); } + @Override + public int maxVectorSize() + { + return processor.maxVectorSize(); + } + abstract void processIndex(TInput input, int i); final ExprEvalVector asEval() diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/LongOutLongInFunctionVectorValueProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/LongUnivariateLongFunctionVectorProcessor.java similarity index 63% rename from processing/src/main/java/org/apache/druid/math/expr/vector/LongOutLongInFunctionVectorValueProcessor.java rename to processing/src/main/java/org/apache/druid/math/expr/vector/LongUnivariateLongFunctionVectorProcessor.java index 58e80dfc2b31..3fc35aec120e 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/LongOutLongInFunctionVectorValueProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/LongUnivariateLongFunctionVectorProcessor.java @@ -20,20 +20,25 @@ package org.apache.druid.math.expr.vector; import org.apache.druid.math.expr.ExpressionType; +import org.apache.druid.math.expr.vector.functional.LongUnivariateLongFunction; /** - * specialized {@link UnivariateLongFunctionVectorValueProcessor} for processing (long[]) -> long[] + * specialized {@link LongUnivariateFunctionVectorProcessor} for processing (long[]) -> long[] */ -public abstract class LongOutLongInFunctionVectorValueProcessor - extends UnivariateLongFunctionVectorValueProcessor +public final class LongUnivariateLongFunctionVectorProcessor + extends LongUnivariateFunctionVectorProcessor { - public LongOutLongInFunctionVectorValueProcessor(ExprVectorProcessor processor, int maxVectorSize) + private final LongUnivariateLongFunction longFunction; + + public LongUnivariateLongFunctionVectorProcessor( + ExprVectorProcessor processor, + LongUnivariateLongFunction longFunction + ) { - super(CastToTypeVectorProcessor.cast(processor, ExpressionType.LONG, maxVectorSize), maxVectorSize); + super(CastToTypeVectorProcessor.cast(processor, ExpressionType.LONG)); + this.longFunction = longFunction; } - public abstract long apply(long input); - @Override public ExpressionType getOutputType() { @@ -41,8 +46,8 @@ public ExpressionType getOutputType() } @Override - final void processIndex(long[] input, int i) + void processIndex(long[] input, int i) { - outValues[i] = apply(input[i]); + outValues[i] = longFunction.process(input[i]); } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/LongOutObjectInFunctionVectorProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/LongUnivariateObjectFunctionVectorProcessor.java similarity index 74% rename from processing/src/main/java/org/apache/druid/math/expr/vector/LongOutObjectInFunctionVectorProcessor.java rename to processing/src/main/java/org/apache/druid/math/expr/vector/LongUnivariateObjectFunctionVectorProcessor.java index 022eb6d4fe60..592a032ce298 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/LongOutObjectInFunctionVectorProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/LongUnivariateObjectFunctionVectorProcessor.java @@ -22,18 +22,17 @@ import org.apache.druid.math.expr.ExpressionType; /** - * specialized {@link UnivariateFunctionVectorObjectProcessor} for processing (Object[]) -> long[] + * specialized {@link UnivariateObjectFunctionVectorProcessor} for processing (Object[]) -> long[] */ -public abstract class LongOutObjectInFunctionVectorProcessor - extends UnivariateFunctionVectorObjectProcessor +public abstract class LongUnivariateObjectFunctionVectorProcessor + extends UnivariateObjectFunctionVectorProcessor { - public LongOutObjectInFunctionVectorProcessor( + public LongUnivariateObjectFunctionVectorProcessor( ExprVectorProcessor processor, - int maxVectorSize, ExpressionType inputType ) { - super(CastToTypeVectorProcessor.cast(processor, inputType, maxVectorSize), maxVectorSize, new long[maxVectorSize]); + super(CastToTypeVectorProcessor.cast(processor, inputType), new long[processor.maxVectorSize()]); } @Override @@ -47,4 +46,10 @@ public final ExprEvalVector asEval() { return new ExprEvalLongVector(outValues, outNulls); } + + @Override + public int maxVectorSize() + { + return processor.maxVectorSize(); + } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/MultivariateVectorProcessorFactory.java b/processing/src/main/java/org/apache/druid/math/expr/vector/MultivariateVectorProcessorFactory.java new file mode 100644 index 000000000000..385fb3b9cd37 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/MultivariateVectorProcessorFactory.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.math.expr.Expr; + +import java.util.List; + +public interface MultivariateVectorProcessorFactory +{ + ExprVectorProcessor asProcessor(List args, Expr.VectorInputBindingInspector inspector); +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/NvlDoubleVectorProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/NvlDoubleVectorProcessor.java new file mode 100644 index 000000000000..1e2f87987ef0 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/NvlDoubleVectorProcessor.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.math.expr.Expr; +import org.apache.druid.math.expr.ExpressionType; + +public final class NvlDoubleVectorProcessor extends NvlFunctionVectorProcessor +{ + private final double[] output; + private final boolean[] outputNulls; + + public NvlDoubleVectorProcessor( + ExprVectorProcessor inputProcessor, + ExprVectorProcessor elseProcessor + ) + { + super(ExpressionType.DOUBLE, inputProcessor, elseProcessor); + this.output = new double[inputProcessor.maxVectorSize()]; + this.outputNulls = new boolean[inputProcessor.maxVectorSize()]; + } + + @Override + public ExprEvalVector evalVector(Expr.VectorInputBinding bindings) + { + inputBindingFilterer.setBindings(bindings); + final ExprEvalVector inputVector = inputProcessor.evalVector(bindings); + + if (inputVector.getNullVector() == null) { + // this one has no nulls, just spit it out + return inputVector; + } + + + final double[] inputValues = inputVector.getDoubleVector(); + final boolean[] inputNulls = inputVector.getNullVector(); + final int[] selection = inputBindingFilterer.getVectorMatch().getSelection(); + int nulls = 0; + for (int i = 0; i < bindings.getCurrentVectorSize(); i++) { + if (inputNulls[i]) { + selection[nulls++] = i; + } else { + outputNulls[i] = false; + output[i] = inputValues[i]; + } + } + if (nulls == 0) { + return new ExprEvalDoubleVector(output, outputNulls); + } + inputBindingFilterer.getVectorMatch().setSelectionSize(nulls); + + if (nulls == bindings.getCurrentVectorSize()) { + // all nulls, just return the other + return elseProcessor.evalVector(bindings); + } + + final ExprEvalVector elseVector = elseProcessor.evalVector(inputBindingFilterer); + final double[] elseValues = elseVector.getDoubleVector(); + final boolean[] elseNulls = elseVector.getNullVector(); + for (int i = 0; i < nulls; i++) { + final int outIndex = selection[i]; + if (elseNulls != null && elseNulls[i]) { + outputNulls[outIndex] = true; + } else { + output[outIndex] = elseValues[i]; + outputNulls[outIndex] = false; + } + } + return new ExprEvalDoubleVector(output, outputNulls); + } +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/NvlFunctionVectorProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/NvlFunctionVectorProcessor.java new file mode 100644 index 000000000000..2053fd5b9295 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/NvlFunctionVectorProcessor.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.math.expr.ExpressionType; + +public abstract class NvlFunctionVectorProcessor implements ExprVectorProcessor +{ + final ExpressionType outputType; + final ExprVectorProcessor inputProcessor; + final ExprVectorProcessor elseProcessor; + final FilteredVectorInputBinding inputBindingFilterer; + + public NvlFunctionVectorProcessor( + ExpressionType outputType, + ExprVectorProcessor inputProcessor, + ExprVectorProcessor elseProcessor + ) + { + this.outputType = outputType; + this.inputProcessor = inputProcessor; + this.elseProcessor = elseProcessor; + this.inputBindingFilterer = new FilteredVectorInputBinding(inputProcessor.maxVectorSize()); + } + + @Override + public ExpressionType getOutputType() + { + return outputType; + } + + @Override + public int maxVectorSize() + { + return inputProcessor.maxVectorSize(); + } +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/NvlLongVectorProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/NvlLongVectorProcessor.java new file mode 100644 index 000000000000..9f709005f028 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/NvlLongVectorProcessor.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.math.expr.Expr; +import org.apache.druid.math.expr.ExpressionType; + +public final class NvlLongVectorProcessor extends NvlFunctionVectorProcessor +{ + private final long[] output; + private final boolean[] outputNulls; + + public NvlLongVectorProcessor( + ExprVectorProcessor inputProcessor, + ExprVectorProcessor elseProcessor + ) + { + super(ExpressionType.LONG, inputProcessor, elseProcessor); + this.output = new long[inputProcessor.maxVectorSize()]; + this.outputNulls = new boolean[inputProcessor.maxVectorSize()]; + } + + @Override + public ExprEvalVector evalVector(Expr.VectorInputBinding bindings) + { + inputBindingFilterer.setBindings(bindings); + final ExprEvalVector inputVector = inputProcessor.evalVector(bindings); + + if (inputVector.getNullVector() == null) { + // this one has no nulls, just spit it out + return inputVector; + } + + + final long[] inputValues = inputVector.getLongVector(); + final boolean[] inputNulls = inputVector.getNullVector(); + final int[] selection = inputBindingFilterer.getVectorMatch().getSelection(); + int nulls = 0; + for (int i = 0; i < bindings.getCurrentVectorSize(); i++) { + if (inputNulls[i]) { + selection[nulls++] = i; + } else { + outputNulls[i] = false; + output[i] = inputValues[i]; + } + } + inputBindingFilterer.getVectorMatch().setSelectionSize(nulls); + if (nulls == 0) { + return new ExprEvalLongVector(output, outputNulls); + } + + if (nulls == bindings.getCurrentVectorSize()) { + // all nulls, just return the other + return elseProcessor.evalVector(bindings); + } + + final ExprEvalVector elseVector = elseProcessor.evalVector(inputBindingFilterer); + final long[] elseValues = elseVector.getLongVector(); + final boolean[] elseNulls = elseVector.getNullVector(); + for (int i = 0; i < nulls; i++) { + final int outIndex = selection[i]; + if (elseNulls != null && elseNulls[i]) { + outputNulls[outIndex] = true; + } else { + output[outIndex] = elseValues[i]; + outputNulls[outIndex] = false; + } + } + return new ExprEvalLongVector(output, outputNulls); + } +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/NvlVectorObjectProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/NvlVectorObjectProcessor.java new file mode 100644 index 000000000000..061a66b08273 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/NvlVectorObjectProcessor.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.math.expr.Expr; +import org.apache.druid.math.expr.ExpressionType; + +public final class NvlVectorObjectProcessor extends NvlFunctionVectorProcessor +{ + private final Object[] output; + + public NvlVectorObjectProcessor( + ExpressionType outputType, + ExprVectorProcessor inputProcessor, + ExprVectorProcessor elseProcessor + ) + { + super(outputType, inputProcessor, elseProcessor); + this.output = new Object[inputProcessor.maxVectorSize()]; + } + + @Override + public ExprEvalVector evalVector(Expr.VectorInputBinding bindings) + { + inputBindingFilterer.setBindings(bindings); + final ExprEvalVector inputVector = inputProcessor.evalVector(bindings); + + Object[] inputValues = inputVector.getObjectVector(); + final int[] selection = inputBindingFilterer.getVectorMatch().getSelection(); + int nulls = 0; + for (int i = 0; i < bindings.getCurrentVectorSize(); i++) { + if (inputValues[i] == null) { + selection[nulls++] = i; + } else { + output[i] = inputValues[i]; + } + } + inputBindingFilterer.getVectorMatch().setSelectionSize(nulls); + final ExprEvalVector elseVector = elseProcessor.evalVector(inputBindingFilterer); + final Object[] elseValues = elseVector.getObjectVector(); + for (int i = 0; i < nulls; i++) { + output[selection[i]] = elseValues[i]; + } + return new ExprEvalObjectVector(output, outputType); + } +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/ObjectOutObjectsInFunctionVectorProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/ObjectBivariateObjectsFunctionVectorProcessor.java similarity index 80% rename from processing/src/main/java/org/apache/druid/math/expr/vector/ObjectOutObjectsInFunctionVectorProcessor.java rename to processing/src/main/java/org/apache/druid/math/expr/vector/ObjectBivariateObjectsFunctionVectorProcessor.java index d40ebe5af05a..61993983d03d 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/ObjectOutObjectsInFunctionVectorProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/ObjectBivariateObjectsFunctionVectorProcessor.java @@ -23,22 +23,21 @@ import javax.annotation.Nullable; -public abstract class ObjectOutObjectsInFunctionVectorProcessor - extends BivariateFunctionVectorObjectProcessor +public abstract class ObjectBivariateObjectsFunctionVectorProcessor + extends BivariateObjectsFunctionVectorProcessor { final ExpressionType expressionType; - protected ObjectOutObjectsInFunctionVectorProcessor( + protected ObjectBivariateObjectsFunctionVectorProcessor( ExprVectorProcessor left, ExprVectorProcessor right, - int maxVectorSize, ExpressionType expressionType ) { super( - CastToTypeVectorProcessor.cast(left, expressionType, maxVectorSize), - CastToTypeVectorProcessor.cast(right, expressionType, maxVectorSize), - new Object[maxVectorSize] + CastToTypeVectorProcessor.cast(left, expressionType), + CastToTypeVectorProcessor.cast(right, expressionType), + new Object[left.maxVectorSize()] ); this.expressionType = expressionType; } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/ObjectOutMultiObjectInVectorProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/ObjectMultivariateObjectsFunctionVectorProcessor.java similarity index 83% rename from processing/src/main/java/org/apache/druid/math/expr/vector/ObjectOutMultiObjectInVectorProcessor.java rename to processing/src/main/java/org/apache/druid/math/expr/vector/ObjectMultivariateObjectsFunctionVectorProcessor.java index 79e99b277c0c..fb223a5fb457 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/ObjectOutMultiObjectInVectorProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/ObjectMultivariateObjectsFunctionVectorProcessor.java @@ -23,23 +23,22 @@ import org.apache.druid.math.expr.ExpressionType; /** - * many strings enter, one string leaves... + * many objects enter, one object leaves... */ -public abstract class ObjectOutMultiObjectInVectorProcessor implements ExprVectorProcessor +public abstract class ObjectMultivariateObjectsFunctionVectorProcessor implements ExprVectorProcessor { final ExprVectorProcessor[] inputs; final Object[] outValues; final ExpressionType expressionType; - protected ObjectOutMultiObjectInVectorProcessor( + protected ObjectMultivariateObjectsFunctionVectorProcessor( ExprVectorProcessor[] inputs, - int maxVectorSize, ExpressionType objectType ) { this.inputs = inputs; - this.outValues = new Object[maxVectorSize]; + this.outValues = new Object[inputs[0].maxVectorSize()]; this.expressionType = objectType; } @@ -65,4 +64,10 @@ public ExprEvalVector evalVector(Expr.VectorInputBinding bindings) } abstract void processIndex(Object[][] in, int i); + + @Override + public int maxVectorSize() + { + return inputs[0].maxVectorSize(); + } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/SimpleVectorComparisonLegacyProcessorFactory.java b/processing/src/main/java/org/apache/druid/math/expr/vector/SimpleVectorComparisonLegacyProcessorFactory.java new file mode 100644 index 000000000000..1097c5b48abd --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/SimpleVectorComparisonLegacyProcessorFactory.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.math.expr.Expr; +import org.apache.druid.math.expr.ExprType; +import org.apache.druid.math.expr.ExpressionProcessing; +import org.apache.druid.math.expr.ExpressionType; +import org.apache.druid.math.expr.vector.functional.DoubleBivariateDoubleLongFunction; +import org.apache.druid.math.expr.vector.functional.DoubleBivariateDoublesFunction; +import org.apache.druid.math.expr.vector.functional.DoubleBivariateLongDoubleFunction; +import org.apache.druid.math.expr.vector.functional.LongBivariateLongsFunction; +import org.apache.druid.math.expr.vector.functional.LongBivariateObjectsFunction; +import org.apache.druid.segment.column.Types; + +public class SimpleVectorComparisonLegacyProcessorFactory extends SimpleVectorMathBivariateProcessorFactory +{ + private final LongBivariateObjectsFunction objectsFunction; + + protected SimpleVectorComparisonLegacyProcessorFactory( + LongBivariateObjectsFunction objectsFunction, + LongBivariateLongsFunction longsFunction, + DoubleBivariateLongDoubleFunction longDoubleFunction, + DoubleBivariateDoubleLongFunction doubleLongFunction, + DoubleBivariateDoublesFunction doublesFunction + ) + { + super(longsFunction, longDoubleFunction, doubleLongFunction, doublesFunction); + this.objectsFunction = objectsFunction; + } + + @Override + public ExprVectorProcessor asProcessor(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) + { + assert !ExpressionProcessing.useStrictBooleans(); + final ExpressionType leftType = left.getOutputType(inspector); + final ExpressionType rightType = right.getOutputType(inspector); + ExprVectorProcessor processor = null; + if (Types.is(leftType, ExprType.STRING)) { + if (Types.isNullOr(rightType, ExprType.STRING)) { + processor = objectsProcessor(inspector, left, right, ExpressionType.STRING); + } else { + processor = doublesProcessor(inspector, left, right); + } + } else if (leftType == null) { + if (Types.isNullOr(rightType, ExprType.STRING)) { + processor = objectsProcessor(inspector, left, right, ExpressionType.STRING); + } + } else if (leftType.is(ExprType.DOUBLE) || Types.is(rightType, ExprType.DOUBLE)) { + processor = doublesProcessor(inspector, left, right); + } + if (processor != null) { + return (ExprVectorProcessor) processor; + } + return super.asProcessor(inspector, left, right); + } + + private ExprVectorProcessor objectsProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right, + ExpressionType inputType + ) + { + return new LongBivariateObjectsFunctionVectorProcessor( + left.asVectorProcessor(inspector), + right.asVectorProcessor(inspector), + inputType, + objectsFunction + ); + } +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/SimpleVectorComparisonProcessorFactory.java b/processing/src/main/java/org/apache/druid/math/expr/vector/SimpleVectorComparisonProcessorFactory.java new file mode 100644 index 000000000000..d709d74b0630 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/SimpleVectorComparisonProcessorFactory.java @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.math.expr.Evals; +import org.apache.druid.math.expr.Expr; +import org.apache.druid.math.expr.ExpressionType; +import org.apache.druid.math.expr.ExpressionTypeConversion; +import org.apache.druid.math.expr.vector.functional.ComparatorFunction; +import org.apache.druid.math.expr.vector.functional.LongBivariateDoubleLongFunction; +import org.apache.druid.math.expr.vector.functional.LongBivariateDoublesFunction; +import org.apache.druid.math.expr.vector.functional.LongBivariateLongDoubleFunction; +import org.apache.druid.math.expr.vector.functional.LongBivariateLongsFunction; +import org.apache.druid.math.expr.vector.functional.LongBivariateObjectsFunction; +import org.apache.druid.segment.column.NullableTypeStrategy; +import org.apache.druid.segment.column.Types; + +import javax.annotation.Nullable; + +public class SimpleVectorComparisonProcessorFactory extends SimpleVectorMathBivariateLongProcessorFactory +{ + private final ComparatorFunction comparatorFunction; + + public SimpleVectorComparisonProcessorFactory( + ComparatorFunction comparatorFunction, + LongBivariateLongsFunction longsFunction, + LongBivariateLongDoubleFunction longDoubleFunction, + LongBivariateDoubleLongFunction doubleLongFunction, + LongBivariateDoublesFunction doublesFunction + ) + { + super(longsFunction, longDoubleFunction, doubleLongFunction, doublesFunction); + this.comparatorFunction = comparatorFunction; + } + + @Override + public ExprVectorProcessor asProcessor(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) + { + final ExpressionType leftType = left.getOutputType(inspector); + final ExpressionType rightType = right.getOutputType(inspector); + if (Types.isNumeric(leftType) || Types.isNumeric(rightType)) { + return super.asProcessor(inspector, left, right); + } + ExprVectorProcessor processor = null; + final ExpressionType commonType = ExpressionTypeConversion.leastRestrictiveType(leftType, rightType); + if (commonType != null) { + processor = objectsProcessor(inspector, left, right, commonType); + } + + if (processor != null) { + return (ExprVectorProcessor) processor; + } + return super.asProcessor(inspector, left, right); + } + + private ExprVectorProcessor objectsProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right, + ExpressionType inputType + ) + { + return new LongBivariateObjectsFunctionVectorProcessor( + left.asVectorProcessor(inspector), + right.asVectorProcessor(inspector), + inputType, + new ObjectsComparatorFunction(inputType.getNullableStrategy(), comparatorFunction) + ); + } + + public static final class ObjectsComparatorFunction implements LongBivariateObjectsFunction + { + private final NullableTypeStrategy nullableTypeStrategy; + private final ComparatorFunction comparatorFunction; + + public ObjectsComparatorFunction( + NullableTypeStrategy nullableTypeStrategy, + ComparatorFunction comparatorFunction + ) + { + this.nullableTypeStrategy = nullableTypeStrategy; + this.comparatorFunction = comparatorFunction; + } + + @Nullable + @Override + public Long process(@Nullable Object left, @Nullable Object right) + { + return Evals.asLong(comparatorFunction.compare(nullableTypeStrategy.compare(left, right))); + } + } +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/SimpleVectorMathBivariateDoubleProcessorFactory.java b/processing/src/main/java/org/apache/druid/math/expr/vector/SimpleVectorMathBivariateDoubleProcessorFactory.java new file mode 100644 index 000000000000..bc05e902f34f --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/SimpleVectorMathBivariateDoubleProcessorFactory.java @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.math.expr.Expr; +import org.apache.druid.math.expr.vector.functional.DoubleBivariateDoubleLongFunction; +import org.apache.druid.math.expr.vector.functional.DoubleBivariateDoublesFunction; +import org.apache.druid.math.expr.vector.functional.DoubleBivariateLongDoubleFunction; +import org.apache.druid.math.expr.vector.functional.DoubleBivariateLongsFunction; + +/** + * Make a 2 argument, math processor with the following type rules + * long, long -> double + * long, double -> double + * double, long -> double + * double, double -> double + */ +public class SimpleVectorMathBivariateDoubleProcessorFactory extends VectorMathBivariateDoubleProcessorFactory +{ + private final DoubleBivariateLongsFunction longsFunction; + private final DoubleBivariateLongDoubleFunction longDoubleFunction; + private final DoubleBivariateDoubleLongFunction doubleLongFunction; + private final DoubleBivariateDoublesFunction doublesFunction; + + public SimpleVectorMathBivariateDoubleProcessorFactory( + DoubleBivariateLongsFunction longsFunction, + DoubleBivariateLongDoubleFunction longDoubleFunction, + DoubleBivariateDoubleLongFunction doubleLongFunction, + DoubleBivariateDoublesFunction doublesFunction + ) + { + this.longsFunction = longsFunction; + this.longDoubleFunction = longDoubleFunction; + this.doubleLongFunction = doubleLongFunction; + this.doublesFunction = doublesFunction; + } + + @Override + public final ExprVectorProcessor longsProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ) + { + return new DoubleBivariateLongsFunctionVectorProcessor( + left.asVectorProcessor(inspector), + right.asVectorProcessor(inspector), + longsFunction + ); + } + + @Override + public final ExprVectorProcessor longDoubleProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ) + { + return new DoubleBivariateLongDoubleFunctionVectorProcessor( + left.asVectorProcessor(inspector), + right.asVectorProcessor(inspector), + longDoubleFunction + ); + } + + @Override + public final ExprVectorProcessor doubleLongProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ) + { + return new DoubleBivariateDoubleLongFunctionVectorProcessor( + left.asVectorProcessor(inspector), + right.asVectorProcessor(inspector), + doubleLongFunction + ); + } + + @Override + public final ExprVectorProcessor doublesProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ) + { + return new DoubleBivariateDoublesFunctionVectorProcessor( + left.asVectorProcessor(inspector), + right.asVectorProcessor(inspector), + doublesFunction + ); + } +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/SimpleVectorMathBivariateLongProcessorFactory.java b/processing/src/main/java/org/apache/druid/math/expr/vector/SimpleVectorMathBivariateLongProcessorFactory.java new file mode 100644 index 000000000000..9c01310846b7 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/SimpleVectorMathBivariateLongProcessorFactory.java @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.math.expr.Expr; +import org.apache.druid.math.expr.vector.functional.LongBivariateDoubleLongFunction; +import org.apache.druid.math.expr.vector.functional.LongBivariateDoublesFunction; +import org.apache.druid.math.expr.vector.functional.LongBivariateLongDoubleFunction; +import org.apache.druid.math.expr.vector.functional.LongBivariateLongsFunction; + +/** + * Make a 2 argument, math processor with the following type rules + * long, long -> long + * long, double -> long + * double, long -> long + * double, double -> long + */ +public class SimpleVectorMathBivariateLongProcessorFactory extends VectorMathBivariateLongProcessorFactory +{ + private final LongBivariateLongsFunction longsFunction; + private final LongBivariateLongDoubleFunction longDoubleFunction; + private final LongBivariateDoubleLongFunction doubleLongFunction; + private final LongBivariateDoublesFunction doublesFunction; + + public SimpleVectorMathBivariateLongProcessorFactory( + LongBivariateLongsFunction longsFunction, + LongBivariateLongDoubleFunction longDoubleFunction, + LongBivariateDoubleLongFunction doubleLongFunction, + LongBivariateDoublesFunction doublesFunction + ) + { + this.longsFunction = longsFunction; + this.longDoubleFunction = longDoubleFunction; + this.doubleLongFunction = doubleLongFunction; + this.doublesFunction = doublesFunction; + } + + @Override + public final ExprVectorProcessor longsProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ) + { + return new LongBivariateLongsFunctionVectorProcessor( + left.asVectorProcessor(inspector), + right.asVectorProcessor(inspector), + longsFunction + ); + } + + @Override + public final ExprVectorProcessor longDoubleProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ) + { + return new LongBivariateLongDoubleFunctionVectorProcessor( + left.asVectorProcessor(inspector), + right.asVectorProcessor(inspector), + longDoubleFunction + ); + } + + @Override + public final ExprVectorProcessor doubleLongProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ) + { + return new LongBivariateDoubleLongFunctionVectorProcessor( + left.asVectorProcessor(inspector), + right.asVectorProcessor(inspector), + doubleLongFunction + ); + } + + @Override + public final ExprVectorProcessor doublesProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ) + { + return new LongBivariateDoublesFunctionVectorProcessor( + left.asVectorProcessor(inspector), + right.asVectorProcessor(inspector), + doublesFunction + ); + } +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/SimpleVectorMathBivariateProcessorFactory.java b/processing/src/main/java/org/apache/druid/math/expr/vector/SimpleVectorMathBivariateProcessorFactory.java new file mode 100644 index 000000000000..230b2e44f350 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/SimpleVectorMathBivariateProcessorFactory.java @@ -0,0 +1,106 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.math.expr.Expr; +import org.apache.druid.math.expr.vector.functional.DoubleBivariateDoubleLongFunction; +import org.apache.druid.math.expr.vector.functional.DoubleBivariateDoublesFunction; +import org.apache.druid.math.expr.vector.functional.DoubleBivariateLongDoubleFunction; +import org.apache.druid.math.expr.vector.functional.LongBivariateLongsFunction; + +/** + * Make a 2 argument, math processor with the following type rules + * long, long -> long + * long, double -> double + * double, long -> double + * double, double -> double + */ +public class SimpleVectorMathBivariateProcessorFactory extends VectorMathBivariateProcessorFactory +{ + private final LongBivariateLongsFunction longsFunction; + private final DoubleBivariateLongDoubleFunction longDoubleFunction; + private final DoubleBivariateDoubleLongFunction doubleLongFunction; + private final DoubleBivariateDoublesFunction doublesFunction; + + protected SimpleVectorMathBivariateProcessorFactory( + LongBivariateLongsFunction longsFunction, + DoubleBivariateLongDoubleFunction longDoubleFunction, + DoubleBivariateDoubleLongFunction doubleLongFunction, + DoubleBivariateDoublesFunction doublesFunction + ) + { + this.longsFunction = longsFunction; + this.longDoubleFunction = longDoubleFunction; + this.doubleLongFunction = doubleLongFunction; + this.doublesFunction = doublesFunction; + } + + @Override + public final ExprVectorProcessor longsProcessor(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) + { + return new LongBivariateLongsFunctionVectorProcessor( + left.asVectorProcessor(inspector), + right.asVectorProcessor(inspector), + longsFunction + ); + } + + @Override + public final ExprVectorProcessor longDoubleProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ) + { + return new DoubleBivariateLongDoubleFunctionVectorProcessor( + left.asVectorProcessor(inspector), + right.asVectorProcessor(inspector), + longDoubleFunction + ); + } + + @Override + public final ExprVectorProcessor doubleLongProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ) + { + return new DoubleBivariateDoubleLongFunctionVectorProcessor( + left.asVectorProcessor(inspector), + right.asVectorProcessor(inspector), + doubleLongFunction + ); + } + + @Override + public final ExprVectorProcessor doublesProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ) + { + return new DoubleBivariateDoublesFunctionVectorProcessor( + left.asVectorProcessor(inspector), + right.asVectorProcessor(inspector), + doublesFunction + ); + } +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/SimpleVectorMathUnivariateDoubleProcessorFactory.java b/processing/src/main/java/org/apache/druid/math/expr/vector/SimpleVectorMathUnivariateDoubleProcessorFactory.java new file mode 100644 index 000000000000..593170dde3ea --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/SimpleVectorMathUnivariateDoubleProcessorFactory.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.math.expr.Expr; +import org.apache.druid.math.expr.vector.functional.DoubleUnivariateDoubleFunction; +import org.apache.druid.math.expr.vector.functional.DoubleUnivariateLongFunction; + +/** + * Make a 1 argument math processor with the following type rules + * long -> double + * double -> double + * using simple scalar functions {@link DoubleUnivariateLongFunction} and {@link DoubleUnivariateDoubleFunction} + */ +public class SimpleVectorMathUnivariateDoubleProcessorFactory extends VectorMathUnivariateDoubleProcessorFactory +{ + private final DoubleUnivariateLongFunction longFunction; + private final DoubleUnivariateDoubleFunction doubleFunction; + + public SimpleVectorMathUnivariateDoubleProcessorFactory( + DoubleUnivariateLongFunction longFunction, + DoubleUnivariateDoubleFunction doubleFunction + ) + { + this.longFunction = longFunction; + this.doubleFunction = doubleFunction; + } + + @Override + public final ExprVectorProcessor longProcessor(Expr.VectorInputBindingInspector inspector, Expr arg) + { + return new DoubleUnivariateLongFunctionVectorProcessor( + arg.asVectorProcessor(inspector), + longFunction + ); + } + + @Override + public final ExprVectorProcessor doubleProcessor(Expr.VectorInputBindingInspector inspector, Expr arg) + { + return new DoubleUnivariateDoubleFunctionVectorProcessor( + arg.asVectorProcessor(inspector), + doubleFunction + ); + } +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/SimpleVectorMathUnivariateLongProcessorFactory.java b/processing/src/main/java/org/apache/druid/math/expr/vector/SimpleVectorMathUnivariateLongProcessorFactory.java new file mode 100644 index 000000000000..3ab2cce5bc94 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/SimpleVectorMathUnivariateLongProcessorFactory.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.math.expr.Expr; +import org.apache.druid.math.expr.vector.functional.LongUnivariateDoubleFunction; +import org.apache.druid.math.expr.vector.functional.LongUnivariateLongFunction; + +/** + * Make a 1 argument math processor with the following type rules + * long -> long + * double -> long + * using simple scalar functions {@link LongUnivariateLongFunction} and {@link LongUnivariateDoubleFunction} + */ +public class SimpleVectorMathUnivariateLongProcessorFactory extends VectorMathUnivariateLongProcessorFactory +{ + private final LongUnivariateLongFunction longFunction; + private final LongUnivariateDoubleFunction doubleFunction; + + public SimpleVectorMathUnivariateLongProcessorFactory( + LongUnivariateLongFunction longFunction, + LongUnivariateDoubleFunction doubleFunction + ) + { + this.longFunction = longFunction; + this.doubleFunction = doubleFunction; + } + + @Override + public final ExprVectorProcessor longProcessor(Expr.VectorInputBindingInspector inspector, Expr arg) + { + return new LongUnivariateLongFunctionVectorProcessor( + arg.asVectorProcessor(inspector), + longFunction + ); + } + + @Override + public final ExprVectorProcessor doubleProcessor(Expr.VectorInputBindingInspector inspector, Expr arg) + { + return new LongUnivariateDoubleFunctionVectorProcessor( + arg.asVectorProcessor(inspector), + doubleFunction + ); + } +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/SimpleVectorMathUnivariateProcessorFactory.java b/processing/src/main/java/org/apache/druid/math/expr/vector/SimpleVectorMathUnivariateProcessorFactory.java new file mode 100644 index 000000000000..8c1c041b123f --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/SimpleVectorMathUnivariateProcessorFactory.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.math.expr.Expr; +import org.apache.druid.math.expr.vector.functional.DoubleUnivariateDoubleFunction; +import org.apache.druid.math.expr.vector.functional.LongUnivariateLongFunction; + +/** + * Make a 1 argument math processor with the following type rules + * long -> long + * double -> double + * using simple scalar functions {@link LongUnivariateLongFunction} and {@link DoubleUnivariateDoubleFunction} + */ +public class SimpleVectorMathUnivariateProcessorFactory extends VectorMathUnivariateProcessorFactory +{ + private final LongUnivariateLongFunction longFunction; + private final DoubleUnivariateDoubleFunction doubleFunction; + + public SimpleVectorMathUnivariateProcessorFactory( + LongUnivariateLongFunction longFunction, + DoubleUnivariateDoubleFunction doubleFunction + ) + { + this.longFunction = longFunction; + this.doubleFunction = doubleFunction; + } + + @Override + public final ExprVectorProcessor longProcessor(Expr.VectorInputBindingInspector inspector, Expr arg) + { + return new LongUnivariateLongFunctionVectorProcessor( + arg.asVectorProcessor(inspector), + longFunction + ); + } + + @Override + public final ExprVectorProcessor doubleProcessor(Expr.VectorInputBindingInspector inspector, Expr arg) + { + return new DoubleUnivariateDoubleFunctionVectorProcessor( + arg.asVectorProcessor(inspector), + doubleFunction + ); + } +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/SymmetricalBivariateFunctionVectorProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/SymmetricalBivariateFunctionVectorProcessor.java index 6e2af319a233..171610c9f914 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/SymmetricalBivariateFunctionVectorProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/SymmetricalBivariateFunctionVectorProcessor.java @@ -29,6 +29,10 @@ public SymmetricalBivariateFunctionVectorProcessor( ExprVectorProcessor right ) { - super(outputType, left, right); + super( + outputType, + CastToTypeVectorProcessor.cast(left, outputType), + CastToTypeVectorProcessor.cast(right, outputType) + ); } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/UnivariateFunctionVectorObjectProcessor.java b/processing/src/main/java/org/apache/druid/math/expr/vector/UnivariateObjectFunctionVectorProcessor.java similarity index 91% rename from processing/src/main/java/org/apache/druid/math/expr/vector/UnivariateFunctionVectorObjectProcessor.java rename to processing/src/main/java/org/apache/druid/math/expr/vector/UnivariateObjectFunctionVectorProcessor.java index da9be989cffd..a8cbccb9f0fb 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/UnivariateFunctionVectorObjectProcessor.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/UnivariateObjectFunctionVectorProcessor.java @@ -25,20 +25,19 @@ * common machinery for processing single input operators and functions, which are backed by an object value instead of * a primitive value (so do not need to use the null vector, and instead can check the value vector itself for nulls) */ -public abstract class UnivariateFunctionVectorObjectProcessor implements ExprVectorProcessor +public abstract class UnivariateObjectFunctionVectorProcessor implements ExprVectorProcessor { final ExprVectorProcessor processor; final boolean[] outNulls; final TOutput outValues; - public UnivariateFunctionVectorObjectProcessor( + public UnivariateObjectFunctionVectorProcessor( ExprVectorProcessor processor, - int maxVectorSize, TOutput outValues ) { this.processor = processor; - this.outNulls = new boolean[maxVectorSize]; + this.outNulls = new boolean[processor.maxVectorSize()]; this.outValues = outValues; } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/UnivariateVectorProcessorFactory.java b/processing/src/main/java/org/apache/druid/math/expr/vector/UnivariateVectorProcessorFactory.java new file mode 100644 index 000000000000..efc89caec828 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/UnivariateVectorProcessorFactory.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.math.expr.Expr; + +interface UnivariateVectorProcessorFactory +{ + ExprVectorProcessor asProcessor(Expr.VectorInputBindingInspector inspector, Expr arg); +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/VectorComparisonProcessors.java b/processing/src/main/java/org/apache/druid/math/expr/vector/VectorComparisonProcessors.java index a132c0ee6725..a102fd75b218 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/VectorComparisonProcessors.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/VectorComparisonProcessors.java @@ -21,988 +21,258 @@ import org.apache.druid.java.util.common.guava.Comparators; import org.apache.druid.math.expr.Evals; -import org.apache.druid.math.expr.Expr; -import org.apache.druid.math.expr.ExprType; import org.apache.druid.math.expr.ExpressionProcessing; -import org.apache.druid.math.expr.ExpressionType; -import org.apache.druid.segment.column.Types; -import javax.annotation.Nullable; import java.util.Objects; -import java.util.function.Supplier; public class VectorComparisonProcessors { - @Deprecated - public static ExprVectorProcessor makeComparisonProcessor( - Expr.VectorInputBindingInspector inspector, - Expr left, - Expr right, - Supplier longOutStringsInFunctionVectorProcessor, - Supplier longOutLongsInProcessor, - Supplier doubleOutLongDoubleInProcessor, - Supplier doubleOutDoubleLongInProcessor, - Supplier doubleOutDoublesInProcessor - ) + public static BivariateFunctionVectorProcessorFactory equals() { - assert !ExpressionProcessing.useStrictBooleans(); - final ExpressionType leftType = left.getOutputType(inspector); - final ExpressionType rightType = right.getOutputType(inspector); - ExprVectorProcessor processor = null; - if (Types.is(leftType, ExprType.STRING)) { - if (Types.isNullOr(rightType, ExprType.STRING)) { - processor = longOutStringsInFunctionVectorProcessor.get(); - } else { - processor = doubleOutDoublesInProcessor.get(); - } - } else if (leftType == null) { - if (Types.isNullOr(rightType, ExprType.STRING)) { - processor = longOutStringsInFunctionVectorProcessor.get(); - } - } else if (leftType.is(ExprType.DOUBLE) || Types.is(rightType, ExprType.DOUBLE)) { - processor = doubleOutDoublesInProcessor.get(); + if (!ExpressionProcessing.useStrictBooleans()) { + return LegacyEqual.INSTANCE; } - if (processor != null) { - return (ExprVectorProcessor) processor; + return Equal.INSTANCE; + } + + public static BivariateFunctionVectorProcessorFactory notEquals() + { + if (!ExpressionProcessing.useStrictBooleans()) { + return LegacyNotEqual.INSTANCE; } - // fall through to normal math processor logic - return VectorMathProcessors.makeMathProcessor( - inspector, - left, - right, - longOutLongsInProcessor, - doubleOutLongDoubleInProcessor, - doubleOutDoubleLongInProcessor, - doubleOutDoublesInProcessor - ); + return NotEqual.INSTANCE; } - public static ExprVectorProcessor makeBooleanProcessor( - Expr.VectorInputBindingInspector inspector, - Expr left, - Expr right, - Supplier longOutStringsInFunctionVectorProcessor, - Supplier longOutLongsInProcessor, - Supplier longOutLongDoubleInProcessor, - Supplier longOutDoubleLongInProcessor, - Supplier longOutDoublesInProcessor - ) + public static BivariateFunctionVectorProcessorFactory greaterThanOrEquals() { - final ExpressionType leftType = left.getOutputType(inspector); - final ExpressionType rightType = right.getOutputType(inspector); - ExprVectorProcessor processor = null; - if (Types.is(leftType, ExprType.STRING)) { - if (Types.isNullOr(rightType, ExprType.STRING)) { - processor = longOutStringsInFunctionVectorProcessor.get(); - } else { - processor = longOutDoublesInProcessor.get(); - } - } else if (Types.is(rightType, ExprType.STRING)) { - if (leftType == null) { - processor = longOutStringsInFunctionVectorProcessor.get(); - } else { - processor = longOutDoublesInProcessor.get(); - } - } else if (leftType == null) { - if (Types.isNullOr(rightType, ExprType.STRING)) { - processor = longOutStringsInFunctionVectorProcessor.get(); - } - } else if (leftType.is(ExprType.DOUBLE) || Types.is(rightType, ExprType.DOUBLE)) { - processor = longOutDoublesInProcessor.get(); + if (!ExpressionProcessing.useStrictBooleans()) { + return LegacyGreaterThanOrEqual.INSTANCE; } - if (processor != null) { - return (ExprVectorProcessor) processor; + return GreaterThanOrEqual.INSTANCE; + } + + public static BivariateFunctionVectorProcessorFactory greaterThan() + { + if (!ExpressionProcessing.useStrictBooleans()) { + return LegacyGreaterThan.INSTANCE; } - // fall through to normal math processor logic - return VectorMathProcessors.makeLongMathProcessor( - inspector, - left, - right, - longOutLongsInProcessor, - longOutLongDoubleInProcessor, - longOutDoubleLongInProcessor, - longOutDoublesInProcessor - ); + return GreaterThan.INSTANCE; } - public static ExprVectorProcessor equal( - Expr.VectorInputBindingInspector inspector, - Expr left, - Expr right - ) + public static BivariateFunctionVectorProcessorFactory lessThanOrEquals() { if (!ExpressionProcessing.useStrictBooleans()) { - return makeComparisonProcessor( - inspector, - left, - right, - () -> new LongOutObjectsInFunctionVectorProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize(), - ExpressionType.STRING - ) - { - @Nullable - @Override - Long processValue(@Nullable Object leftVal, @Nullable Object rightVal) - { - return Evals.asLong(Objects.equals(leftVal, rightVal)); - } - }, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return Evals.asLong(left == right); - } - }, - () -> new DoubleOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, double right) - { - return Evals.asDouble(left == right); - } - }, - () -> new DoubleOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, long right) - { - return Evals.asDouble(left == right); - } - }, - () -> new DoubleOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, double right) - { - return Evals.asDouble(left == right); - } - } - ); + return LegacyLessThanOrEqual.INSTANCE; } - return makeBooleanProcessor( - inspector, - left, - right, - () -> new LongOutObjectsInFunctionVectorProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize(), - ExpressionType.STRING - ) - { - @Nullable - @Override - Long processValue(@Nullable Object leftVal, @Nullable Object rightVal) - { - return Evals.asLong(Objects.equals(leftVal, rightVal)); - } - }, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return Evals.asLong(left == right); - } - }, - () -> new LongOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, double right) - { - return Evals.asLong(left == right); - } - }, - () -> new LongOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double left, long right) - { - return Evals.asLong(left == right); - } - }, - () -> new LongOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double left, double right) - { - return Evals.asLong(left == right); - } - } - ); + return LessThanOrEqual.INSTANCE; } - public static ExprVectorProcessor notEqual( - Expr.VectorInputBindingInspector inspector, - Expr left, - Expr right - ) + public static BivariateFunctionVectorProcessorFactory lessThan() { if (!ExpressionProcessing.useStrictBooleans()) { - return makeComparisonProcessor( - inspector, - left, - right, - () -> new LongOutObjectsInFunctionVectorProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize(), - ExpressionType.STRING - ) - { - @Nullable - @Override - Long processValue(@Nullable Object leftVal, @Nullable Object rightVal) - { - return Evals.asLong(!Objects.equals(leftVal, rightVal)); - } - }, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return Evals.asLong(left != right); - } - }, - () -> new DoubleOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, double right) - { - return Evals.asDouble(left != right); - } - }, - () -> new DoubleOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, long right) - { - return Evals.asDouble(left != right); - } - }, - () -> new DoubleOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, double right) - { - return Evals.asDouble(left != right); - } - } + return LegacyLessThan.INSTANCE; + } + return LessThan.INSTANCE; + } + + public static class Equal extends SimpleVectorComparisonProcessorFactory + { + private static final Equal INSTANCE = new Equal(); + + public Equal() + { + super( + (compareResult) -> compareResult == 0, + (left, right) -> Evals.asLong(left == right), + (left, right) -> Evals.asLong(left == right), + (left, right) -> Evals.asLong(left == right), + (left, right) -> Evals.asLong(left == right) ); } - return makeBooleanProcessor( - inspector, - left, - right, - () -> new LongOutObjectsInFunctionVectorProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize(), - ExpressionType.STRING - ) - { - @Nullable - @Override - Long processValue(@Nullable Object leftVal, @Nullable Object rightVal) - { - return Evals.asLong(!Objects.equals(leftVal, rightVal)); - } - }, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return Evals.asLong(left != right); - } - }, - () -> new LongOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, double right) - { - return Evals.asLong(left != right); - } - }, - () -> new LongOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double left, long right) - { - return Evals.asLong(left != right); - } - }, - () -> new LongOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double left, double right) - { - return Evals.asLong(left != right); - } - } - ); } - public static ExprVectorProcessor greaterThanOrEqual( - Expr.VectorInputBindingInspector inspector, - Expr left, - Expr right - ) + public static class NotEqual extends SimpleVectorComparisonProcessorFactory { - if (!ExpressionProcessing.useStrictBooleans()) { - return makeComparisonProcessor( - inspector, - left, - right, - () -> new LongOutObjectsInFunctionVectorProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize(), - ExpressionType.STRING - ) - { - @Nullable - @Override - Long processValue(@Nullable Object leftVal, @Nullable Object rightVal) - { - return Evals.asLong( - Comparators.naturalNullsFirst().compare((String) leftVal, (String) rightVal) >= 0 - ); - } - }, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return Evals.asLong(left >= right); - } - }, - () -> new DoubleOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, double right) - { - return Evals.asDouble(Double.compare(left, right) >= 0); - } - }, - () -> new DoubleOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, long right) - { - return Evals.asDouble(Double.compare(left, right) >= 0); - } - }, - () -> new DoubleOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, double right) - { - return Evals.asDouble(Double.compare(left, right) >= 0); - } - } + private static final NotEqual INSTANCE = new NotEqual(); + + public NotEqual() + { + super( + compareResult -> compareResult != 0, + (left, right) -> Evals.asLong(left != right), + (left, right) -> Evals.asLong(left != right), + (left, right) -> Evals.asLong(left != right), + (left, right) -> Evals.asLong(left != right) ); } - return makeBooleanProcessor( - inspector, - left, - right, - () -> new LongOutObjectsInFunctionVectorProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize(), - ExpressionType.STRING - ) - { - @Nullable - @Override - Long processValue(@Nullable Object leftVal, @Nullable Object rightVal) - { - return Evals.asLong( - Comparators.naturalNullsFirst().compare((String) leftVal, (String) rightVal) >= 0 - ); - } - }, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return Evals.asLong(left >= right); - } - }, - () -> new LongOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, double right) - { - return Evals.asLong(Double.compare(left, right) >= 0); - } - }, - () -> new LongOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double left, long right) - { - return Evals.asLong(Double.compare(left, right) >= 0); - } - }, - () -> new LongOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double left, double right) - { - return Evals.asLong(Double.compare(left, right) >= 0); - } - } - ); } - public static ExprVectorProcessor greaterThan( - Expr.VectorInputBindingInspector inspector, - Expr left, - Expr right - ) + public static class GreaterThanOrEqual extends SimpleVectorComparisonProcessorFactory { - if (!ExpressionProcessing.useStrictBooleans()) { - return makeComparisonProcessor( - inspector, - left, - right, - () -> new LongOutObjectsInFunctionVectorProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize(), - ExpressionType.STRING - ) - { - @Nullable - @Override - Long processValue(@Nullable Object leftVal, @Nullable Object rightVal) - { - return Evals.asLong( - Comparators.naturalNullsFirst().compare((String) leftVal, (String) rightVal) > 0 - ); - } - }, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return Evals.asLong(left > right); - } - }, - () -> new DoubleOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, double right) - { - return Evals.asDouble(Double.compare(left, right) > 0); - } - }, - () -> new DoubleOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, long right) - { - return Evals.asDouble(Double.compare(left, right) > 0); - } - }, - () -> new DoubleOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, double right) - { - return Evals.asDouble(Double.compare(left, right) > 0); - } - } + private static final GreaterThanOrEqual INSTANCE = new GreaterThanOrEqual(); + + public GreaterThanOrEqual() + { + super( + compareResult -> compareResult >= 0, + (left, right) -> Evals.asLong(left >= right), + (left, right) -> Evals.asLong(left >= right), + (left, right) -> Evals.asLong(left >= right), + (left, right) -> Evals.asLong(left >= right) ); } - return makeBooleanProcessor( - inspector, - left, - right, - () -> new LongOutObjectsInFunctionVectorProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize(), - ExpressionType.STRING - ) - { - @Nullable - @Override - Long processValue(@Nullable Object leftVal, @Nullable Object rightVal) - { - return Evals.asLong( - Comparators.naturalNullsFirst().compare((String) leftVal, (String) rightVal) > 0 - ); - } - }, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return Evals.asLong(left > right); - } - }, - () -> new LongOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, double right) - { - return Evals.asLong(Double.compare(left, right) > 0); - } - }, - () -> new LongOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double left, long right) - { - return Evals.asLong(Double.compare(left, right) > 0); - } - }, - () -> new LongOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double left, double right) - { - return Evals.asLong(Double.compare(left, right) > 0); - } - } - ); } - public static ExprVectorProcessor lessThanOrEqual( - Expr.VectorInputBindingInspector inspector, - Expr left, - Expr right - ) + public static class GreaterThan extends SimpleVectorComparisonProcessorFactory { - if (!ExpressionProcessing.useStrictBooleans()) { - return makeComparisonProcessor( - inspector, - left, - right, - () -> new LongOutObjectsInFunctionVectorProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize(), - ExpressionType.STRING - ) - { - @Nullable - @Override - Long processValue(@Nullable Object leftVal, @Nullable Object rightVal) - { - return Evals.asLong( - Comparators.naturalNullsFirst().compare((String) leftVal, (String) rightVal) <= 0 - ); - } - }, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return Evals.asLong(left <= right); - } - }, - () -> new DoubleOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, double right) - { - return Evals.asDouble(Double.compare(left, right) <= 0); - } - }, - () -> new DoubleOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, long right) - { - return Evals.asDouble(Double.compare(left, right) <= 0); - } - }, - () -> new DoubleOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, double right) - { - return Evals.asDouble(Double.compare(left, right) <= 0); - } - } + private static final GreaterThan INSTANCE = new GreaterThan(); + + public GreaterThan() + { + super( + compareResult -> compareResult > 0, + (left, right) -> Evals.asLong(left > right), + (left, right) -> Evals.asLong(left > right), + (left, right) -> Evals.asLong(left > right), + (left, right) -> Evals.asLong(left > right) ); } - return makeBooleanProcessor( - inspector, - left, - right, - () -> new LongOutObjectsInFunctionVectorProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize(), - ExpressionType.STRING - ) - { - @Nullable - @Override - Long processValue(@Nullable Object leftVal, @Nullable Object rightVal) - { - return Evals.asLong( - Comparators.naturalNullsFirst().compare((String) leftVal, (String) rightVal) <= 0 - ); - } - }, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return Evals.asLong(left <= right); - } - }, - () -> new LongOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, double right) - { - return Evals.asLong(Double.compare(left, right) <= 0); - } - }, - () -> new LongOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double left, long right) - { - return Evals.asLong(Double.compare(left, right) <= 0); - } - }, - () -> new LongOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double left, double right) - { - return Evals.asLong(Double.compare(left, right) <= 0); - } - } - ); } - public static ExprVectorProcessor lessThan( - Expr.VectorInputBindingInspector inspector, - Expr left, - Expr right - ) + public static class LessThanOrEqual extends SimpleVectorComparisonProcessorFactory { - if (!ExpressionProcessing.useStrictBooleans()) { - return makeComparisonProcessor( - inspector, - left, - right, - () -> new LongOutObjectsInFunctionVectorProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize(), - ExpressionType.STRING - ) - { - @Nullable - @Override - Long processValue(@Nullable Object leftVal, @Nullable Object rightVal) - { - return Evals.asLong( - Comparators.naturalNullsFirst().compare((String) leftVal, (String) rightVal) < 0 - ); - } - }, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return Evals.asLong(left < right); - } - }, - () -> new DoubleOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, double right) - { - return Evals.asDouble(Double.compare(left, right) < 0); - } - }, - () -> new DoubleOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, long right) - { - return Evals.asDouble(Double.compare(left, right) < 0); - } - }, - () -> new DoubleOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, double right) - { - return Evals.asDouble(Double.compare(left, right) < 0); - } - } + private static final LessThanOrEqual INSTANCE = new LessThanOrEqual(); + + public LessThanOrEqual() + { + super( + compareResult -> compareResult <= 0, + (left, right) -> Evals.asLong(left <= right), + (left, right) -> Evals.asLong(left <= right), + (left, right) -> Evals.asLong(left <= right), + (left, right) -> Evals.asLong(left <= right) + ); + } + } + + public static class LessThan extends SimpleVectorComparisonProcessorFactory + { + private static final LessThan INSTANCE = new LessThan(); + + public LessThan() + { + super( + compareResult -> compareResult < 0, + (left, right) -> Evals.asLong(left < right), + (left, right) -> Evals.asLong(left < right), + (left, right) -> Evals.asLong(left < right), + (left, right) -> Evals.asLong(left < right) + ); + } + } + + public static class LegacyEqual extends SimpleVectorComparisonLegacyProcessorFactory + { + private static final LegacyEqual INSTANCE = new LegacyEqual(); + + public LegacyEqual() + { + super( + (left, right) -> Evals.asLong(Objects.equals(left, right)), + (left, right) -> Evals.asLong(left == right), + (left, right) -> Evals.asDouble(left == right), + (left, right) -> Evals.asDouble(left == right), + (left, right) -> Evals.asDouble(left == right) + ); + } + } + + public static class LegacyNotEqual extends SimpleVectorComparisonLegacyProcessorFactory + { + private static final LegacyNotEqual INSTANCE = new LegacyNotEqual(); + + public LegacyNotEqual() + { + super( + (left, right) -> Evals.asLong(!Objects.equals(left, right)), + (left, right) -> Evals.asLong(left != right), + (left, right) -> Evals.asDouble(left != right), + (left, right) -> Evals.asDouble(left != right), + (left, right) -> Evals.asDouble(left != right) + ); + } + } + + public static class LegacyGreaterThanOrEqual extends SimpleVectorComparisonLegacyProcessorFactory + { + private static final LegacyGreaterThanOrEqual INSTANCE = new LegacyGreaterThanOrEqual(); + + public LegacyGreaterThanOrEqual() + { + super( + (left, right) -> Evals.asLong( + Comparators.naturalNullsFirst().compare((String) left, (String) right) >= 0 + ), + (left, right) -> Evals.asLong(left >= right), + (left, right) -> Evals.asDouble(left >= right), + (left, right) -> Evals.asDouble(left >= right), + (left, right) -> Evals.asDouble(left >= right) + ); + } + } + + public static class LegacyGreaterThan extends SimpleVectorComparisonLegacyProcessorFactory + { + private static final LegacyGreaterThan INSTANCE = new LegacyGreaterThan(); + + public LegacyGreaterThan() + { + super( + (left, right) -> Evals.asLong( + Comparators.naturalNullsFirst().compare((String) left, (String) right) > 0 + ), + (left, right) -> Evals.asLong(left > right), + (left, right) -> Evals.asDouble(left > right), + (left, right) -> Evals.asDouble(left > right), + (left, right) -> Evals.asDouble(left > right) + ); + } + } + + public static class LegacyLessThanOrEqual extends SimpleVectorComparisonLegacyProcessorFactory + { + private static final LegacyLessThanOrEqual INSTANCE = new LegacyLessThanOrEqual(); + + public LegacyLessThanOrEqual() + { + super( + (left, right) -> Evals.asLong( + Comparators.naturalNullsFirst().compare((String) left, (String) right) <= 0 + ), + (left, right) -> Evals.asLong(left <= right), + (left, right) -> Evals.asDouble(left <= right), + (left, right) -> Evals.asDouble(left <= right), + (left, right) -> Evals.asDouble(left <= right) + ); + } + } + + public static class LegacyLessThan extends SimpleVectorComparisonLegacyProcessorFactory + { + private static final LegacyLessThan INSTANCE = new LegacyLessThan(); + + public LegacyLessThan() + { + super( + (left, right) -> Evals.asLong( + Comparators.naturalNullsFirst().compare((String) left, (String) right) < 0 + ), + (left, right) -> Evals.asLong(left < right), + (left, right) -> Evals.asDouble(left < right), + (left, right) -> Evals.asDouble(left < right), + (left, right) -> Evals.asDouble(left < right) ); } - return makeBooleanProcessor( - inspector, - left, - right, - () -> new LongOutObjectsInFunctionVectorProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize(), - ExpressionType.STRING - ) - { - @Nullable - @Override - Long processValue(@Nullable Object leftVal, @Nullable Object rightVal) - { - return Evals.asLong( - Comparators.naturalNullsFirst().compare((String) leftVal, (String) rightVal) < 0 - ); - } - }, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return Evals.asLong(left < right); - } - }, - () -> new LongOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, double right) - { - return Evals.asLong(Double.compare(left, right) < 0); - } - }, - () -> new LongOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double left, long right) - { - return Evals.asLong(Double.compare(left, right) < 0); - } - }, - () -> new LongOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double left, double right) - { - return Evals.asLong(Double.compare(left, right) < 0); - } - } - ); } private VectorComparisonProcessors() diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/VectorConditionalProcessors.java b/processing/src/main/java/org/apache/druid/math/expr/vector/VectorConditionalProcessors.java new file mode 100644 index 000000000000..8d462c922281 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/VectorConditionalProcessors.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.math.expr.Expr; +import org.apache.druid.math.expr.ExprType; +import org.apache.druid.math.expr.ExpressionType; +import org.apache.druid.math.expr.ExpressionTypeConversion; + +public class VectorConditionalProcessors +{ + public static ExprVectorProcessor nvl(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) + { + final ExpressionType leftType = left.getOutputType(inspector); + final ExpressionType rightType = right.getOutputType(inspector); + final ExpressionType outputType = ExpressionTypeConversion.leastRestrictiveType(leftType, rightType); + + final ExprVectorProcessor processor; + if (outputType.is(ExprType.LONG)) { + // long is most restrictive so both processors are definitely long typed if output is long + processor = new NvlLongVectorProcessor( + left.asVectorProcessor(inspector), + right.asVectorProcessor(inspector) + ); + } else if (outputType.is(ExprType.DOUBLE)) { + processor = new NvlDoubleVectorProcessor( + CastToTypeVectorProcessor.cast(left.asVectorProcessor(inspector), ExpressionType.DOUBLE), + CastToTypeVectorProcessor.cast(right.asVectorProcessor(inspector), ExpressionType.DOUBLE) + ); + } else { + processor = new NvlVectorObjectProcessor( + outputType, + CastToTypeVectorProcessor.cast(left.asVectorProcessor(inspector), outputType), + CastToTypeVectorProcessor.cast(right.asVectorProcessor(inspector), outputType) + ); + } + return (ExprVectorProcessor) processor; + } +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/VectorMathBivariateDoubleProcessorFactory.java b/processing/src/main/java/org/apache/druid/math/expr/vector/VectorMathBivariateDoubleProcessorFactory.java new file mode 100644 index 000000000000..62115ea982ab --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/VectorMathBivariateDoubleProcessorFactory.java @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.math.expr.Expr; +import org.apache.druid.math.expr.ExprType; +import org.apache.druid.math.expr.ExpressionType; +import org.apache.druid.math.expr.Exprs; +import org.apache.druid.segment.column.Types; + +/** + * Make a 2 argument, math processor with the following type rules + * long, long -> double + * long, double -> double + * double, long -> double + * double, double -> double + */ +public abstract class VectorMathBivariateDoubleProcessorFactory implements BivariateFunctionVectorProcessorFactory +{ + @Override + public ExprVectorProcessor asProcessor(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) + { + final ExpressionType leftType = left.getOutputType(inspector); + final ExpressionType rightType = right.getOutputType(inspector); + ExprVectorProcessor processor = null; + if (Types.is(leftType, ExprType.LONG)) { + if (Types.is(rightType, ExprType.LONG)) { + processor = longsProcessor(inspector, left, right); + } else if (Types.isNullOr(rightType, ExprType.DOUBLE)) { + processor = longDoubleProcessor(inspector, left, right); + } + } else if (Types.is(leftType, ExprType.DOUBLE)) { + if (Types.is(rightType, ExprType.LONG)) { + processor = doubleLongProcessor(inspector, left, right); + } else if (Types.isNullOr(rightType, ExprType.DOUBLE)) { + processor = doublesProcessor(inspector, left, right); + } + } else if (leftType == null) { + if (Types.is(rightType, ExprType.LONG)) { + processor = doubleLongProcessor(inspector, left, right); + } else if (Types.isNullOr(rightType, ExprType.DOUBLE)) { + processor = doublesProcessor(inspector, left, right); + } + } else { + processor = doublesProcessor(inspector, left, right); + } + if (processor == null) { + throw Exprs.cannotVectorize(); + } + return (ExprVectorProcessor) processor; + } + + public abstract ExprVectorProcessor longsProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ); + + public abstract ExprVectorProcessor longDoubleProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ); + + public abstract ExprVectorProcessor doubleLongProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ); + + public abstract ExprVectorProcessor doublesProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ); +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/VectorMathBivariateLongProcessorFactory.java b/processing/src/main/java/org/apache/druid/math/expr/vector/VectorMathBivariateLongProcessorFactory.java new file mode 100644 index 000000000000..075afe0b0d2e --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/VectorMathBivariateLongProcessorFactory.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.math.expr.Expr; +import org.apache.druid.math.expr.ExprType; +import org.apache.druid.math.expr.ExpressionType; +import org.apache.druid.math.expr.Exprs; +import org.apache.druid.segment.column.Types; + +/** + * Make a 2 argument, math processor with the following type rules + * long, long -> long + * long, double -> long + * double, long -> long + * double, double -> long + */ +public abstract class VectorMathBivariateLongProcessorFactory implements BivariateFunctionVectorProcessorFactory +{ + @Override + public ExprVectorProcessor asProcessor(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) + { + final ExpressionType leftType = left.getOutputType(inspector); + final ExpressionType rightType = right.getOutputType(inspector); + ExprVectorProcessor processor = null; + if (Types.is(leftType, ExprType.LONG)) { + if (Types.isNullOr(rightType, ExprType.LONG)) { + processor = longsProcessor(inspector, left, right); + } else if (rightType.is(ExprType.DOUBLE)) { + processor = longDoubleProcessor(inspector, left, right); + } else { + processor = doublesProcessor(inspector, left, right); + } + } else if (Types.is(leftType, ExprType.DOUBLE)) { + if (Types.is(rightType, ExprType.LONG)) { + processor = doubleLongProcessor(inspector, left, right); + } else if (Types.isNullOr(rightType, ExprType.DOUBLE)) { + processor = doublesProcessor(inspector, left, right); + } else { + processor = doublesProcessor(inspector, left, right); + } + } else if (leftType == null) { + if (Types.isNullOr(rightType, ExprType.LONG)) { + processor = longsProcessor(inspector, left, right); + } else if (Types.is(rightType, ExprType.DOUBLE)) { + processor = doublesProcessor(inspector, left, right); + } else { + processor = doublesProcessor(inspector, left, right); + } + } else { + processor = doublesProcessor(inspector, left, right); + } + if (processor == null) { + throw Exprs.cannotVectorize(); + } + return (ExprVectorProcessor) processor; + } + + public abstract ExprVectorProcessor longsProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ); + + public abstract ExprVectorProcessor longDoubleProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ); + + public abstract ExprVectorProcessor doubleLongProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ); + + public abstract ExprVectorProcessor doublesProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ); +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/VectorMathBivariateProcessorFactory.java b/processing/src/main/java/org/apache/druid/math/expr/vector/VectorMathBivariateProcessorFactory.java new file mode 100644 index 000000000000..349519441223 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/VectorMathBivariateProcessorFactory.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.java.util.common.StringUtils; +import org.apache.druid.math.expr.Expr; +import org.apache.druid.math.expr.ExprType; +import org.apache.druid.math.expr.ExpressionType; +import org.apache.druid.math.expr.Exprs; +import org.apache.druid.segment.column.Types; + +/** + * Make a 2 argument, math processor with the following type rules + * long, long -> long + * long, double -> double + * double, long -> double + * double, double -> double + */ +public abstract class VectorMathBivariateProcessorFactory implements BivariateFunctionVectorProcessorFactory +{ + @Override + public ExprVectorProcessor asProcessor(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) + { + final ExpressionType leftType = left.getOutputType(inspector); + final ExpressionType rightType = right.getOutputType(inspector); + ExprVectorProcessor processor = null; + if (Types.is(leftType, ExprType.LONG)) { + if (Types.isNullOr(rightType, ExprType.LONG)) { + processor = longsProcessor(inspector, left, right); + } else if (rightType.anyOf(ExprType.STRING, ExprType.DOUBLE)) { + processor = longDoubleProcessor(inspector, left, right); + } + } else if (Types.is(leftType, ExprType.DOUBLE)) { + if (Types.is(rightType, ExprType.LONG)) { + processor = doubleLongProcessor(inspector, left, right); + } else if (Types.isNullOrAnyOf(rightType, ExprType.STRING, ExprType.DOUBLE)) { + processor = doublesProcessor(inspector, left, right); + } + } else if (leftType == null) { + if (Types.isNullOr(rightType, ExprType.LONG)) { + processor = longsProcessor(inspector, left, right); + } else if (Types.is(rightType, ExprType.DOUBLE)) { + processor = longDoubleProcessor(inspector, left, right); + } + } else if (leftType.is(ExprType.STRING)) { + if (Types.is(rightType, ExprType.LONG)) { + processor = doubleLongProcessor(inspector, left, right); + } else if (Types.is(rightType, ExprType.DOUBLE)) { + processor = doublesProcessor(inspector, left, right); + } + } + if (processor == null) { + throw Exprs.cannotVectorize(StringUtils.format("%s %s", leftType, rightType)); + } + return (ExprVectorProcessor) processor; + } + + public abstract ExprVectorProcessor longsProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ); + + public abstract ExprVectorProcessor longDoubleProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ); + + public abstract ExprVectorProcessor doubleLongProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ); + + public abstract ExprVectorProcessor doublesProcessor( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ); +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/VectorMathProcessors.java b/processing/src/main/java/org/apache/druid/math/expr/vector/VectorMathProcessors.java index c4240405378e..ad3f838f2d12 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/VectorMathProcessors.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/VectorMathProcessors.java @@ -21,2370 +21,899 @@ import com.google.common.math.LongMath; import com.google.common.primitives.Ints; -import org.apache.druid.java.util.common.StringUtils; -import org.apache.druid.math.expr.Expr; -import org.apache.druid.math.expr.ExprType; -import org.apache.druid.math.expr.ExpressionType; -import org.apache.druid.math.expr.Exprs; -import org.apache.druid.segment.column.Types; +import org.apache.druid.math.expr.ExpressionValidationException; +import org.apache.druid.math.expr.Function; -import java.util.function.Supplier; +public class VectorMathProcessors +{ + public static Add plus() + { + return Add.INSTANCE; + } + + public static Subtract subtract() + { + return Subtract.INSTANCE; + } + + public static Multiply multiply() + { + return Multiply.INSTANCE; + } + + public static Divide divide() + { + return Divide.INSTANCE; + } + + public static LongDivide longDivide() + { + return LongDivide.INSTANCE; + } + + public static Modulo modulo() + { + return Modulo.INSTANCE; + } + + public static Negate negate() + { + return Negate.INSTANCE; + } + + public static Power power() + { + return Power.INSTANCE; + } + + public static DoublePower doublePower() + { + return DoublePower.INSTANCE; + } + + public static Max max() + { + return Max.INSTANCE; + } + + public static Min min() + { + return Min.INSTANCE; + } + + public static Atan2 atan2() + { + return Atan2.INSTANCE; + } + + public static CopySign copySign() + { + return CopySign.INSTANCE; + } + + public static Hypot hypot() + { + return Hypot.INSTANCE; + } + + public static Remainder remainder() + { + return Remainder.INSTANCE; + } + + public static NextAfter nextAfter() + { + return NextAfter.INSTANCE; + } + + public static Scalb scalb() + { + return Scalb.INSTANCE; + } + + public static Abs abs() + { + return Abs.INSTANCE; + } + + public static Acos acos() + { + return Acos.INSTANCE; + } + + public static Asin asin() + { + return Asin.INSTANCE; + } + + public static Atan atan() + { + return Atan.INSTANCE; + } + + public static Cos cos() + { + return Cos.INSTANCE; + } + + public static Cosh cosh() + { + return Cosh.INSTANCE; + } + + public static Cot cot() + { + return Cot.INSTANCE; + } + + public static Sin sin() + { + return Sin.INSTANCE; + } + + public static Sinh sinh() + { + return Sinh.INSTANCE; + } + + public static Tan tan() + { + return Tan.INSTANCE; + } + + public static Tanh tanh() + { + return Tanh.INSTANCE; + } + + public static Cbrt cbrt() + { + return Cbrt.INSTANCE; + } + + public static Ceil ceil() + { + return Ceil.INSTANCE; + } + + public static Floor floor() + { + return Floor.INSTANCE; + } + + public static Exp exp() + { + return Exp.INSTANCE; + } + + public static Expm1 expm1() + { + return Expm1.INSTANCE; + } + + public static GetExponent getExponent() + { + return GetExponent.INSTANCE; + } + + public static Log log() + { + return Log.INSTANCE; + } + + public static Log10 log10() + { + return Log10.INSTANCE; + } + + public static Log1p log1p() + { + return Log1p.INSTANCE; + } + + public static NextUp nextUp() + { + return NextUp.INSTANCE; + } + + public static Rint rint() + { + return Rint.INSTANCE; + } + + public static Signum signum() + { + return Signum.INSTANCE; + } + + public static Sqrt sqrt() + { + return Sqrt.INSTANCE; + } + + public static ToDegrees toDegrees() + { + return ToDegrees.INSTANCE; + } + + public static ToRadians toRadians() + { + return ToRadians.INSTANCE; + } + + public static Ulp ulp() + { + return Ulp.INSTANCE; + } + + public static BitwiseComplement bitwiseComplement() + { + return BitwiseComplement.INSTANCE; + } + + public static BitwiseConvertDoubleToLongBits bitwiseConvertDoubleToLongBits() + { + return BitwiseConvertDoubleToLongBits.INSTANCE; + } + + public static BitwiseConvertLongBitsToDouble bitwiseConvertLongBitsToDouble() + { + return BitwiseConvertLongBitsToDouble.INSTANCE; + } + + public static BitwiseAnd bitwiseAnd() + { + return BitwiseAnd.INSTANCE; + } + + public static BitwiseOr bitwiseOr() + { + return BitwiseOr.INSTANCE; + } + + public static BitwiseXor bitwiseXor() + { + return BitwiseXor.INSTANCE; + } + + public static BitwiseShiftLeft bitwiseShiftLeft() + { + return BitwiseShiftLeft.INSTANCE; + } + + public static BitwiseShiftRight bitwiseShiftRight() + { + return BitwiseShiftRight.INSTANCE; + } + + private VectorMathProcessors() + { + // No instantiation + } + + /** + * Vectorizized addition processor factory + */ + public static final class Add extends SimpleVectorMathBivariateProcessorFactory + { + private static final Add INSTANCE = new Add(); + + public Add() + { + super(Long::sum, Double::sum, Double::sum, Double::sum); + } + } + + public static final class Subtract extends SimpleVectorMathBivariateProcessorFactory + { + private static final Subtract INSTANCE = new Subtract(); + + public Subtract() + { + super( + (left, right) -> left - right, + (left, right) -> (double) left - right, + (left, right) -> left - (double) right, + (left, right) -> left - right + ); + } + } + + public static final class Multiply extends SimpleVectorMathBivariateProcessorFactory + { + private static final Multiply INSTANCE = new Multiply(); + + public Multiply() + { + super(Multiply::multiply, Multiply::multiply, Multiply::multiply, Multiply::multiply); + } + + private static long multiply(long x, long y) + { + return x * y; + } + + private static double multiply(long x, double y) + { + return (double) x * y; + } + + private static double multiply(double x, long y) + { + return x * (double) y; + } + + private static double multiply(double x, double y) + { + return x * y; + } + } + + public static final class Divide extends SimpleVectorMathBivariateProcessorFactory + { + private static final Divide INSTANCE = new Divide(); + + public Divide() + { + super( + (left, right) -> left / right, + (left, right) -> (double) left / right, + (left, right) -> left / (double) right, + (left, right) -> left / right + ); + } + } + + public static final class LongDivide extends SimpleVectorMathBivariateLongProcessorFactory + { + private static final LongDivide INSTANCE = new LongDivide(); + + public LongDivide() + { + super( + (left, right) -> left / right, + (left, right) -> (long) (left / right), + (left, right) -> (long) (left / right), + (left, right) -> (long) (left / right) + ); + } + } + + public static final class Modulo extends SimpleVectorMathBivariateProcessorFactory + { + private static final Modulo INSTANCE = new Modulo(); + + public Modulo() + { + super( + (left, right) -> left % right, + (left, right) -> (double) left % right, + (left, right) -> left % (double) right, + (left, right) -> left % right + ); + } + } + + public static final class Negate extends SimpleVectorMathUnivariateProcessorFactory + { + private static final Negate INSTANCE = new Negate(); + + public Negate() + { + super( + input -> -input, + input -> -input + ); + } + } + + public static final class Power extends SimpleVectorMathBivariateProcessorFactory + { + private static final Power INSTANCE = new Power(); + + public Power() + { + super( + (left, right) -> LongMath.pow(left, Ints.checkedCast(right)), + Math::pow, + Math::pow, + Math::pow + ); + } + } + + public static final class DoublePower extends SimpleVectorMathBivariateDoubleProcessorFactory + { + private static final DoublePower INSTANCE = new DoublePower(); + + public DoublePower() + { + super(Math::pow, Math::pow, Math::pow, Math::pow); + } + } + + public static class Max extends SimpleVectorMathBivariateProcessorFactory + { + private static final Max INSTANCE = new Max(); + + public Max() + { + super(Math::max, Math::max, Math::max, Math::max); + } + } + + public static class Min extends SimpleVectorMathBivariateProcessorFactory + { + private static final Min INSTANCE = new Min(); + + public Min() + { + super(Math::min, Math::min, Math::min, Math::min); + } + } + + public static class Atan2 extends SimpleVectorMathBivariateDoubleProcessorFactory + { + private static final Atan2 INSTANCE = new Atan2(); + + public Atan2() + { + super(Math::atan2, Math::atan2, Math::atan2, Math::atan2); + } + } + + public static class CopySign extends SimpleVectorMathBivariateDoubleProcessorFactory + { + private static final CopySign INSTANCE = new CopySign(); + + public CopySign() + { + super( + (l1, l2) -> Math.copySign((double) l1, (double) l2), + (l1, d2) -> Math.copySign((double) l1, d2), + (d1, l2) -> Math.copySign(d1, (double) l2), + Math::copySign + ); + } + } + + public static class Hypot extends SimpleVectorMathBivariateDoubleProcessorFactory + { + private static final Hypot INSTANCE = new Hypot(); + + public Hypot() + { + super(Math::hypot, Math::hypot, Math::hypot, Math::hypot); + } + } + + public static class Remainder extends SimpleVectorMathBivariateDoubleProcessorFactory + { + private static final Remainder INSTANCE = new Remainder(); + + public Remainder() + { + super(Math::IEEEremainder, Math::IEEEremainder, Math::IEEEremainder, Math::IEEEremainder); + } + } + + public static class NextAfter extends SimpleVectorMathBivariateDoubleProcessorFactory + { + private static final NextAfter INSTANCE = new NextAfter(); + + public NextAfter() + { + super( + (l1, l2) -> Math.nextAfter((double) l1, (double) l2), + (l1, d2) -> Math.nextAfter((double) l1, d2), + (d1, l2) -> Math.nextAfter(d1, (double) l2), + Math::nextAfter + ); + } + } + + public static class Scalb extends SimpleVectorMathBivariateDoubleProcessorFactory + { + private static final Scalb INSTANCE = new Scalb(); + + public Scalb() + { + super( + (left, right) -> Math.scalb((double) left, (int) right), + (left, right) -> Math.scalb((double) left, (int) right), + (left, right) -> Math.scalb(left, (int) right), + (left, right) -> Math.scalb(left, (int) right) + ); + } + } + + public static final class Abs extends SimpleVectorMathUnivariateProcessorFactory + { + private static final Abs INSTANCE = new Abs(); + + public Abs() + { + super(Math::abs, Math::abs); + } + } + + public static final class Acos extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final Acos INSTANCE = new Acos(); + + public Acos() + { + super(Math::acos, Math::acos); + } + } + + public static final class Asin extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final Asin INSTANCE = new Asin(); + + public Asin() + { + super(Math::asin, Math::asin); + } + } + + public static final class Atan extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final Atan INSTANCE = new Atan(); + + public Atan() + { + super(Math::atan, Math::atan); + } + } + + public static final class Cos extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final Cos INSTANCE = new Cos(); + + public Cos() + { + super(Math::cos, Math::cos); + } + } + + public static final class Cosh extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final Cosh INSTANCE = new Cosh(); + + public Cosh() + { + super(Math::cosh, Math::cosh); + } + } + + public static final class Cot extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final Cot INSTANCE = new Cot(); + + public Cot() + { + super( + (input) -> Math.cos(input) / Math.sin(input), + (input) -> Math.cos(input) / Math.sin(input) + ); + } + } -public class VectorMathProcessors -{ - /** - * Make a 1 argument math processor with the following type rules - * long -> long - * double -> double - */ - public static ExprVectorProcessor makeMathProcessor( - Expr.VectorInputBindingInspector inspector, - Expr arg, - Supplier longOutLongInSupplier, - Supplier doubleOutDoubleInSupplier - ) - { - final ExpressionType inputType = arg.getOutputType(inspector); - - ExprVectorProcessor processor = null; - if (Types.isNullOr(inputType, ExprType.DOUBLE)) { - processor = doubleOutDoubleInSupplier.get(); - } else if (inputType.is(ExprType.LONG)) { - processor = longOutLongInSupplier.get(); + public static final class Sin extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final Sin INSTANCE = new Sin(); + + public Sin() + { + super(Math::sin, Math::sin); } + } + + public static final class Sinh extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final Sinh INSTANCE = new Sinh(); - if (processor == null) { - throw Exprs.cannotVectorize(); + public Sinh() + { + super(Math::sinh, Math::sinh); } - return (ExprVectorProcessor) processor; } - /** - * Make a 1 argument math processor with the following type rules - * long -> double - * double -> double - */ - public static ExprVectorProcessor makeDoubleMathProcessor( - Expr.VectorInputBindingInspector inspector, - Expr arg, - Supplier doubleOutLongInSupplier, - Supplier doubleOutDoubleInSupplier - ) - { - final ExpressionType inputType = arg.getOutputType(inspector); - - ExprVectorProcessor processor = null; - if (Types.isNullOr(inputType, ExprType.DOUBLE)) { - processor = doubleOutDoubleInSupplier.get(); - } else if (inputType.is(ExprType.LONG)) { - processor = doubleOutLongInSupplier.get(); + public static final class Tan extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final Tan INSTANCE = new Tan(); + + public Tan() + { + super(Math::tan, Math::tan); } + } + + public static final class Tanh extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final Tanh INSTANCE = new Tanh(); - if (processor == null) { - throw Exprs.cannotVectorize(); + public Tanh() + { + super(Math::tanh, Math::tanh); } - return (ExprVectorProcessor) processor; } - /** - * Make a 1 argument math processor with the following type rules - * long -> long - * double -> long - */ - public static ExprVectorProcessor makeLongMathProcessor( - Expr.VectorInputBindingInspector inspector, - Expr arg, - Supplier longOutLongInSupplier, - Supplier longOutDoubleInSupplier - ) - { - final ExpressionType inputType = arg.getOutputType(inspector); - - ExprVectorProcessor processor = null; - if (Types.isNullOr(inputType, ExprType.DOUBLE)) { - processor = longOutDoubleInSupplier.get(); - } else if (inputType.is(ExprType.LONG)) { - processor = longOutLongInSupplier.get(); + public static final class Cbrt extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final Cbrt INSTANCE = new Cbrt(); + + public Cbrt() + { + super(Math::cbrt, Math::cbrt); } + } + + public static final class Ceil extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final Ceil INSTANCE = new Ceil(); - if (processor == null) { - throw Exprs.cannotVectorize(); + public Ceil() + { + super(Math::ceil, Math::ceil); } - return (ExprVectorProcessor) processor; } - /** - * Make a 2 argument, math processor with the following type rules - * long, long -> long - * long, double -> double - * double, long -> double - * double, double -> double - */ - public static ExprVectorProcessor makeMathProcessor( - Expr.VectorInputBindingInspector inspector, - Expr left, - Expr right, - Supplier longOutLongsInProcessor, - Supplier doubleOutLongDoubleInProcessor, - Supplier doubleOutDoubleLongInProcessor, - Supplier doubleOutDoublesInProcessor - ) - { - final ExpressionType leftType = left.getOutputType(inspector); - final ExpressionType rightType = right.getOutputType(inspector); - ExprVectorProcessor processor = null; - if (Types.is(leftType, ExprType.LONG)) { - if (Types.isNullOr(rightType, ExprType.LONG)) { - processor = longOutLongsInProcessor.get(); - } else if (rightType.anyOf(ExprType.STRING, ExprType.DOUBLE)) { - processor = doubleOutLongDoubleInProcessor.get(); - } - } else if (Types.is(leftType, ExprType.DOUBLE)) { - if (Types.is(rightType, ExprType.LONG)) { - processor = doubleOutDoubleLongInProcessor.get(); - } else if (Types.isNullOrAnyOf(rightType, ExprType.STRING, ExprType.DOUBLE)) { - processor = doubleOutDoublesInProcessor.get(); - } - } else if (leftType == null) { - if (Types.is(rightType, ExprType.LONG)) { - processor = longOutLongsInProcessor.get(); - } else if (Types.is(rightType, ExprType.DOUBLE)) { - processor = doubleOutLongDoubleInProcessor.get(); - } else if (rightType == null) { - processor = longOutLongsInProcessor.get(); - } - } else if (leftType.is(ExprType.STRING)) { - if (Types.is(rightType, ExprType.LONG)) { - processor = doubleOutDoubleLongInProcessor.get(); - } else if (Types.is(rightType, ExprType.DOUBLE)) { - processor = doubleOutDoublesInProcessor.get(); - } + public static final class Floor extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final Floor INSTANCE = new Floor(); + + public Floor() + { + super(Math::floor, Math::floor); } - if (processor == null) { - throw Exprs.cannotVectorize(StringUtils.format("%s %s", leftType, rightType)); + } + + public static final class Exp extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final Exp INSTANCE = new Exp(); + + public Exp() + { + super(Math::exp, Math::exp); } - return (ExprVectorProcessor) processor; } - /** - * Make a 2 argument, math processor with the following type rules - * long, long -> double - * long, double -> double - * double, long -> double - * double, double -> double - */ - public static ExprVectorProcessor makeDoubleMathProcessor( - Expr.VectorInputBindingInspector inspector, - Expr left, - Expr right, - Supplier doubleOutLongsInProcessor, - Supplier doubleOutLongDoubleInProcessor, - Supplier doubleOutDoubleLongInProcessor, - Supplier doubleOutDoublesInProcessor - ) - { - final ExpressionType leftType = left.getOutputType(inspector); - final ExpressionType rightType = right.getOutputType(inspector); - ExprVectorProcessor processor = null; - if (Types.is(leftType, ExprType.LONG)) { - if (Types.is(rightType, ExprType.LONG)) { - processor = doubleOutLongsInProcessor.get(); - } else if (Types.isNullOr(rightType, ExprType.DOUBLE)) { - processor = doubleOutLongDoubleInProcessor.get(); - } - } else if (Types.is(leftType, ExprType.DOUBLE)) { - if (Types.is(rightType, ExprType.LONG)) { - processor = doubleOutDoubleLongInProcessor.get(); - } else if (Types.isNullOr(rightType, ExprType.DOUBLE)) { - processor = doubleOutDoublesInProcessor.get(); - } - } else if (leftType == null) { - if (Types.is(rightType, ExprType.LONG)) { - processor = doubleOutDoubleLongInProcessor.get(); - } else if (Types.is(rightType, ExprType.DOUBLE)) { - processor = doubleOutDoublesInProcessor.get(); - } + public static final class Expm1 extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final Expm1 INSTANCE = new Expm1(); + + public Expm1() + { + super(Math::expm1, Math::expm1); } - if (processor == null) { - throw Exprs.cannotVectorize(); + } + + public static class GetExponent extends SimpleVectorMathUnivariateLongProcessorFactory + { + private static final GetExponent INSTANCE = new GetExponent(); + + public GetExponent() + { + super(Math::getExponent, Math::getExponent); } - return (ExprVectorProcessor) processor; } - /** - * Make a 2 argument, math processor with the following type rules - * long, long -> long - * long, double -> long - * double, long -> long - * double, double -> long - */ - public static ExprVectorProcessor makeLongMathProcessor( - Expr.VectorInputBindingInspector inspector, - Expr left, - Expr right, - Supplier longOutLongsInProcessor, - Supplier longOutLongDoubleInProcessor, - Supplier longOutDoubleLongInProcessor, - Supplier longOutDoublesInProcessor - ) - { - final ExpressionType leftType = left.getOutputType(inspector); - final ExpressionType rightType = right.getOutputType(inspector); - ExprVectorProcessor processor = null; - if (Types.is(leftType, ExprType.LONG)) { - if (Types.isNullOr(rightType, ExprType.LONG)) { - processor = longOutLongsInProcessor.get(); - } else if (rightType.is(ExprType.DOUBLE)) { - processor = longOutLongDoubleInProcessor.get(); - } - } else if (Types.is(leftType, ExprType.DOUBLE)) { - if (Types.is(rightType, ExprType.LONG)) { - processor = longOutDoubleLongInProcessor.get(); - } else if (Types.isNullOr(rightType, ExprType.DOUBLE)) { - processor = longOutDoublesInProcessor.get(); - } - } else if (leftType == null) { - if (Types.is(rightType, ExprType.LONG)) { - processor = longOutLongsInProcessor.get(); - } else if (Types.is(rightType, ExprType.DOUBLE)) { - processor = longOutDoublesInProcessor.get(); - } + public static final class Log extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final Log INSTANCE = new Log(); + + public Log() + { + super(Math::log, Math::log); } - if (processor == null) { - throw Exprs.cannotVectorize(); + } + + public static final class Log10 extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final Log10 INSTANCE = new Log10(); + + public Log10() + { + super(Math::log10, Math::log10); } - return (ExprVectorProcessor) processor; - } - - public static ExprVectorProcessor plus(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) - { - return makeMathProcessor( - inspector, - left, - right, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return left + right; - } - }, - () -> new DoubleOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, double right) - { - return (double) left + right; - } - }, - () -> new DoubleOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, long right) - { - return left + (double) right; - } - }, - () -> new DoubleOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, double right) - { - return left + right; - } - } - ); - } - - public static ExprVectorProcessor minus(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) - { - return makeMathProcessor( - inspector, - left, - right, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return left - right; - } - }, - () -> new DoubleOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, double right) - { - return (double) left - right; - } - }, - () -> new DoubleOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, long right) - { - return left - (double) right; - } - }, - () -> new DoubleOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, double right) - { - return left - right; - } - } - ); - } - - public static ExprVectorProcessor multiply(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) - { - return makeMathProcessor( - inspector, - left, - right, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return left * right; - } - }, - () -> new DoubleOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, double right) - { - return (double) left * right; - } - }, - () -> new DoubleOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, long right) - { - return left * (double) right; - } - }, - () -> new DoubleOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, double right) - { - return left * right; - } - } - ); - } - - public static ExprVectorProcessor divide(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) - { - return makeMathProcessor( - inspector, - left, - right, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return left / right; - } - }, - () -> new DoubleOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, double right) - { - return (double) left / right; - } - }, - () -> new DoubleOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, long right) - { - return left / (double) right; - } - }, - () -> new DoubleOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, double right) - { - return left / right; - } - } - ); - } - - public static ExprVectorProcessor longDivide(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) - { - return makeLongMathProcessor( - inspector, - left, - right, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return left / right; - } - }, - () -> new LongOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, double right) - { - return (long) (left / right); - } - }, - () -> new LongOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double left, long right) - { - return (long) (left / right); - } - }, - () -> new LongOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double left, double right) - { - return (long) (left / right); - } - } - ); - } - - public static ExprVectorProcessor modulo(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) - { - return makeMathProcessor( - inspector, - left, - right, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return left % right; - } - }, - () -> new DoubleOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, double right) - { - return (double) left % right; - } - }, - () -> new DoubleOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, long right) - { - return left % (double) right; - } - }, - () -> new DoubleOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, double right) - { - return left % right; - } - } - ); - } - - public static ExprVectorProcessor negate(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeMathProcessor( - inspector, - arg, - () -> new LongOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long input) - { - return -input; - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return -input; - } - } - ); - } - - public static ExprVectorProcessor power(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) - { - return makeMathProcessor( - inspector, - left, - right, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return LongMath.pow(left, Ints.checkedCast(right)); - } - }, - () -> new DoubleOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, double right) - { - return Math.pow(left, right); - } - }, - () -> new DoubleOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, long right) - { - return Math.pow(left, right); - } - }, - () -> new DoubleOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, double right) - { - return Math.pow(left, right); - } - } - ); - } - - public static ExprVectorProcessor doublePower( - Expr.VectorInputBindingInspector inspector, - Expr left, - Expr right - ) - { - final ExpressionType leftType = left.getOutputType(inspector); - final ExpressionType rightType = right.getOutputType(inspector); - ExprVectorProcessor processor = null; - if ((Types.is(leftType, ExprType.LONG) && Types.isNullOr(rightType, ExprType.LONG)) || - (leftType == null && Types.is(rightType, ExprType.LONG))) { - processor = new DoubleOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, long right) - { - return Math.pow(left, right); - } - }; + } + public static final class Log1p extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final Log1p INSTANCE = new Log1p(); + + public Log1p() + { + super(Math::log1p, Math::log1p); } + } + + public static final class NextUp extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final NextUp INSTANCE = new NextUp(); - if (processor != null) { - return (ExprVectorProcessor) processor; + public NextUp() + { + super(l -> Math.nextUp((double) l), Math::nextUp); } - return power(inspector, left, right); - } - - public static ExprVectorProcessor max(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) - { - return makeMathProcessor( - inspector, - left, - right, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return Math.max(left, right); - } - }, - () -> new DoubleOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, double right) - { - return Math.max(left, right); - } - }, - () -> new DoubleOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, long right) - { - return Math.max(left, right); - } - }, - () -> new DoubleOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, double right) - { - return Math.max(left, right); - } - } - ); - } - - public static ExprVectorProcessor min(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) - { - return makeMathProcessor( - inspector, - left, - right, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return Math.min(left, right); - } - }, - () -> new DoubleOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, double right) - { - return Math.min(left, right); - } - }, - () -> new DoubleOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, long right) - { - return Math.min(left, right); - } - }, - () -> new DoubleOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, double right) - { - return Math.min(left, right); - } - } - ); - } - - public static ExprVectorProcessor atan2(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) - { - return makeDoubleMathProcessor( - inspector, - left, - right, - () -> new DoubleOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, long right) - { - return Math.atan2(left, right); - } - }, - () -> new DoubleOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, double right) - { - return Math.atan2(left, right); - } - }, - () -> new DoubleOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, long right) - { - return Math.atan2(left, right); - } - }, - () -> new DoubleOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, double right) - { - return Math.atan2(left, right); - } - } - ); - } - - public static ExprVectorProcessor copySign(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) - { - return makeDoubleMathProcessor( - inspector, - left, - right, - () -> new DoubleOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, long right) - { - return Math.copySign((double) left, (double) right); - } - }, - () -> new DoubleOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, double right) - { - return Math.copySign((double) left, right); - } - }, - () -> new DoubleOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, long right) - { - return Math.copySign(left, (double) right); - } - }, - () -> new DoubleOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, double right) - { - return Math.copySign(left, right); - } - } - ); - } - - public static ExprVectorProcessor hypot(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) - { - return makeDoubleMathProcessor( - inspector, - left, - right, - () -> new DoubleOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, long right) - { - return Math.hypot(left, right); - } - }, - () -> new DoubleOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, double right) - { - return Math.hypot(left, right); - } - }, - () -> new DoubleOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, long right) - { - return Math.hypot(left, right); - } - }, - () -> new DoubleOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, double right) - { - return Math.hypot(left, right); - } - } - ); - } - - public static ExprVectorProcessor remainder(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) - { - return makeDoubleMathProcessor( - inspector, - left, - right, - () -> new DoubleOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, long right) - { - return Math.IEEEremainder(left, right); - } - }, - () -> new DoubleOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, double right) - { - return Math.IEEEremainder(left, right); - } - }, - () -> new DoubleOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, long right) - { - return Math.IEEEremainder(left, right); - } - }, - () -> new DoubleOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, double right) - { - return Math.IEEEremainder(left, right); - } - } - ); - } - - public static ExprVectorProcessor nextAfter(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) - { - return makeDoubleMathProcessor( - inspector, - left, - right, - () -> new DoubleOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, long right) - { - return Math.nextAfter((double) left, (double) right); - } - }, - () -> new DoubleOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, double right) - { - return Math.nextAfter((double) left, right); - } - }, - () -> new DoubleOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, long right) - { - return Math.nextAfter(left, (double) right); - } - }, - () -> new DoubleOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, double right) - { - return Math.nextAfter(left, right); - } - } - ); - } - - public static ExprVectorProcessor scalb(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) - { - return makeDoubleMathProcessor( - inspector, - left, - right, - () -> new DoubleOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, long right) - { - return Math.scalb((double) left, (int) right); - } - }, - () -> new DoubleOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long left, double right) - { - return Math.scalb((double) left, (int) right); - } - }, - () -> new DoubleOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, long right) - { - return Math.scalb(left, (int) right); - } - }, - () -> new DoubleOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double left, double right) - { - return Math.scalb(left, (int) right); - } - } - ); - } - - public static ExprVectorProcessor acos(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.acos(input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.acos(input); - } - } - ); - } - - public static ExprVectorProcessor asin(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.asin(input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.asin(input); - } - } - ); - } - - public static ExprVectorProcessor atan(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.atan(input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.atan(input); - } - } - ); - } - - public static ExprVectorProcessor cos(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.cos(input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.cos(input); - } - } - ); - } - - public static ExprVectorProcessor cosh(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.cosh(input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.cosh(input); - } - } - ); - } - - public static ExprVectorProcessor cot(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.cos(input) / Math.sin(input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.cos(input) / Math.sin(input); - } - } - ); - } - - public static ExprVectorProcessor sin(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.sin(input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.sin(input); - } - } - ); - } - - public static ExprVectorProcessor sinh(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.sinh(input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.sinh(input); - } - } - ); - } - - public static ExprVectorProcessor tan(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.tan(input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.tan(input); - } - } - ); - } - - public static ExprVectorProcessor tanh(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.tanh(input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.tanh(input); - } - } - ); - } - - public static ExprVectorProcessor abs(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeMathProcessor( - inspector, - arg, - () -> new LongOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long input) - { - return Math.abs(input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.abs(input); - } - } - ); - } - - public static ExprVectorProcessor cbrt(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.cbrt(input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.cbrt(input); - } - } - ); - } - - public static ExprVectorProcessor ceil(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.ceil(input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.ceil(input); - } - } - ); - } - - public static ExprVectorProcessor floor(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.floor(input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.floor(input); - } - } - ); - } - - public static ExprVectorProcessor exp(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.exp(input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.exp(input); - } - } - ); - } - - public static ExprVectorProcessor expm1(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.expm1(input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.expm1(input); - } - } - ); - } - - public static ExprVectorProcessor getExponent(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeLongMathProcessor( - inspector, - arg, - () -> new LongOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long input) - { - return Math.getExponent((double) input); - } - }, - () -> new LongOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double input) - { - return Math.getExponent(input); - } - } - ); - } - - public static ExprVectorProcessor log(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.log(input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.log(input); - } - } - ); - } - - public static ExprVectorProcessor log10(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.log10(input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.log10(input); - } - } - ); - } - - public static ExprVectorProcessor log1p(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.log1p(input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.log1p(input); - } - } - ); - } - - public static ExprVectorProcessor nextUp(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.nextUp((double) input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.nextUp(input); - } - } - ); - } - - public static ExprVectorProcessor rint(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.rint(input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.rint(input); - } - } - ); - } - - public static ExprVectorProcessor signum(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.signum(input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.signum(input); - } - } - ); - } - - public static ExprVectorProcessor sqrt(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.sqrt(input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.sqrt(input); - } - } - ); - } - - public static ExprVectorProcessor toDegrees(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.toDegrees(input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.toDegrees(input); - } - } - ); - } - - public static ExprVectorProcessor toRadians(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.toRadians(input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.toRadians(input); - } - } - ); - } - - public static ExprVectorProcessor ulp(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeDoubleMathProcessor( - inspector, - arg, - () -> new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Math.ulp((double) input); - } - }, - () -> new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Math.ulp(input); - } - } - ); - } - - public static ExprVectorProcessor bitwiseComplement(Expr.VectorInputBindingInspector inspector, Expr arg) - { - return makeLongMathProcessor( - inspector, - arg, - () -> new LongOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long input) - { - return ~input; - } - }, - () -> new LongOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double input) - { + } + + public static final class Rint extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final Rint INSTANCE = new Rint(); + + public Rint() + { + super(Math::rint, Math::rint); + } + } + + public static final class Signum extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final Signum INSTANCE = new Signum(); + + public Signum() + { + super(Math::signum, Math::signum); + } + } + + public static final class Sqrt extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final Sqrt INSTANCE = new Sqrt(); + + public Sqrt() + { + super(Math::sqrt, Math::sqrt); + } + } + + public static final class ToDegrees extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final ToDegrees INSTANCE = new ToDegrees(); + + public ToDegrees() + { + super(Math::toDegrees, Math::toDegrees); + } + } + + public static final class ToRadians extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final ToRadians INSTANCE = new ToRadians(); + + public ToRadians() + { + super(Math::toRadians, Math::toRadians); + } + } + + public static final class Ulp extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final Ulp INSTANCE = new Ulp(); + + public Ulp() + { + super(l -> Math.ulp((double) l), Math::ulp); + } + } + + + public static final class BitwiseComplement extends SimpleVectorMathUnivariateLongProcessorFactory + { + private static final BitwiseComplement INSTANCE = new BitwiseComplement(); + + public BitwiseComplement() + { + super( + input -> ~input, + input -> { + if (input < Long.MIN_VALUE || input > Long.MAX_VALUE) { + throw new ExpressionValidationException( + Function.BitwiseComplement.NAME, + "Possible data truncation, param [%f] is out of LONG value range", + input + ); + } return ~((long) input); } - } - ); - } - - public static ExprVectorProcessor bitwiseConvertDoubleToLongBits( - Expr.VectorInputBindingInspector inspector, - Expr arg - ) - { - final ExpressionType inputType = arg.getOutputType(inspector); - - ExprVectorProcessor processor = null; - if (Types.is(inputType, ExprType.LONG)) { - processor = new LongOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long input) - { - return Double.doubleToLongBits(input); - } - }; - } else if (Types.isNullOr(inputType, ExprType.DOUBLE)) { - processor = new LongOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double input) - { - return Double.doubleToLongBits(input); - } - }; + ); } - if (processor == null) { - throw Exprs.cannotVectorize(); + } + + public static class BitwiseConvertDoubleToLongBits extends SimpleVectorMathUnivariateLongProcessorFactory + { + private static final BitwiseConvertDoubleToLongBits INSTANCE = new BitwiseConvertDoubleToLongBits(); + + public BitwiseConvertDoubleToLongBits() + { + super(Double::doubleToLongBits, Double::doubleToLongBits); } - return (ExprVectorProcessor) processor; - } - - public static ExprVectorProcessor bitwiseConvertLongBitsToDouble( - Expr.VectorInputBindingInspector inspector, - Expr arg - ) - { - final ExpressionType inputType = arg.getOutputType(inspector); - - ExprVectorProcessor processor = null; - if (Types.is(inputType, ExprType.LONG)) { - processor = new DoubleOutLongInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(long input) - { - return Double.longBitsToDouble(input); - } - }; - } else if (Types.isNullOr(inputType, ExprType.DOUBLE)) { - processor = new DoubleOutDoubleInFunctionVectorValueProcessor( - arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public double apply(double input) - { - return Double.longBitsToDouble((long) input); - } - }; + } + + public static class BitwiseConvertLongBitsToDouble extends SimpleVectorMathUnivariateDoubleProcessorFactory + { + private static final BitwiseConvertLongBitsToDouble INSTANCE = new BitwiseConvertLongBitsToDouble(); + + public BitwiseConvertLongBitsToDouble() + { + super(Double::longBitsToDouble, (input) -> Double.longBitsToDouble((long) input)); } - if (processor == null) { - throw Exprs.cannotVectorize(); + } + + public static class BitwiseAnd extends SimpleVectorMathBivariateLongProcessorFactory + { + private static final BitwiseAnd INSTANCE = new BitwiseAnd(); + + public BitwiseAnd() + { + super( + (left, right) -> left & right, + (left, right) -> left & (long) right, + (left, right) -> (long) left & right, + (left, right) -> (long) left & (long) right + ); } - return (ExprVectorProcessor) processor; - } - - public static ExprVectorProcessor bitwiseAnd(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) - { - return makeLongMathProcessor( - inspector, - left, - right, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return left & right; - } - }, - () -> new LongOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, double right) - { - return left & (long) right; - } - }, - () -> new LongOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double left, long right) - { - return (long) left & right; - } - }, - () -> new LongOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double left, double right) - { - return (long) left & (long) right; - } - } - ); - } - - public static ExprVectorProcessor bitwiseOr(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) - { - return makeLongMathProcessor( - inspector, - left, - right, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return left | right; - } - }, - () -> new LongOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, double right) - { - return left | (long) right; - } - }, - () -> new LongOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double left, long right) - { - return (long) left | right; - } - }, - () -> new LongOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double left, double right) - { - return (long) left | (long) right; - } - } - ); - } - - public static ExprVectorProcessor bitwiseXor(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) - { - return makeLongMathProcessor( - inspector, - left, - right, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return left ^ right; - } - }, - () -> new LongOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, double right) - { - return left ^ (long) right; - } - }, - () -> new LongOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double left, long right) - { - return (long) left ^ right; - } - }, - () -> new LongOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double left, double right) - { - return (long) left ^ (long) right; - } - } - ); - } - - public static ExprVectorProcessor bitwiseShiftLeft( - Expr.VectorInputBindingInspector inspector, - Expr left, - Expr right - ) - { - return makeLongMathProcessor( - inspector, - left, - right, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return left << right; - } - }, - () -> new LongOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, double right) - { - return left << (long) right; - } - }, - () -> new LongOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double left, long right) - { - return (long) left << right; - } - }, - () -> new LongOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double left, double right) - { - return (long) left << (long) right; - } - } - ); - } - - public static ExprVectorProcessor bitwiseShiftRight( - Expr.VectorInputBindingInspector inspector, - Expr left, - Expr right - ) - { - return makeLongMathProcessor( - inspector, - left, - right, - () -> new LongOutLongsInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, long right) - { - return left >> right; - } - }, - () -> new LongOutLongDoubleInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long left, double right) - { - return left >> (long) right; - } - }, - () -> new LongOutDoubleLongInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double left, long right) - { - return (long) left >> right; - } - }, - () -> new LongOutDoublesInFunctionVectorValueProcessor( - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(double left, double right) - { - return (long) left >> (long) right; - } - } - ); } - private VectorMathProcessors() + public static class BitwiseOr extends SimpleVectorMathBivariateLongProcessorFactory { - // No instantiation + private static final BitwiseOr INSTANCE = new BitwiseOr(); + + public BitwiseOr() + { + super( + (left, right) -> left | right, + (left, right) -> left | (long) right, + (left, right) -> (long) left | right, + (left, right) -> (long) left | (long) right + ); + } + } + + public static class BitwiseXor extends SimpleVectorMathBivariateLongProcessorFactory + { + private static final BitwiseXor INSTANCE = new BitwiseXor(); + + public BitwiseXor() + { + super( + (left, right) -> left ^ right, + (left, right) -> left ^ (long) right, + (left, right) -> (long) left ^ right, + (left, right) -> (long) left ^ (long) right + ); + } + } + + public static class BitwiseShiftLeft extends SimpleVectorMathBivariateLongProcessorFactory + { + private static final BitwiseShiftLeft INSTANCE = new BitwiseShiftLeft(); + + public BitwiseShiftLeft() + { + super( + (left, right) -> left << right, + (left, right) -> left << (long) right, + (left, right) -> (long) left << right, + (left, right) -> (long) left << (long) right + ); + } + } + + public static class BitwiseShiftRight extends SimpleVectorMathBivariateLongProcessorFactory + { + private static final BitwiseShiftRight INSTANCE = new BitwiseShiftRight(); + + public BitwiseShiftRight() + { + super( + (left, right) -> left >> right, + (left, right) -> left >> (long) right, + (left, right) -> (long) left >> right, + (left, right) -> (long) left >> (long) right + ); + } } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/VectorMathUnivariateDoubleProcessorFactory.java b/processing/src/main/java/org/apache/druid/math/expr/vector/VectorMathUnivariateDoubleProcessorFactory.java new file mode 100644 index 000000000000..cdbbdd219305 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/VectorMathUnivariateDoubleProcessorFactory.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.math.expr.Expr; +import org.apache.druid.math.expr.ExprType; +import org.apache.druid.math.expr.ExpressionType; +import org.apache.druid.math.expr.Exprs; + +/** + * Make a 1 argument math processor with the following type rules + * long -> double + * double -> double + */ +public abstract class VectorMathUnivariateDoubleProcessorFactory implements UnivariateVectorProcessorFactory +{ + @Override + public ExprVectorProcessor asProcessor(Expr.VectorInputBindingInspector inspector, Expr arg) + { + final ExpressionType inputType = arg.getOutputType(inspector); + + ExprVectorProcessor processor = null; + if (inputType != null) { + if (inputType.is(ExprType.LONG)) { + processor = longProcessor(inspector, arg); + } else if (inputType.is(ExprType.DOUBLE)) { + processor = doubleProcessor(inspector, arg); + } + } else { + processor = doubleProcessor(inspector, arg); + } + if (processor == null) { + throw Exprs.cannotVectorize(); + } + return (ExprVectorProcessor) processor; + } + + public abstract ExprVectorProcessor longProcessor(Expr.VectorInputBindingInspector inspector, Expr arg); + + public abstract ExprVectorProcessor doubleProcessor(Expr.VectorInputBindingInspector inspector, Expr arg); +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/VectorMathUnivariateLongProcessorFactory.java b/processing/src/main/java/org/apache/druid/math/expr/vector/VectorMathUnivariateLongProcessorFactory.java new file mode 100644 index 000000000000..7044a6d5ad93 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/VectorMathUnivariateLongProcessorFactory.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.math.expr.Expr; +import org.apache.druid.math.expr.ExprType; +import org.apache.druid.math.expr.ExpressionType; +import org.apache.druid.math.expr.Exprs; + +/** + * 1 argument math processor with the following type rules + * long -> long + * double -> long + */ +public abstract class VectorMathUnivariateLongProcessorFactory implements UnivariateVectorProcessorFactory +{ + @Override + public ExprVectorProcessor asProcessor(Expr.VectorInputBindingInspector inspector, Expr arg) + { + final ExpressionType inputType = arg.getOutputType(inspector); + + ExprVectorProcessor processor = null; + if (inputType != null) { + if (inputType.is(ExprType.LONG)) { + processor = longProcessor(inspector, arg); + } else if (inputType.is(ExprType.DOUBLE)) { + processor = doubleProcessor(inspector, arg); + } + } else { + processor = longProcessor(inspector, arg); + } + if (processor == null) { + throw Exprs.cannotVectorize(); + } + return (ExprVectorProcessor) processor; + } + + public abstract ExprVectorProcessor longProcessor(Expr.VectorInputBindingInspector inspector, Expr arg); + + public abstract ExprVectorProcessor doubleProcessor(Expr.VectorInputBindingInspector inspector, Expr arg); +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/VectorMathUnivariateProcessorFactory.java b/processing/src/main/java/org/apache/druid/math/expr/vector/VectorMathUnivariateProcessorFactory.java new file mode 100644 index 000000000000..3d144a031858 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/VectorMathUnivariateProcessorFactory.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.math.expr.Expr; +import org.apache.druid.math.expr.ExprType; +import org.apache.druid.math.expr.ExpressionType; +import org.apache.druid.math.expr.Exprs; + +/** + * 1 argument math processor with the following type rules + * long -> long + * double -> double + */ +public abstract class VectorMathUnivariateProcessorFactory implements UnivariateVectorProcessorFactory +{ + @Override + public ExprVectorProcessor asProcessor(Expr.VectorInputBindingInspector inspector, Expr arg) + { + final ExpressionType inputType = arg.getOutputType(inspector); + + ExprVectorProcessor processor = null; + if (inputType != null) { + if (inputType.is(ExprType.LONG)) { + processor = longProcessor(inspector, arg); + } else if (inputType.is(ExprType.DOUBLE)) { + processor = doubleProcessor(inspector, arg); + } + } else { + processor = doubleProcessor(inspector, arg); + } + if (processor == null) { + throw Exprs.cannotVectorize(); + } + return (ExprVectorProcessor) processor; + } + + public abstract ExprVectorProcessor longProcessor(Expr.VectorInputBindingInspector inspector, Expr arg); + + public abstract ExprVectorProcessor doubleProcessor(Expr.VectorInputBindingInspector inspector, Expr arg); +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/VectorProcessors.java b/processing/src/main/java/org/apache/druid/math/expr/vector/VectorProcessors.java index 33e4c82cbe8a..d75de0dfe375 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/VectorProcessors.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/VectorProcessors.java @@ -49,7 +49,7 @@ public static ExprVectorProcessor makeSymmetricalProcessor( Expr right, Supplier> longProcessor, Supplier> doubleProcessor, - Supplier> stringProcessor + Supplier> objectProcessor ) { final ExpressionType leftType = left.getOutputType(inspector); @@ -68,7 +68,7 @@ public static ExprVectorProcessor makeSymmetricalProcessor( ExprVectorProcessor processor = null; if (Types.is(leftType, ExprType.STRING)) { - processor = stringProcessor.get(); + processor = objectProcessor.get(); } else if (Types.is(leftType, ExprType.LONG)) { processor = longProcessor.get(); } else if (Types.is(leftType, ExprType.DOUBLE)) { @@ -95,20 +95,7 @@ public static ExprVectorProcessor constant(@Nullable Object constant, int final Object[] objects = new Object[maxVectorSize]; Arrays.fill(objects, constant); final ExprEvalObjectVector eval = new ExprEvalObjectVector(objects, type); - return new ExprVectorProcessor() - { - @Override - public ExprEvalVector evalVector(Expr.VectorInputBinding bindings) - { - return (ExprEvalVector) eval; - } - - @Override - public ExpressionType getOutputType() - { - return type; - } - }; + return (ExprVectorProcessor) new ConstantVectorProcessor<>(eval, maxVectorSize); } /** @@ -132,20 +119,7 @@ public static ExprVectorProcessor constant(@Nullable Double constant, int Arrays.fill(doubles, constant); } final ExprEvalDoubleVector eval = new ExprEvalDoubleVector(doubles, nulls); - return new ExprVectorProcessor() - { - @Override - public ExprEvalVector evalVector(Expr.VectorInputBinding bindings) - { - return (ExprEvalVector) eval; - } - - @Override - public ExpressionType getOutputType() - { - return ExpressionType.DOUBLE; - } - }; + return (ExprVectorProcessor) new ConstantVectorProcessor<>(eval, maxVectorSize); } /** @@ -169,20 +143,7 @@ public static ExprVectorProcessor constant(@Nullable Long constant, int m Arrays.fill(longs, constant); } final ExprEvalLongVector eval = new ExprEvalLongVector(longs, nulls); - return new ExprVectorProcessor() - { - @Override - public ExprEvalVector evalVector(Expr.VectorInputBinding bindings) - { - return (ExprEvalVector) eval; - } - - @Override - public ExpressionType getOutputType() - { - return ExpressionType.LONG; - } - }; + return (ExprVectorProcessor) new ConstantVectorProcessor<>(eval, maxVectorSize); } /** @@ -195,45 +156,13 @@ public ExpressionType getOutputType() */ public static ExprVectorProcessor identifier(Expr.VectorInputBindingInspector inspector, String binding) { - ExpressionType inputType = inspector.getType(binding); + final ExpressionType inputType = inspector.getType(binding); - if (inputType == null) { - // nil column, we can be anything, so be a string because it's the most flexible - if (NullHandling.sqlCompatible()) { - return constant((Long) null, inspector.getMaxVectorSize()); - } else { - return constant(null, inspector.getMaxVectorSize(), ExpressionType.STRING); - } - } - switch (inputType.getType()) { - case LONG: - return new IdentifierVectorProcessor(inputType) - { - @Override - public ExprEvalVector evalVector(Expr.VectorInputBinding bindings) - { - return new ExprEvalLongVector(bindings.getLongVector(binding), bindings.getNullVector(binding)); - } - }; - case DOUBLE: - return new IdentifierVectorProcessor(inputType) - { - @Override - public ExprEvalVector evalVector(Expr.VectorInputBinding bindings) - { - return new ExprEvalDoubleVector(bindings.getDoubleVector(binding), bindings.getNullVector(binding)); - } - }; - default: - return new IdentifierVectorProcessor(inputType) - { - @Override - public ExprEvalVector evalVector(Expr.VectorInputBinding bindings) - { - return new ExprEvalObjectVector(bindings.getObjectVector(binding), ExpressionType.STRING); - } - }; - } + return new IdentifierVectorProcessor<>( + inputType == null ? ExpressionType.LONG : inputType, + binding, + inspector.getMaxVectorSize() + ); } /** @@ -243,12 +172,17 @@ public ExprEvalVector evalVector(Expr.VectorInputBinding bindings) */ public static ExprVectorProcessor parseLong(Expr.VectorInputBindingInspector inspector, Expr arg, int radix) { - final ExprVectorProcessor processor = new LongOutObjectInFunctionVectorProcessor( + final ExprVectorProcessor processor = new LongUnivariateObjectFunctionVectorProcessor( arg.asVectorProcessor(inspector), - inspector.getMaxVectorSize(), ExpressionType.STRING ) { + @Override + public int maxVectorSize() + { + return inspector.getMaxVectorSize(); + } + @Override public void processIndex(Object[] strings, long[] longs, boolean[] outputNulls, int i) { @@ -324,6 +258,12 @@ public ExpressionType getOutputType() { return ExpressionType.LONG; } + + @Override + public int maxVectorSize() + { + return outputValues.length; + } }; } else if (Types.is(type, ExprType.DOUBLE)) { final ExprVectorProcessor input = expr.asVectorProcessor(inspector); @@ -355,6 +295,12 @@ public ExpressionType getOutputType() { return ExpressionType.LONG; } + + @Override + public int maxVectorSize() + { + return outputValues.length; + } }; } else { final ExprVectorProcessor input = expr.asVectorProcessor(inspector); @@ -382,6 +328,12 @@ public ExpressionType getOutputType() { return ExpressionType.LONG; } + + @Override + public int maxVectorSize() + { + return outputValues.length; + } }; } @@ -435,6 +387,12 @@ public ExpressionType getOutputType() { return ExpressionType.LONG; } + + @Override + public int maxVectorSize() + { + return outputValues.length; + } }; } else if (Types.is(type, ExprType.DOUBLE)) { final ExprVectorProcessor input = expr.asVectorProcessor(inspector); @@ -466,6 +424,12 @@ public ExpressionType getOutputType() { return ExpressionType.LONG; } + + @Override + public int maxVectorSize() + { + return outputValues.length; + } }; } else { final ExprVectorProcessor input = expr.asVectorProcessor(inspector); @@ -493,131 +457,18 @@ public ExpressionType getOutputType() { return ExpressionType.LONG; } + + @Override + public int maxVectorSize() + { + return inspector.getMaxVectorSize(); + } }; } return (ExprVectorProcessor) processor; } - /** - * Creates an {@link ExprVectorProcessor} for the 'nvl' function, that will return the first argument value if it is - * not null, else the value of the 2nd argument. - * - * @see org.apache.druid.math.expr.Function.NvlFunc - */ - public static ExprVectorProcessor nvl(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) - { - final int maxVectorSize = inspector.getMaxVectorSize(); - - return makeSymmetricalProcessor( - inspector, - left, - right, - () -> new SymmetricalBivariateFunctionVectorProcessor( - ExpressionType.LONG, - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector) - ) - { - final long[] output = new long[maxVectorSize]; - final boolean[] outputNulls = new boolean[maxVectorSize]; - - @Override - public void processIndex( - long[] leftInput, - @Nullable boolean[] leftNulls, - long[] rightInput, - @Nullable boolean[] rightNulls, - int i - ) - { - if (leftNulls != null && leftNulls[i]) { - if (rightNulls != null) { - output[i] = rightNulls[i] ? 0L : rightInput[i]; - outputNulls[i] = rightNulls[i]; - } else { - output[i] = rightInput[i]; - outputNulls[i] = false; - } - } else { - output[i] = leftInput[i]; - outputNulls[i] = false; - } - } - - @Override - public ExprEvalVector asEval() - { - return new ExprEvalLongVector(output, outputNulls); - } - }, - () -> new SymmetricalBivariateFunctionVectorProcessor( - ExpressionType.DOUBLE, - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector) - ) - { - final double[] output = new double[maxVectorSize]; - final boolean[] outputNulls = new boolean[maxVectorSize]; - - @Override - public void processIndex( - double[] leftInput, - @Nullable boolean[] leftNulls, - double[] rightInput, - @Nullable boolean[] rightNulls, - int i - ) - { - if (leftNulls != null && leftNulls[i]) { - if (rightNulls != null) { - output[i] = rightNulls[i] ? 0.0 : rightInput[i]; - outputNulls[i] = rightNulls[i]; - } else { - output[i] = rightInput[i]; - outputNulls[i] = false; - } - } else { - output[i] = leftInput[i]; - outputNulls[i] = false; - } - } - - @Override - public ExprEvalVector asEval() - { - return new ExprEvalDoubleVector(output, outputNulls); - } - }, - () -> new SymmetricalBivariateFunctionVectorProcessor( - ExpressionType.STRING, - left.asVectorProcessor(inspector), - right.asVectorProcessor(inspector) - ) - { - final Object[] output = new Object[maxVectorSize]; - - @Override - public void processIndex( - Object[] leftInput, - @Nullable boolean[] leftNulls, - Object[] rightInput, - @Nullable boolean[] rightNulls, - int i - ) - { - output[i] = leftInput[i] != null ? leftInput[i] : rightInput[i]; - } - - @Override - public ExprEvalVector asEval() - { - return new ExprEvalObjectVector(output, getOutputType()); - } - } - ); - } - /** * Creates an {@link ExprVectorProcessor} for the logical 'not' operator, which produces a long typed vector output * with values set by the following rules: @@ -630,14 +481,9 @@ public ExprEvalVector asEval() public static ExprVectorProcessor not(Expr.VectorInputBindingInspector inspector, Expr expr) { final ExpressionType inputType = expr.getOutputType(inspector); - final int maxVectorSize = inspector.getMaxVectorSize(); ExprVectorProcessor processor = null; if (Types.is(inputType, ExprType.STRING)) { - processor = new LongOutObjectInFunctionVectorProcessor( - expr.asVectorProcessor(inspector), - maxVectorSize, - ExpressionType.STRING - ) + processor = new LongUnivariateObjectFunctionVectorProcessor(expr.asVectorProcessor(inspector), ExpressionType.STRING) { @Override public void processIndex(Object[] strings, long[] longs, boolean[] outputNulls, int i) @@ -649,33 +495,21 @@ public void processIndex(Object[] strings, long[] longs, boolean[] outputNulls, } }; } else if (Types.is(inputType, ExprType.LONG)) { - processor = new LongOutLongInFunctionVectorValueProcessor(expr.asVectorProcessor(inspector), maxVectorSize) - { - @Override - public long apply(long input) - { - return Evals.asLong(!Evals.asBoolean(input)); - } - }; + processor = new LongUnivariateLongFunctionVectorProcessor( + expr.asVectorProcessor(inspector), + (input) -> Evals.asLong(!Evals.asBoolean(input)) + ); } else if (Types.is(inputType, ExprType.DOUBLE)) { if (!ExpressionProcessing.useStrictBooleans()) { - processor = new DoubleOutDoubleInFunctionVectorValueProcessor(expr.asVectorProcessor(inspector), maxVectorSize) - { - @Override - public double apply(double input) - { - return Evals.asDouble(!Evals.asBoolean(input)); - } - }; + processor = new DoubleUnivariateDoubleFunctionVectorProcessor( + expr.asVectorProcessor(inspector), + input -> Evals.asDouble(!Evals.asBoolean(input)) + ); } else { - processor = new LongOutDoubleInFunctionVectorValueProcessor(expr.asVectorProcessor(inspector), maxVectorSize) - { - @Override - public long apply(double input) - { - return Evals.asLong(!Evals.asBoolean(input)); - } - }; + processor = new LongUnivariateDoubleFunctionVectorProcessor( + expr.asVectorProcessor(inspector), + input -> Evals.asLong(!Evals.asBoolean(input)) + ); } } if (processor == null) { @@ -1023,18 +857,57 @@ private VectorProcessors() // No instantiation } + static final class ConstantVectorProcessor implements ExprVectorProcessor + { + private final ExprEvalVector constantVector; + private final int maxVectorSize; + + ConstantVectorProcessor(ExprEvalVector constantVector, int maxVectorSize) + { + this.constantVector = constantVector; + this.maxVectorSize = maxVectorSize; + } + + @Override + public ExprEvalVector evalVector(Expr.VectorInputBinding bindings) + { + return constantVector; + } + + @Override + public ExpressionType getOutputType() + { + return constantVector.getType(); + } + + @Override + public int maxVectorSize() + { + return maxVectorSize; + } + } /** * Basic scaffolding for an 'identifier' {@link ExprVectorProcessor} * * @see #identifier */ - abstract static class IdentifierVectorProcessor implements ExprVectorProcessor + static final class IdentifierVectorProcessor implements ExprVectorProcessor { private final ExpressionType outputType; + private final String bindingName; + private final int maxVectorSize; - public IdentifierVectorProcessor(ExpressionType outputType) + public IdentifierVectorProcessor(ExpressionType outputType, String bindingName, int maxVectorSize) { this.outputType = outputType; + this.bindingName = bindingName; + this.maxVectorSize = maxVectorSize; + } + + @Override + public ExprEvalVector evalVector(Expr.VectorInputBinding bindings) + { + return new ExprEvalBindingVector<>(outputType, bindings, bindingName); } @Override @@ -1042,5 +915,11 @@ public ExpressionType getOutputType() { return outputType; } + + @Override + public int maxVectorSize() + { + return maxVectorSize; + } } } diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/VectorStringProcessors.java b/processing/src/main/java/org/apache/druid/math/expr/vector/VectorStringProcessors.java index 342c8fa7522f..2d0180092549 100644 --- a/processing/src/main/java/org/apache/druid/math/expr/vector/VectorStringProcessors.java +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/VectorStringProcessors.java @@ -33,10 +33,9 @@ public static ExprVectorProcessor concat(Expr.VectorInputBindingInspector { final ExprVectorProcessor processor; if (NullHandling.sqlCompatible()) { - processor = new ObjectOutObjectsInFunctionVectorProcessor( + processor = new ObjectBivariateObjectsFunctionVectorProcessor( left.asVectorProcessor(inspector), right.asVectorProcessor(inspector), - inspector.getMaxVectorSize(), ExpressionType.STRING ) { @@ -49,10 +48,9 @@ protected String processValue(@Nullable Object leftVal, @Nullable Object rightVa } }; } else { - processor = new ObjectOutObjectsInFunctionVectorProcessor( + processor = new ObjectBivariateObjectsFunctionVectorProcessor( left.asVectorProcessor(inspector), right.asVectorProcessor(inspector), - inspector.getMaxVectorSize(), ExpressionType.STRING ) { @@ -74,13 +72,11 @@ public static ExprVectorProcessor concat(Expr.VectorInputBindingInspector for (int i = 0; i < inputs.size(); i++) { inputProcessors[i] = CastToTypeVectorProcessor.cast( inputs.get(i).asVectorProcessor(inspector), - ExpressionType.STRING, - inspector.getMaxVectorSize() + ExpressionType.STRING ); } - final ExprVectorProcessor processor = new ObjectOutMultiObjectInVectorProcessor( + final ExprVectorProcessor processor = new ObjectMultivariateObjectsFunctionVectorProcessor( inputProcessors, - inspector.getMaxVectorSize(), ExpressionType.STRING ) { diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/functional/ComparatorFunction.java b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/ComparatorFunction.java new file mode 100644 index 000000000000..6a688884e606 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/ComparatorFunction.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector.functional; + +@FunctionalInterface +public interface ComparatorFunction +{ + boolean compare(int compareResult); +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/functional/DoubleBivariateDoubleLongFunction.java b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/DoubleBivariateDoubleLongFunction.java new file mode 100644 index 000000000000..a5bfef620582 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/DoubleBivariateDoubleLongFunction.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector.functional; + +@FunctionalInterface +public interface DoubleBivariateDoubleLongFunction +{ + double process(double left, long right); +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/functional/DoubleBivariateDoublesFunction.java b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/DoubleBivariateDoublesFunction.java new file mode 100644 index 000000000000..cd89ac5b20fa --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/DoubleBivariateDoublesFunction.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector.functional; + +@FunctionalInterface +public interface DoubleBivariateDoublesFunction +{ + double process(double left, double right); +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/functional/DoubleBivariateLongDoubleFunction.java b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/DoubleBivariateLongDoubleFunction.java new file mode 100644 index 000000000000..6983f1633216 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/DoubleBivariateLongDoubleFunction.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector.functional; + +@FunctionalInterface +public interface DoubleBivariateLongDoubleFunction +{ + double process(long left, double right); +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/functional/DoubleBivariateLongsFunction.java b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/DoubleBivariateLongsFunction.java new file mode 100644 index 000000000000..b1724cc67cf8 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/DoubleBivariateLongsFunction.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector.functional; + +@FunctionalInterface +public interface DoubleBivariateLongsFunction +{ + double process(long left, long right); +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/functional/DoubleUnivariateDoubleFunction.java b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/DoubleUnivariateDoubleFunction.java new file mode 100644 index 000000000000..81a46d024708 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/DoubleUnivariateDoubleFunction.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector.functional; + +@FunctionalInterface +public interface DoubleUnivariateDoubleFunction +{ + double process(double input); +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/functional/DoubleUnivariateLongFunction.java b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/DoubleUnivariateLongFunction.java new file mode 100644 index 000000000000..cd7b7b191e09 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/DoubleUnivariateLongFunction.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector.functional; + +@FunctionalInterface +public interface DoubleUnivariateLongFunction +{ + double process(long input); +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/functional/LongBivariateDoubleLongFunction.java b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/LongBivariateDoubleLongFunction.java new file mode 100644 index 000000000000..cba7a45f1966 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/LongBivariateDoubleLongFunction.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector.functional; + +@FunctionalInterface +public interface LongBivariateDoubleLongFunction +{ + long process(double left, long right); +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/functional/LongBivariateDoublesFunction.java b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/LongBivariateDoublesFunction.java new file mode 100644 index 000000000000..ddd31efc34e4 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/LongBivariateDoublesFunction.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector.functional; + +@FunctionalInterface +public interface LongBivariateDoublesFunction +{ + long process(double left, double right); +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/functional/LongBivariateLongDoubleFunction.java b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/LongBivariateLongDoubleFunction.java new file mode 100644 index 000000000000..0847d2a08a3f --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/LongBivariateLongDoubleFunction.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector.functional; + +@FunctionalInterface +public interface LongBivariateLongDoubleFunction +{ + long process(long left, double right); +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/functional/LongBivariateLongsFunction.java b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/LongBivariateLongsFunction.java new file mode 100644 index 000000000000..7536176fbcc3 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/LongBivariateLongsFunction.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector.functional; + +@FunctionalInterface +public interface LongBivariateLongsFunction +{ + long process(long left, long right); +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/functional/LongBivariateObjectsFunction.java b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/LongBivariateObjectsFunction.java new file mode 100644 index 000000000000..b1435fc12b0c --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/LongBivariateObjectsFunction.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector.functional; + +import javax.annotation.Nullable; + +@FunctionalInterface +public interface LongBivariateObjectsFunction +{ + @Nullable + Long process(@Nullable Object left, @Nullable Object right); +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/functional/LongUnivariateDoubleFunction.java b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/LongUnivariateDoubleFunction.java new file mode 100644 index 000000000000..32baf0555aad --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/LongUnivariateDoubleFunction.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector.functional; + +@FunctionalInterface +public interface LongUnivariateDoubleFunction +{ + long process(double input); +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/functional/LongUnivariateLongFunction.java b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/LongUnivariateLongFunction.java new file mode 100644 index 000000000000..70d53fc7b247 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/LongUnivariateLongFunction.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector.functional; + +@FunctionalInterface +public interface LongUnivariateLongFunction +{ + long process(long input); +} diff --git a/processing/src/main/java/org/apache/druid/math/expr/vector/functional/ObjectBivariateObjectsFunction.java b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/ObjectBivariateObjectsFunction.java new file mode 100644 index 000000000000..03b0beedcdbb --- /dev/null +++ b/processing/src/main/java/org/apache/druid/math/expr/vector/functional/ObjectBivariateObjectsFunction.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector.functional; + +import javax.annotation.Nullable; + +@FunctionalInterface +public interface ObjectBivariateObjectsFunction +{ + @Nullable + Object process(@Nullable Object left, @Nullable Object right); +} diff --git a/processing/src/main/java/org/apache/druid/query/expression/TimestampFloorExprMacro.java b/processing/src/main/java/org/apache/druid/query/expression/TimestampFloorExprMacro.java index b2f8f7b82bbd..e71412c6ddac 100644 --- a/processing/src/main/java/org/apache/druid/query/expression/TimestampFloorExprMacro.java +++ b/processing/src/main/java/org/apache/druid/query/expression/TimestampFloorExprMacro.java @@ -27,7 +27,7 @@ import org.apache.druid.math.expr.InputBindings; import org.apache.druid.math.expr.vector.CastToTypeVectorProcessor; import org.apache.druid.math.expr.vector.ExprVectorProcessor; -import org.apache.druid.math.expr.vector.LongOutLongInFunctionVectorValueProcessor; +import org.apache.druid.math.expr.vector.LongUnivariateLongFunctionVectorProcessor; import org.apache.druid.segment.column.ColumnHolder; import org.joda.time.Period; @@ -132,18 +132,10 @@ public boolean canVectorize(InputBindingInspector inspector) @Override public ExprVectorProcessor asVectorProcessor(VectorInputBindingInspector inspector) { - ExprVectorProcessor processor; - processor = new LongOutLongInFunctionVectorValueProcessor( - CastToTypeVectorProcessor.cast(args.get(0).asVectorProcessor(inspector), ExpressionType.LONG, inspector.getMaxVectorSize()), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long input) - { - return granularity.bucketStart(input); - } - }; + final ExprVectorProcessor processor = new LongUnivariateLongFunctionVectorProcessor( + CastToTypeVectorProcessor.cast(args.get(0).asVectorProcessor(inspector), ExpressionType.LONG), + granularity::bucketStart + ); return (ExprVectorProcessor) processor; } diff --git a/processing/src/main/java/org/apache/druid/query/expression/TimestampShiftExprMacro.java b/processing/src/main/java/org/apache/druid/query/expression/TimestampShiftExprMacro.java index 99bf23cc15d8..3e2535d787f0 100644 --- a/processing/src/main/java/org/apache/druid/query/expression/TimestampShiftExprMacro.java +++ b/processing/src/main/java/org/apache/druid/query/expression/TimestampShiftExprMacro.java @@ -27,7 +27,7 @@ import org.apache.druid.math.expr.InputBindings; import org.apache.druid.math.expr.vector.CastToTypeVectorProcessor; import org.apache.druid.math.expr.vector.ExprVectorProcessor; -import org.apache.druid.math.expr.vector.LongOutLongInFunctionVectorValueProcessor; +import org.apache.druid.math.expr.vector.LongUnivariateLongFunctionVectorProcessor; import org.joda.time.Chronology; import org.joda.time.Period; import org.joda.time.chrono.ISOChronology; @@ -115,22 +115,10 @@ public boolean canVectorize(InputBindingInspector inspector) @Override public ExprVectorProcessor asVectorProcessor(VectorInputBindingInspector inspector) { - ExprVectorProcessor processor; - processor = new LongOutLongInFunctionVectorValueProcessor( - CastToTypeVectorProcessor.cast( - args.get(0).asVectorProcessor(inspector), - ExpressionType.LONG, - inspector.getMaxVectorSize() - ), - inspector.getMaxVectorSize() - ) - { - @Override - public long apply(long input) - { - return chronology.add(period, input, step); - } - }; + final ExprVectorProcessor processor = new LongUnivariateLongFunctionVectorProcessor( + CastToTypeVectorProcessor.cast(args.get(0).asVectorProcessor(inspector), ExpressionType.LONG), + input -> chronology.add(period, input, step) + ); return (ExprVectorProcessor) processor; } diff --git a/processing/src/main/java/org/apache/druid/segment/column/NullableTypeStrategy.java b/processing/src/main/java/org/apache/druid/segment/column/NullableTypeStrategy.java index b6d5114fb0a1..db6192669864 100644 --- a/processing/src/main/java/org/apache/druid/segment/column/NullableTypeStrategy.java +++ b/processing/src/main/java/org/apache/druid/segment/column/NullableTypeStrategy.java @@ -133,7 +133,7 @@ public int write(ByteBuffer buffer, int offset, @Nullable T value, int maxSizeBy } @Override - public int compare(T o1, T o2) + public int compare(@Nullable T o1, @Nullable T o2) { return delegateComparator.compare(o1, o2); } diff --git a/processing/src/main/java/org/apache/druid/segment/virtual/ExpressionVectorSelectors.java b/processing/src/main/java/org/apache/druid/segment/virtual/ExpressionVectorSelectors.java index c0776a2356c5..9c1d6c2c941c 100644 --- a/processing/src/main/java/org/apache/druid/segment/virtual/ExpressionVectorSelectors.java +++ b/processing/src/main/java/org/apache/druid/segment/virtual/ExpressionVectorSelectors.java @@ -184,8 +184,7 @@ public static VectorObjectSelector castValueSelectorToObject( return new ExpressionVectorObjectSelector( CastToTypeVectorProcessor.cast( VectorProcessors.identifier(binding, columnName), - ExpressionType.fromColumnType(castTo), - binding.getMaxVectorSize() + ExpressionType.fromColumnType(castTo) ), binding ); @@ -205,8 +204,7 @@ public static VectorValueSelector castObjectSelectorToNumeric( return new ExpressionVectorValueSelector( CastToTypeVectorProcessor.cast( VectorProcessors.identifier(binding, columnName), - ExpressionType.fromColumnType(castTo), - binding.getMaxVectorSize() + ExpressionType.fromColumnType(castTo) ), binding ); diff --git a/processing/src/main/java/org/apache/druid/segment/virtual/SingleStringInputDeferredEvaluationExpressionDimensionVectorSelector.java b/processing/src/main/java/org/apache/druid/segment/virtual/SingleStringInputDeferredEvaluationExpressionDimensionVectorSelector.java index 5a1dd4955069..b1c896cf8bd0 100644 --- a/processing/src/main/java/org/apache/druid/segment/virtual/SingleStringInputDeferredEvaluationExpressionDimensionVectorSelector.java +++ b/processing/src/main/java/org/apache/druid/segment/virtual/SingleStringInputDeferredEvaluationExpressionDimensionVectorSelector.java @@ -147,9 +147,9 @@ public int getCurrentVectorId() } @Override - public T[] getObjectVector(String name) + public Object[] getObjectVector(String name) { - return (T[]) currentValue; + return currentValue; } @Override diff --git a/processing/src/test/java/org/apache/druid/math/expr/VectorExprSanityTest.java b/processing/src/test/java/org/apache/druid/math/expr/VectorExprSanityTest.java index 2da11bb4e29c..281e63a04295 100644 --- a/processing/src/test/java/org/apache/druid/math/expr/VectorExprSanityTest.java +++ b/processing/src/test/java/org/apache/druid/math/expr/VectorExprSanityTest.java @@ -578,7 +578,7 @@ static String[][] makeTemplateArgs(String[] arg1, String[] arg2, String[] arg3) .toArray(String[][]::new); } - static class SettableVectorInputBinding implements Expr.VectorInputBinding + public static class SettableVectorInputBinding implements Expr.VectorInputBinding { private final Map nulls; private final Map longs; @@ -590,7 +590,7 @@ static class SettableVectorInputBinding implements Expr.VectorInputBinding private int id = 0; - SettableVectorInputBinding(int vectorSize) + public SettableVectorInputBinding(int vectorSize) { this.nulls = new HashMap<>(); this.longs = new HashMap<>(); @@ -616,6 +616,7 @@ public SettableVectorInputBinding addLong(String name, long[] longs, boolean[] n { assert longs.length == vectorSize; this.longs.put(name, longs); + this.doubles.put(name, Arrays.stream(longs).asDoubleStream().toArray()); return addBinding(name, ExpressionType.LONG, nulls); } @@ -628,10 +629,11 @@ public SettableVectorInputBinding addDouble(String name, double[] doubles, boole { assert doubles.length == vectorSize; this.doubles.put(name, doubles); + this.longs.put(name, Arrays.stream(doubles).mapToLong(x -> (long) x).toArray()); return addBinding(name, ExpressionType.DOUBLE, nulls); } - public SettableVectorInputBinding addString(String name, String[] strings) + public SettableVectorInputBinding addString(String name, Object[] strings) { assert strings.length == vectorSize; this.objects.put(name, strings); @@ -639,9 +641,9 @@ public SettableVectorInputBinding addString(String name, String[] strings) } @Override - public T[] getObjectVector(String name) + public Object[] getObjectVector(String name) { - return (T[]) objects.getOrDefault(name, new Object[getCurrentVectorSize()]); + return objects.getOrDefault(name, new Object[getCurrentVectorSize()]); } @Override diff --git a/processing/src/test/java/org/apache/druid/math/expr/vector/FilteredVectorInputBindingTest.java b/processing/src/test/java/org/apache/druid/math/expr/vector/FilteredVectorInputBindingTest.java new file mode 100644 index 000000000000..00f23677db38 --- /dev/null +++ b/processing/src/test/java/org/apache/druid/math/expr/vector/FilteredVectorInputBindingTest.java @@ -0,0 +1,216 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.math.expr.vector; + +import org.apache.druid.math.expr.VectorExprSanityTest; +import org.apache.druid.query.filter.vector.VectorMatch; +import org.apache.druid.testing.InitializedNullHandlingTest; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class FilteredVectorInputBindingTest extends InitializedNullHandlingTest +{ + private static final int VECTOR_SIZE = 8; + private static final Object[] STRINGS = new Object[]{ + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7" + }; + private static final long[] LONGS = new long[]{ + 0L, + 1L, + 2L, + 3L, + 4L, + 5L, + 6L, + 7L + }; + + private static final double[] DOUBLES = new double[]{ + 0.0, + 1.1, + 2.2, + 3.3, + 4.4, + 5.5, + 6.6, + 7.7 + }; + + private static final boolean[] NULLS = new boolean[]{ + false, + false, + false, + true, + false, + false, + true, + false + }; + + private VectorExprSanityTest.SettableVectorInputBinding baseBinding; + + @Before + public void setup() + { + baseBinding = new VectorExprSanityTest.SettableVectorInputBinding(VECTOR_SIZE); + baseBinding.addString("string", STRINGS); + baseBinding.addLong("long", LONGS, NULLS); + baseBinding.addDouble("double", DOUBLES); + } + @Test + public void testFilterString() + { + FilteredVectorInputBinding filteredVectorInputBinding = new FilteredVectorInputBinding(VECTOR_SIZE); + filteredVectorInputBinding.setBindings(baseBinding); + VectorMatch matchMaker = filteredVectorInputBinding.getVectorMatch(); + int[] selection = matchMaker.getSelection(); + selection[0] = 1; + selection[1] = 3; + selection[2] = 4; + matchMaker.setSelectionSize(3); + + final Object[] strings = filteredVectorInputBinding.getObjectVector("string"); + Assert.assertEquals(3, filteredVectorInputBinding.getCurrentVectorSize()); + Assert.assertEquals("1", strings[0]); + Assert.assertEquals("3", strings[1]); + Assert.assertEquals("4", strings[2]); + } + + @Test + public void testFilterLongWithNull() + { + FilteredVectorInputBinding filteredVectorInputBinding = new FilteredVectorInputBinding(VECTOR_SIZE); + filteredVectorInputBinding.setBindings(baseBinding); + VectorMatch matchMaker = filteredVectorInputBinding.getVectorMatch(); + int[] selection = matchMaker.getSelection(); + selection[0] = 1; + selection[1] = 3; + selection[2] = 4; + matchMaker.setSelectionSize(3); + + long[] longs = filteredVectorInputBinding.getLongVector("long"); + boolean[] nulls = filteredVectorInputBinding.getNullVector("long"); + Assert.assertEquals(3, filteredVectorInputBinding.getCurrentVectorSize()); + Assert.assertNotNull(nulls); + Assert.assertEquals(1L, longs[0]); + Assert.assertEquals(3L, longs[1]); + Assert.assertEquals(4L, longs[2]); + Assert.assertFalse(nulls[0]); + Assert.assertTrue(nulls[1]); + Assert.assertFalse(nulls[2]); + + selection[0] = 0; + selection[1] = 2; + selection[2] = 5; + selection[3] = 6; + selection[4] = 7; + matchMaker.setSelectionSize(5); + + longs = filteredVectorInputBinding.getLongVector("long"); + nulls = filteredVectorInputBinding.getNullVector("long"); + Assert.assertEquals(5, filteredVectorInputBinding.getCurrentVectorSize()); + Assert.assertNotNull(nulls); + Assert.assertEquals(0L, longs[0]); + Assert.assertEquals(2L, longs[1]); + Assert.assertEquals(5L, longs[2]); + Assert.assertEquals(6L, longs[3]); + Assert.assertEquals(7L, longs[4]); + Assert.assertFalse(nulls[0]); + Assert.assertFalse(nulls[1]); + Assert.assertFalse(nulls[2]); + Assert.assertTrue(nulls[3]); + Assert.assertFalse(nulls[4]); + + + selection[0] = 1; + selection[1] = 3; + selection[2] = 4; + matchMaker.setSelectionSize(3); + + longs = filteredVectorInputBinding.getLongVector("long"); + nulls = filteredVectorInputBinding.getNullVector("long"); + Assert.assertEquals(3, filteredVectorInputBinding.getCurrentVectorSize()); + Assert.assertNotNull(nulls); + Assert.assertEquals(1L, longs[0]); + Assert.assertEquals(3L, longs[1]); + Assert.assertEquals(4L, longs[2]); + Assert.assertFalse(nulls[0]); + Assert.assertTrue(nulls[1]); + Assert.assertFalse(nulls[2]); + } + + @Test + public void testDoubles() + { + FilteredVectorInputBinding filteredVectorInputBinding = new FilteredVectorInputBinding(VECTOR_SIZE); + filteredVectorInputBinding.setBindings(baseBinding); + VectorMatch matchMaker = filteredVectorInputBinding.getVectorMatch(); + int[] selection = matchMaker.getSelection(); + selection[0] = 1; + selection[1] = 3; + selection[2] = 4; + matchMaker.setSelectionSize(3); + + double[] doubles = filteredVectorInputBinding.getDoubleVector("double"); + boolean[] nulls = filteredVectorInputBinding.getNullVector("double"); + Assert.assertEquals(3, filteredVectorInputBinding.getCurrentVectorSize()); + Assert.assertEquals(1.1, doubles[0], 0.0); + Assert.assertEquals(3.3, doubles[1], 0.0); + Assert.assertEquals(4.4, doubles[2], 0.0); + + selection[0] = 0; + selection[1] = 2; + selection[2] = 5; + selection[3] = 6; + selection[4] = 7; + matchMaker.setSelectionSize(5); + + doubles = filteredVectorInputBinding.getDoubleVector("double"); + nulls = filteredVectorInputBinding.getNullVector("double"); + Assert.assertEquals(5, filteredVectorInputBinding.getCurrentVectorSize()); + + Assert.assertEquals(0.0, doubles[0], 0.0); + Assert.assertEquals(2.2, doubles[1], 0.0); + Assert.assertEquals(5.5, doubles[2], 0.0); + Assert.assertEquals(6.6, doubles[3], 0.0); + Assert.assertEquals(7.7, doubles[4], 0.0); + + selection[0] = 1; + selection[1] = 3; + selection[2] = 4; + matchMaker.setSelectionSize(3); + + doubles = filteredVectorInputBinding.getDoubleVector("double"); + nulls = filteredVectorInputBinding.getNullVector("double"); + Assert.assertEquals(3, filteredVectorInputBinding.getCurrentVectorSize()); + + Assert.assertEquals(1.1, doubles[0], 0.0); + Assert.assertEquals(3.3, doubles[1], 0.0); + Assert.assertEquals(4.4, doubles[2], 0.0); + } +}