Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Licensed 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 com.facebook.presto.operator.aggregation;
 
 
 import java.util.List;
 
 import static com.facebook.presto.spi.type.BigintType.BIGINT;
 import static com.facebook.presto.spi.type.BooleanType.BOOLEAN;
 import static com.facebook.presto.spi.type.DoubleType.DOUBLE;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
 
 public final class AggregationTestUtils
 {
     private AggregationTestUtils()
     {
     }
 
     public static void assertAggregation(InternalAggregationFunction functiondouble confidenceObject expectedValueint positionsBlock... blocks)
     {
         if (positions == 0) {
             assertAggregation(functionconfidenceexpectedValue);
         }
         else {
             assertAggregation(functionconfidenceexpectedValuenew Page(positionsblocks));
         }
     }
 
     public static void assertApproximateAggregation(InternalAggregationFunction functionint sampleWeightChanneldouble confidenceDouble expectedValuePage... pages)
     {
         assertTrue(approximateAggregationWithinErrorBound(functionsampleWeightChannelconfidenceexpectedValuepages));
         assertTrue(partialApproximateAggregationWithinErrorBound(functionsampleWeightChannelconfidenceexpectedValuepages));
         assertTrue(groupedApproximateAggregationWithinErrorBound(functionsampleWeightChannelconfidenceexpectedValuepages));
     }
 
     public static boolean approximateAggregationWithinErrorBound(InternalAggregationFunction functionint sampleWeightChanneldouble confidenceDouble expectedValuePage... pages)
     {
         Accumulator accumulator = function.bind(ImmutableList.of(0), Optional.empty(), Optional.of(sampleWeightChannel), confidence).createAccumulator();
         for (Page page : pages) {
             accumulator.addInput(page);
         }
         Block result = getFinalBlock(accumulator);
 
         if (expectedValue == null) {
             return BlockAssertions.toValues(function.getFinalType(), result).get(0) == null;
         }
 
         return withinErrorBound(BlockAssertions.toValues(function.getFinalType(), result).get(0).toString(), expectedValue);
     }
 
     public static Block getIntermediateBlock(Accumulator accumulator)
     {
         BlockBuilder blockBuilder = accumulator.getIntermediateType().createBlockBuilder(new BlockBuilderStatus(), 1000);
         accumulator.evaluateIntermediate(blockBuilder);
         return blockBuilder.build();
     }
 
     public static Block getFinalBlock(Accumulator accumulator)
     {
         BlockBuilder blockBuilder = accumulator.getFinalType().createBlockBuilder(new BlockBuilderStatus(), 1000);
         accumulator.evaluateFinal(blockBuilder);
         return blockBuilder.build();
     }
 
     public static boolean partialApproximateAggregationWithinErrorBound(InternalAggregationFunction functionint sampleWeightChanneldouble confidenceDouble expectedValuePage... pages)
     {
         AccumulatorFactory factory = function.bind(ImmutableList.of(0), Optional.empty(), Optional.of(sampleWeightChannel), confidence);
         Accumulator partialAccumulator = factory.createAccumulator();
         for (Page page : pages) {
             if (page.getPositionCount() > 0) {
                 partialAccumulator.addInput(page);
             }
         }
        Block partialBlock = getIntermediateBlock(partialAccumulator);
        Accumulator finalAggregation = factory.createIntermediateAccumulator();
        finalAggregation.addIntermediate(partialBlock);
        Block finalBlock = getFinalBlock(finalAggregation);
        if (expectedValue == null) {
            return BlockAssertions.toValues(function.getFinalType(), finalBlock).get(0) == null;
        }
        return withinErrorBound(BlockAssertions.toValues(function.getFinalType(), finalBlock).get(0).toString(), expectedValue);
    }
    public static boolean groupedApproximateAggregationWithinErrorBound(InternalAggregationFunction functionint sampleWeightChanneldouble confidenceDouble expectedValuePage... pages)
    {
        GroupedAccumulator groupedAggregation = function.bind(ImmutableList.of(0), Optional.empty(), Optional.of(sampleWeightChannel), confidence).createGroupedAccumulator();
        for (Page page : pages) {
            groupedAggregation.addInput(createGroupByIdBlock(0, page.getPositionCount()), page);
        }
        Object groupValue = getGroupValue(groupedAggregation, 0);
        if (expectedValue == null) {
            return groupValue == null;
        }
        return withinErrorBound(groupValue.toString(), expectedValue);
    }
    private static boolean withinErrorBound(String approximateValuedouble expected)
    {
        List<Stringparts = Splitter.on(' ').splitToList(approximateValue);
        double actual = Double.parseDouble(parts.get(0));
        double error = Double.parseDouble(parts.get(2));
        return Math.abs(expected - actual) <= error && !Double.isInfinite(error);
    }
    public static void assertAggregation(InternalAggregationFunction functiondouble confidenceObject expectedValuePage... pages)
    {
        assertEquals(aggregation(functionconfidencepages), expectedValue);
        assertEquals(partialAggregation(functionconfidencepages), expectedValue);
        if (pages.length > 0) {
            assertEquals(groupedAggregation(functionconfidencepages), expectedValue);
            assertEquals(groupedPartialAggregation(functionconfidencepages), expectedValue);
            assertEquals(distinctAggregation(functionconfidencepages), expectedValue);
        }
    }
    public static Object distinctAggregation(InternalAggregationFunction functiondouble confidencePage... pages)
    {
        Optional<IntegermaskChannel = Optional.of(pages[0].getChannelCount());
        // Execute normally
        Object aggregation = aggregation(functioncreateArgs(function), maskChannelconfidencemaskPages(truepages));
        Page[] dupedPages = new Page[pages.length * 2];
        // Create two copies of each page with one of them masked off
        System.arraycopy(maskPages(truepages), 0, dupedPages, 0, pages.length);
        System.arraycopy(maskPages(falsepages), 0, dupedPagespages.lengthpages.length);
        // Execute with masked pages and assure equal to normal execution
        Object aggregationWithDupes = aggregation(functioncreateArgs(function), maskChannelconfidencedupedPages);
        assertEquals(aggregationWithDupesaggregation"Inconsistent results with mask");
        return aggregation;
    }
    // Adds the mask as the last channel
    private static Page[] maskPages(boolean maskValuePage... pages)
    {
        Page[] maskedPages = new Page[pages.length];
        for (int i = 0; i < pages.lengthi++) {
            Page page = pages[i];
            BlockBuilder blockBuilder = .createBlockBuilder(new BlockBuilderStatus(), page.getPositionCount());
            for (int j = 0; j < page.getPositionCount(); j++) {
                .writeBoolean(blockBuildermaskValue);
            }
            Block[] sourceBlocks = page.getBlocks();
            Block[] outputBlocks = new Block[sourceBlocks.length + 1]; // +1 for the single boolean output channel
            System.arraycopy(sourceBlocks, 0, outputBlocks, 0, sourceBlocks.length);
            outputBlocks[sourceBlocks.length] = blockBuilder.build();
            maskedPages[i] = new Page(outputBlocks);
        }
        return maskedPages;
    }
    public static Object aggregation(InternalAggregationFunction functiondouble confidencePage... pages)
    {
        // execute with args in positions: arg0, arg1, arg2
        Object aggregation = aggregation(functioncreateArgs(function), Optional.empty(), confidencepages);
        // execute with args in reverse order: arg2, arg1, arg0
        if (function.getParameterTypes().size() > 1) {
            Object aggregationWithOffset = aggregation(functionreverseArgs(function), Optional.empty(), confidencereverseColumns(pages));
            assertEquals(aggregationWithOffsetaggregation"Inconsistent results with reversed channels");
        }
        // execute with args at an offset (and possibly reversed): null, null, null, arg2, arg1, arg0
        Object aggregationWithOffset = aggregation(functionoffsetArgs(function, 3), Optional.empty(), confidenceoffsetColumns(pages, 3));
        assertEquals(aggregationWithOffsetaggregation"Inconsistent results with channel offset");
        return aggregation;
    }
    private static Object aggregation(InternalAggregationFunction functionint[] argsOptional<IntegermaskChanneldouble confidencePage... pages)
    {
        Accumulator aggregation = function.bind(Ints.asList(args), maskChannel, Optional.empty(), confidence).createAccumulator();
        for (Page page : pages) {
            if (page.getPositionCount() > 0) {
                aggregation.addInput(page);
            }
        }
        Block block = getFinalBlock(aggregation);
        return BlockAssertions.getOnlyValue(aggregation.getFinalType(), block);
    }
    public static Object partialAggregation(InternalAggregationFunction functiondouble confidencePage... pages)
    {
        // execute with args in positions: arg0, arg1, arg2
        Object aggregation = partialAggregation(functionconfidencecreateArgs(function), pages);
        // execute with args in reverse order: arg2, arg1, arg0
        if (function.getParameterTypes().size() > 1) {
            Object aggregationWithOffset = partialAggregation(functionconfidencereverseArgs(function), reverseColumns(pages));
            assertEquals(aggregationWithOffsetaggregation"Inconsistent results with reversed channels");
        }
        // execute with args at an offset (and possibly reversed): null, null, null, arg2, arg1, arg0
        Object aggregationWithOffset = partialAggregation(functionconfidenceoffsetArgs(function, 3), offsetColumns(pages, 3));
        assertEquals(aggregationWithOffsetaggregation"Inconsistent results with channel offset");
        return aggregation;
    }
    public static Object partialAggregation(InternalAggregationFunction functiondouble confidenceint[] argsPage... pages)
    {
        AccumulatorFactory factory = function.bind(Ints.asList(args), Optional.empty(), Optional.empty(), confidence);
        Accumulator partialAggregation = factory.createAccumulator();
        for (Page page : pages) {
            if (page.getPositionCount() > 0) {
                partialAggregation.addInput(page);
            }
        }
        Block partialBlock = getIntermediateBlock(partialAggregation);
        Accumulator finalAggregation = factory.createIntermediateAccumulator();
        // Test handling of empty intermediate blocks
        Accumulator emptyAggregation = factory.createAccumulator();
        Block emptyBlock = getIntermediateBlock(emptyAggregation);
        finalAggregation.addIntermediate(emptyBlock);
        finalAggregation.addIntermediate(partialBlock);
        Block finalBlock = getFinalBlock(finalAggregation);
        return BlockAssertions.getOnlyValue(finalAggregation.getFinalType(), finalBlock);
    }
    public static Object groupedAggregation(InternalAggregationFunction functiondouble confidencePage... pages)
    {
        // execute with args in positions: arg0, arg1, arg2
        Object aggregation = groupedAggregation(functionconfidencecreateArgs(function), pages);
        // execute with args in reverse order: arg2, arg1, arg0
        if (function.getParameterTypes().size() > 1) {
            Object aggregationWithOffset = groupedAggregation(functionconfidencereverseArgs(function), reverseColumns(pages));
            assertEquals(aggregationWithOffsetaggregation"Inconsistent results with reversed channels");
        }
        // execute with args at an offset (and possibly reversed): null, null, null, arg2, arg1, arg0
        Object aggregationWithOffset = groupedAggregation(functionconfidenceoffsetArgs(function, 3), offsetColumns(pages, 3));
        assertEquals(aggregationWithOffsetaggregation"Inconsistent results with channel offset");
        return aggregation;
    }
    public static Object groupedAggregation(InternalAggregationFunction functiondouble confidenceint[] argsPage... pages)
    {
        GroupedAccumulator groupedAggregation = function.bind(Ints.asList(args), Optional.empty(), Optional.empty(), confidence).createGroupedAccumulator();
        for (Page page : pages) {
            groupedAggregation.addInput(createGroupByIdBlock(0, page.getPositionCount()), page);
        }
        Object groupValue = getGroupValue(groupedAggregation, 0);
        for (Page page : pages) {
            groupedAggregation.addInput(createGroupByIdBlock(4000, page.getPositionCount()), page);
        }
        Object largeGroupValue = getGroupValue(groupedAggregation, 4000);
        assertEquals(largeGroupValuegroupValue"Inconsistent results with large group id");
        return groupValue;
    }
    public static Object groupedPartialAggregation(InternalAggregationFunction functiondouble confidencePage... pages)
    {
        // execute with args in positions: arg0, arg1, arg2
        Object aggregation = groupedPartialAggregation(functionconfidencecreateArgs(function), pages);
        // execute with args in reverse order: arg2, arg1, arg0
        if (function.getParameterTypes().size() > 1) {
            Object aggregationWithOffset = groupedPartialAggregation(functionconfidencereverseArgs(function), reverseColumns(pages));
            assertEquals(aggregationWithOffsetaggregation"Inconsistent results with reversed channels");
        }
        // execute with args at an offset (and possibly reversed): null, null, null, arg2, arg1, arg0
        Object aggregationWithOffset = groupedPartialAggregation(functionconfidenceoffsetArgs(function, 3), offsetColumns(pages, 3));
        assertEquals(aggregationWithOffsetaggregation"Inconsistent results with channel offset");
        return aggregation;
    }
    public static Object groupedPartialAggregation(InternalAggregationFunction functiondouble confidenceint[] argsPage... pages)
    {
        AccumulatorFactory factory = function.bind(Ints.asList(args), Optional.empty(), Optional.empty(), confidence);
        GroupedAccumulator partialAggregation = factory.createGroupedAccumulator();
        for (Page page : pages) {
            partialAggregation.addInput(createGroupByIdBlock(0, page.getPositionCount()), page);
        }
        BlockBuilder partialOut = partialAggregation.getIntermediateType().createBlockBuilder(new BlockBuilderStatus(), 1);
        partialAggregation.evaluateIntermediate(0, partialOut);
        Block partialBlock = partialOut.build();
        GroupedAccumulator finalAggregation = factory.createGroupedIntermediateAccumulator();
        // Add an empty block to test the handling of empty intermediates
        GroupedAccumulator emptyAggregation = factory.createGroupedAccumulator();
        BlockBuilder emptyOut = emptyAggregation.getIntermediateType().createBlockBuilder(new BlockBuilderStatus(), 1);
        emptyAggregation.evaluateIntermediate(0, emptyOut);
        Block emptyBlock = emptyOut.build();
        finalAggregation.addIntermediate(createGroupByIdBlock(0, emptyBlock.getPositionCount()), emptyBlock);
        finalAggregation.addIntermediate(createGroupByIdBlock(0, partialBlock.getPositionCount()), partialBlock);
        finalAggregation.addIntermediate(createGroupByIdBlock(0, emptyBlock.getPositionCount()), emptyBlock);
        return getGroupValue(finalAggregation, 0);
    }
    public static GroupByIdBlock createGroupByIdBlock(int groupIdint positions)
    {
        BlockBuilder blockBuilder = .createBlockBuilder(new BlockBuilderStatus(), positions);
        for (int i = 0; i < positionsi++) {
            .writeLong(blockBuildergroupId);
        }
        return new GroupByIdBlock(groupIdblockBuilder.build());
    }
    private static int[] createArgs(InternalAggregationFunction function)
    {
        int[] args = new int[function.getParameterTypes().size()];
        for (int i = 0; i < args.lengthi++) {
            args[i] = i;
        }
        return args;
    }
    private static int[] reverseArgs(InternalAggregationFunction function)
    {
        int[] args = createArgs(function);
        Collections.reverse(Ints.asList(args));
        return args;
    }
    private static int[] offsetArgs(InternalAggregationFunction functionint offset)
    {
        int[] args = createArgs(function);
        for (int i = 0; i < args.lengthi++) {
            args[i] += offset;
        }
        return args;
    }
    private static Page[] reverseColumns(Page[] pages)
    {
        Page[] newPages = new Page[pages.length];
        for (int i = 0; i < pages.lengthi++) {
            Page page = pages[i];
            if (page.getPositionCount() == 0) {
                newPages[i] = page;
            }
            else {
                Block[] newBlocks = Arrays.copyOf(page.getBlocks(), page.getChannelCount());
                Collections.reverse(Arrays.asList(newBlocks));
                newPages[i] = new Page(page.getPositionCount(), newBlocks);
            }
        }
        return newPages;
    }
    private static Page[] offsetColumns(Page[] pagesint offset)
    {
        Page[] newPages = new Page[pages.length];
        for (int i = 0; i < pages.lengthi++) {
            Page page = pages[i];
            Block[] newBlocks = new Block[page.getChannelCount() + offset];
            for (int channel = 0; channel < offsetchannel++) {
                newBlocks[channel] = createNullRLEBlock(page.getPositionCount());
            }
            for (int channel = 0; channel < page.getBlocks().lengthchannel++) {
                newBlocks[channel + offset] = page.getBlocks()[channel];
            }
            newPages[i] = new Page(page.getPositionCount(), newBlocks);
        }
        return newPages;
    }
    private static RunLengthEncodedBlock createNullRLEBlock(int positionCount)
    {
        Block value = .createBlockBuilder(new BlockBuilderStatus(), 1)
                .appendNull()
                .build();
        return new RunLengthEncodedBlock(valuepositionCount);
    }
    private static Object getGroupValue(GroupedAccumulator groupedAggregationint groupId)
    {
        BlockBuilder out = groupedAggregation.getFinalType().createBlockBuilder(new BlockBuilderStatus(), 1);
        groupedAggregation.evaluateFinal(groupIdout);
        return BlockAssertions.getOnlyValue(groupedAggregation.getFinalType(), out.build());
    }
    public static double[] constructDoublePrimitiveArray(int startint length)
    {
        return IntStream.range(startstart + length).asDoubleStream().toArray();
    }
    public static Block createDoubleSequenceBlock(int startint length)
    {
        BlockBuilder blockBuilder = .createBlockBuilder(new BlockBuilderStatus(), length);
        for (int i = starti < start + lengthi++) {
            .writeDouble(blockBuilderi);
        }
        return blockBuilder.build();
    }
    public static Block createDoubleArbitraryBlock(double... values)
    {
        BlockBuilder blockBuilder = .createBlockBuilder(new BlockBuilderStatus(), values.length);
        for (double i : values) {
            .writeDouble(blockBuilderi);
        }
        return blockBuilder.build();
    }
New to GrepCode? Check out our FAQ X