public static Object aggregation(InternalAggregationFunction function, Page... pages) { // execute with args in positions: arg0, arg1, arg2 Object aggregation = aggregation(function, createArgs(function), Optional.empty(), pages); // execute with args in reverse order: arg2, arg1, arg0 if (function.getParameterTypes().size() > 1) { Object aggregationWithOffset = aggregation(function, reverseArgs(function), Optional.empty(), reverseColumns(pages)); assertEquals(aggregationWithOffset, aggregation, "Inconsistent results with reversed channels"); } // execute with args at an offset (and possibly reversed): null, null, null, arg2, arg1, arg0 Object aggregationWithOffset = aggregation(function, offsetArgs(function, 3), Optional.empty(), offsetColumns(pages, 3)); assertEquals(aggregationWithOffset, aggregation, "Inconsistent results with channel offset"); return aggregation; }
private void testAggregationReal(InternalAggregationFunction function, Page page, double maxError, float... inputs) { assertAggregation(function, QDIGEST_EQUALITY, "test multiple positions", page, getExpectedValuesFloats(maxError, inputs)); // test scalars List<Double> rows = Floats.asList(inputs).stream().sorted().map(Float::doubleValue).collect(Collectors.toList()); SqlVarbinary returned = (SqlVarbinary) AggregationTestUtils.aggregation(function, page); assertPercentileWithinError(StandardTypes.REAL, returned, maxError, rows, 0.1, 0.5, 0.9, 0.99); }
private long estimateCount(List<?> values, double maxStandardError) { Object result = AggregationTestUtils.aggregation(getAggregationFunction(), createPage(values, maxStandardError)); return (long) result; }
public static Object distinctAggregation(InternalAggregationFunction function, Page... pages) { Optional<Integer> maskChannel = Optional.of(pages[0].getChannelCount()); // Execute normally Object aggregation = aggregation(function, createArgs(function), maskChannel, maskPages(true, pages)); Page[] dupedPages = new Page[pages.length * 2]; // Create two copies of each page with one of them masked off System.arraycopy(maskPages(true, pages), 0, dupedPages, 0, pages.length); System.arraycopy(maskPages(false, pages), 0, dupedPages, pages.length, pages.length); // Execute with masked pages and assure equal to normal execution Object aggregationWithDupes = aggregation(function, createArgs(function), maskChannel, dupedPages); assertEquals(aggregationWithDupes, aggregation, "Inconsistent results with mask"); return aggregation; }
private void testAggregationDoubles(InternalAggregationFunction function, Page page, double maxError, double... inputs) { assertAggregation(function, QDIGEST_EQUALITY, "test multiple positions", page, getExpectedValueDoubles(maxError, inputs)); // test scalars List<Double> rows = Arrays.stream(inputs).sorted().boxed().collect(Collectors.toList()); SqlVarbinary returned = (SqlVarbinary) AggregationTestUtils.aggregation(function, page); assertPercentileWithinError(StandardTypes.DOUBLE, returned, maxError, rows, 0.1, 0.5, 0.9, 0.99); }
private void testAggregationBigints(InternalAggregationFunction function, Page page, double maxError, long... inputs) { // aggregate level assertAggregation(function, QDIGEST_EQUALITY, "test multiple positions", page, getExpectedValueLongs(maxError, inputs)); // test scalars List<Long> rows = Arrays.stream(inputs).sorted().boxed().collect(Collectors.toList()); SqlVarbinary returned = (SqlVarbinary) AggregationTestUtils.aggregation(function, page); assertPercentileWithinError(StandardTypes.BIGINT, returned, maxError, rows, 0.1, 0.5, 0.9, 0.99); }
private static void assertAggregationInternal(InternalAggregationFunction function, BiFunction<Object, Object, Boolean> isEqual, String testDescription, Object expectedValue, Page... pages) { // This assertAggregation does not try to split up the page to test the correctness of combine function. // Do not use this directly. Always use the other assertAggregation. assertFunctionEquals(isEqual, testDescription, aggregation(function, pages), expectedValue); assertFunctionEquals(isEqual, testDescription, partialAggregation(function, pages), expectedValue); if (pages.length > 0) { assertFunctionEquals(isEqual, testDescription, groupedAggregation(isEqual, function, pages), expectedValue); assertFunctionEquals(isEqual, testDescription, groupedPartialAggregation(isEqual, function, pages), expectedValue); assertFunctionEquals(isEqual, testDescription, distinctAggregation(function, pages), expectedValue); } }
public static Object aggregation(InternalAggregationFunction function, double confidence, Page... pages) { // execute with args in positions: arg0, arg1, arg2 Object aggregation = aggregation(function, createArgs(function), Optional.empty(), confidence, pages); // execute with args in reverse order: arg2, arg1, arg0 if (function.getParameterTypes().size() > 1) { Object aggregationWithOffset = aggregation(function, reverseArgs(function), Optional.empty(), confidence, reverseColumns(pages)); assertEquals(aggregationWithOffset, aggregation, "Inconsistent results with reversed channels"); } // execute with args at an offset (and possibly reversed): null, null, null, arg2, arg1, arg0 Object aggregationWithOffset = aggregation(function, offsetArgs(function, 3), Optional.empty(), confidence, offsetColumns(pages, 3)); assertEquals(aggregationWithOffset, aggregation, "Inconsistent results with channel offset"); return aggregation; }
private long estimateCount(List<Object> values, double maxStandardError) { Object result = AggregationTestUtils.aggregation(getAggregationFunction(), 1.0, createPage(values, maxStandardError)); return (long) result; }
public static Object distinctAggregation(InternalAggregationFunction function, double confidence, Page... pages) { Optional<Integer> maskChannel = Optional.of(pages[0].getChannelCount()); // Execute normally Object aggregation = aggregation(function, createArgs(function), maskChannel, confidence, maskPages(true, pages)); Page[] dupedPages = new Page[pages.length * 2]; // Create two copies of each page with one of them masked off System.arraycopy(maskPages(true, pages), 0, dupedPages, 0, pages.length); System.arraycopy(maskPages(false, pages), 0, dupedPages, pages.length, pages.length); // Execute with masked pages and assure equal to normal execution Object aggregationWithDupes = aggregation(function, createArgs(function), maskChannel, confidence, dupedPages); assertEquals(aggregationWithDupes, aggregation, "Inconsistent results with mask"); return aggregation; }
private static void assertAggregation(InternalAggregationFunction function, double confidence, Object expectedValue, Page... pages) { BiConsumer<Object, Object> equalAssertion = (actual, expected) -> { assertEquals(actual, expected); }; if (isFloatingNumber(expectedValue) && !isNan(expectedValue)) { equalAssertion = (actual, expected) -> { assertEquals((double) actual, (double) expected, 1e-10); }; } // This assertAggregation does not try to split up the page to test the correctness of combine function. // Do not use this directly. Always use the other assertAggregation. equalAssertion.accept(aggregation(function, confidence, pages), expectedValue); equalAssertion.accept(partialAggregation(function, confidence, pages), expectedValue); if (pages.length > 0) { equalAssertion.accept(groupedAggregation(function, confidence, pages), expectedValue); equalAssertion.accept(groupedPartialAggregation(function, confidence, pages), expectedValue); equalAssertion.accept(distinctAggregation(function, confidence, pages), expectedValue); } }