Search in sources :

Example 31 with Parameter

use of com.facebook.presto.bytecode.Parameter in project presto by prestodb.

the class PageProcessorCompiler method generateFilterPageMethod.

private void generateFilterPageMethod(ClassDefinition classDefinition, RowExpression filter) {
    Parameter session = arg("session", ConnectorSession.class);
    Parameter page = arg("page", Page.class);
    MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), "filterPage", type(int[].class), session, page);
    method.comment("Filter: %s rows in the page", filter.toString());
    Scope scope = method.getScope();
    Variable thisVariable = method.getThis();
    BytecodeBlock body = method.getBody();
    Variable positionCount = scope.declareVariable("positionCount", body, page.invoke("getPositionCount", int.class));
    Variable selectedPositions = scope.declareVariable("selectedPositions", body, newArray(type(int[].class), positionCount));
    Variable selectedCount = scope.declareVariable("selectedCount", body, constantInt(0));
    Variable position = scope.declareVariable(int.class, "position");
    List<Integer> filterChannels = getInputChannels(filter);
    // extract block variables
    ImmutableList.Builder<Variable> blockVariablesBuilder = ImmutableList.builder();
    for (int channel : filterChannels) {
        Variable blockVariable = scope.declareVariable("block_" + channel, body, page.invoke("getBlock", Block.class, constantInt(channel)));
        blockVariablesBuilder.add(blockVariable);
    }
    List<Variable> blockVariables = blockVariablesBuilder.build();
    if (filterChannels.size() == 1 && determinismEvaluator.isDeterministic(filter)) {
        BytecodeBlock ifFilterOnDictionaryBlock = getBytecodeFilterOnDictionary(session, scope, blockVariables.get(0));
        BytecodeBlock ifFilterOnRLEBlock = getBytecodeFilterOnRLE(session, scope, blockVariables.get(0));
        body.append(new IfStatement().condition(blockVariables.get(0).instanceOf(DictionaryBlock.class)).ifTrue(ifFilterOnDictionaryBlock));
        body.append(new IfStatement().condition(blockVariables.get(0).instanceOf(RunLengthEncodedBlock.class)).ifTrue(ifFilterOnRLEBlock));
    }
    body.append(new ForLoop().initialize(position.set(constantInt(0))).condition(lessThan(position, positionCount)).update(position.increment()).body(new IfStatement().condition(invokeFilter(thisVariable, session, blockVariables, position)).ifTrue(new BytecodeBlock().append(selectedPositions.setElement(selectedCount, position)).append(selectedCount.increment()))));
    body.append(invokeStatic(Arrays.class, "copyOf", int[].class, selectedPositions, selectedCount).ret());
}
Also used : Variable(com.facebook.presto.bytecode.Variable) ForLoop(com.facebook.presto.bytecode.control.ForLoop) ImmutableList(com.google.common.collect.ImmutableList) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) DictionaryBlock(com.facebook.presto.spi.block.DictionaryBlock) IfStatement(com.facebook.presto.bytecode.control.IfStatement) Scope(com.facebook.presto.bytecode.Scope) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) Parameter(com.facebook.presto.bytecode.Parameter) Block(com.facebook.presto.spi.block.Block) DictionaryBlock(com.facebook.presto.spi.block.DictionaryBlock) LazyBlock(com.facebook.presto.spi.block.LazyBlock) RunLengthEncodedBlock(com.facebook.presto.spi.block.RunLengthEncodedBlock) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) RunLengthEncodedBlock(com.facebook.presto.spi.block.RunLengthEncodedBlock)

Example 32 with Parameter

use of com.facebook.presto.bytecode.Parameter in project presto by prestodb.

the class PageProcessorCompiler method generateMethodsForLambdaAndTry.

private PreGeneratedExpressions generateMethodsForLambdaAndTry(ClassDefinition containerClassDefinition, CallSiteBinder callSiteBinder, CachedInstanceBinder cachedInstanceBinder, RowExpression projection, String methodPrefix) {
    Set<RowExpression> lambdaAndTryExpressions = ImmutableSet.copyOf(extractLambdaAndTryExpressions(projection));
    ImmutableMap.Builder<CallExpression, MethodDefinition> tryMethodMap = ImmutableMap.builder();
    ImmutableMap.Builder<LambdaDefinitionExpression, FieldDefinition> lambdaFieldMap = ImmutableMap.builder();
    int counter = 0;
    for (RowExpression expression : lambdaAndTryExpressions) {
        if (expression instanceof CallExpression) {
            CallExpression tryExpression = (CallExpression) expression;
            verify(!Signatures.TRY.equals(tryExpression.getSignature().getName()));
            Parameter session = arg("session", ConnectorSession.class);
            List<Parameter> blocks = toBlockParameters(getInputChannels(tryExpression.getArguments()));
            Parameter position = arg("position", int.class);
            BytecodeExpressionVisitor innerExpressionVisitor = new BytecodeExpressionVisitor(callSiteBinder, cachedInstanceBinder, fieldReferenceCompiler(callSiteBinder), metadata.getFunctionRegistry(), new PreGeneratedExpressions(tryMethodMap.build(), lambdaFieldMap.build()));
            List<Parameter> inputParameters = ImmutableList.<Parameter>builder().add(session).addAll(blocks).add(position).build();
            MethodDefinition tryMethod = defineTryMethod(innerExpressionVisitor, containerClassDefinition, methodPrefix + "_try_" + counter, inputParameters, Primitives.wrap(tryExpression.getType().getJavaType()), tryExpression, callSiteBinder);
            tryMethodMap.put(tryExpression, tryMethod);
        } else if (expression instanceof LambdaDefinitionExpression) {
            LambdaDefinitionExpression lambdaExpression = (LambdaDefinitionExpression) expression;
            PreGeneratedExpressions preGeneratedExpressions = new PreGeneratedExpressions(tryMethodMap.build(), lambdaFieldMap.build());
            FieldDefinition methodHandleField = LambdaBytecodeGenerator.preGenerateLambdaExpression(lambdaExpression, methodPrefix + "_lambda_" + counter, containerClassDefinition, preGeneratedExpressions, callSiteBinder, cachedInstanceBinder, metadata.getFunctionRegistry());
            lambdaFieldMap.put(lambdaExpression, methodHandleField);
        } else {
            throw new VerifyException(format("unexpected expression: %s", expression.toString()));
        }
        counter++;
    }
    return new PreGeneratedExpressions(tryMethodMap.build(), lambdaFieldMap.build());
}
Also used : FieldDefinition(com.facebook.presto.bytecode.FieldDefinition) RowExpression(com.facebook.presto.sql.relational.RowExpression) ImmutableMap(com.google.common.collect.ImmutableMap) VerifyException(com.google.common.base.VerifyException) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) Parameter(com.facebook.presto.bytecode.Parameter) CallExpression(com.facebook.presto.sql.relational.CallExpression) LambdaDefinitionExpression(com.facebook.presto.sql.relational.LambdaDefinitionExpression)

Example 33 with Parameter

use of com.facebook.presto.bytecode.Parameter in project presto by prestodb.

the class PageProcessorCompiler method generateProcessColumnarMethod.

private static void generateProcessColumnarMethod(ClassDefinition classDefinition, List<RowExpression> projections, List<MethodDefinition> projectColumnarMethods) {
    Parameter session = arg("session", ConnectorSession.class);
    Parameter page = arg("page", Page.class);
    Parameter types = arg("types", List.class);
    MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), "processColumnar", type(Page.class), session, page, types);
    Scope scope = method.getScope();
    BytecodeBlock body = method.getBody();
    Variable thisVariable = method.getThis();
    Variable selectedPositions = scope.declareVariable("selectedPositions", body, thisVariable.invoke("filterPage", int[].class, session, page));
    Variable cardinality = scope.declareVariable("cardinality", body, selectedPositions.length());
    body.comment("if no rows selected return null").append(new IfStatement().condition(equal(cardinality, constantInt(0))).ifTrue(constantNull(Page.class).ret()));
    if (projections.isEmpty()) {
        // if no projections, return new page with selected rows
        body.append(newInstance(Page.class, cardinality, newArray(type(Block[].class), 0)).ret());
        return;
    }
    Variable pageBuilder = scope.declareVariable("pageBuilder", body, newInstance(PageBuilder.class, cardinality, types));
    Variable outputBlocks = scope.declareVariable("outputBlocks", body, newArray(type(Block[].class), projections.size()));
    for (int projectionIndex = 0; projectionIndex < projections.size(); projectionIndex++) {
        List<BytecodeExpression> params = ImmutableList.<BytecodeExpression>builder().add(session).add(page).add(selectedPositions).add(pageBuilder).add(constantInt(projectionIndex)).build();
        body.append(outputBlocks.setElement(projectionIndex, thisVariable.invoke(projectColumnarMethods.get(projectionIndex), params)));
    }
    // create new page from outputBlocks
    body.append(newInstance(Page.class, cardinality, outputBlocks).ret());
}
Also used : IfStatement(com.facebook.presto.bytecode.control.IfStatement) Variable(com.facebook.presto.bytecode.Variable) Scope(com.facebook.presto.bytecode.Scope) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Parameter(com.facebook.presto.bytecode.Parameter) Block(com.facebook.presto.spi.block.Block) DictionaryBlock(com.facebook.presto.spi.block.DictionaryBlock) LazyBlock(com.facebook.presto.spi.block.LazyBlock) RunLengthEncodedBlock(com.facebook.presto.spi.block.RunLengthEncodedBlock) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Page(com.facebook.presto.spi.Page) PageBuilder(com.facebook.presto.spi.PageBuilder) BytecodeExpression(com.facebook.presto.bytecode.expression.BytecodeExpression)

Example 34 with Parameter

use of com.facebook.presto.bytecode.Parameter in project presto by prestodb.

the class PageProcessorCompiler method generateProcessMethod.

private static void generateProcessMethod(ClassDefinition classDefinition, RowExpression filter, List<RowExpression> projections, List<MethodDefinition> projectionMethods) {
    Parameter session = arg("session", ConnectorSession.class);
    Parameter page = arg("page", Page.class);
    Parameter start = arg("start", int.class);
    Parameter end = arg("end", int.class);
    Parameter pageBuilder = arg("pageBuilder", PageBuilder.class);
    MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), "process", type(int.class), session, page, start, end, pageBuilder);
    Scope scope = method.getScope();
    BytecodeBlock body = method.getBody();
    Variable thisVariable = method.getThis();
    // extract blocks
    List<Integer> allInputChannels = getInputChannels(concat(projections, ImmutableList.of(filter)));
    ImmutableMap.Builder<Integer, Variable> builder = ImmutableMap.builder();
    for (int channel : allInputChannels) {
        Variable blockVariable = scope.declareVariable("block_" + channel, body, page.invoke("getBlock", Block.class, constantInt(channel)));
        builder.put(channel, blockVariable);
    }
    Map<Integer, Variable> channelBlocks = builder.build();
    Map<RowExpression, List<Variable>> expressionInputBlocks = getExpressionInputBlocks(projections, filter, channelBlocks);
    // projection body
    Variable position = scope.declareVariable(int.class, "position");
    BytecodeBlock project = new BytecodeBlock().append(pageBuilder.invoke("declarePosition", void.class));
    for (int projectionIndex = 0; projectionIndex < projections.size(); projectionIndex++) {
        RowExpression projection = projections.get(projectionIndex);
        project.append(invokeProject(thisVariable, session, expressionInputBlocks.get(projection), position, pageBuilder, constantInt(projectionIndex), projectionMethods.get(projectionIndex)));
    }
    LabelNode done = new LabelNode("done");
    // for loop loop body
    ForLoop loop = new ForLoop().initialize(position.set(start)).condition(lessThan(position, end)).update(position.set(add(position, constantInt(1)))).body(new BytecodeBlock().append(new IfStatement().condition(pageBuilder.invoke("isFull", boolean.class)).ifTrue(jump(done))).append(new IfStatement().condition(invokeFilter(thisVariable, session, expressionInputBlocks.get(filter), position)).ifTrue(project)));
    body.append(loop).visitLabel(done).append(position.ret());
}
Also used : LabelNode(com.facebook.presto.bytecode.instruction.LabelNode) Variable(com.facebook.presto.bytecode.Variable) ForLoop(com.facebook.presto.bytecode.control.ForLoop) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) RowExpression(com.facebook.presto.sql.relational.RowExpression) ImmutableMap(com.google.common.collect.ImmutableMap) IfStatement(com.facebook.presto.bytecode.control.IfStatement) Scope(com.facebook.presto.bytecode.Scope) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) Parameter(com.facebook.presto.bytecode.Parameter) Block(com.facebook.presto.spi.block.Block) DictionaryBlock(com.facebook.presto.spi.block.DictionaryBlock) LazyBlock(com.facebook.presto.spi.block.LazyBlock) RunLengthEncodedBlock(com.facebook.presto.spi.block.RunLengthEncodedBlock) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Collections.singletonList(java.util.Collections.singletonList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) Collectors.toList(java.util.stream.Collectors.toList)

Example 35 with Parameter

use of com.facebook.presto.bytecode.Parameter in project presto by prestodb.

the class LambdaBytecodeGenerator method defineLambdaMethodAndField.

private static FieldDefinition defineLambdaMethodAndField(BytecodeExpressionVisitor innerExpressionVisitor, ClassDefinition classDefinition, String fieldAndMethodName, List<Parameter> inputParameters, LambdaDefinitionExpression lambda) {
    Class<?> returnType = Primitives.wrap(lambda.getBody().getType().getJavaType());
    MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), fieldAndMethodName, type(returnType), inputParameters);
    Scope scope = method.getScope();
    Variable wasNull = scope.declareVariable(boolean.class, "wasNull");
    BytecodeNode compiledBody = lambda.getBody().accept(innerExpressionVisitor, scope);
    method.getBody().putVariable(wasNull, false).append(compiledBody).append(boxPrimitiveIfNecessary(scope, returnType)).ret(returnType);
    FieldDefinition methodHandleField = classDefinition.declareField(a(PRIVATE, STATIC, FINAL), fieldAndMethodName, type(MethodHandle.class));
    classDefinition.getClassInitializer().getBody().append(setStatic(methodHandleField, invokeStatic(Reflection.class, "methodHandle", MethodHandle.class, constantClass(classDefinition.getType()), constantString(fieldAndMethodName), newArray(type(Class[].class), inputParameters.stream().map(Parameter::getType).map(BytecodeExpressions::constantClass).collect(toImmutableList())))));
    return methodHandleField;
}
Also used : Variable(com.facebook.presto.bytecode.Variable) Scope(com.facebook.presto.bytecode.Scope) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) FieldDefinition(com.facebook.presto.bytecode.FieldDefinition) Parameter(com.facebook.presto.bytecode.Parameter) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode) BytecodeExpressions.constantClass(com.facebook.presto.bytecode.expression.BytecodeExpressions.constantClass) MethodHandle(java.lang.invoke.MethodHandle)

Aggregations

Parameter (com.facebook.presto.bytecode.Parameter)58 MethodDefinition (com.facebook.presto.bytecode.MethodDefinition)56 Variable (com.facebook.presto.bytecode.Variable)43 BytecodeBlock (com.facebook.presto.bytecode.BytecodeBlock)40 Scope (com.facebook.presto.bytecode.Scope)29 IfStatement (com.facebook.presto.bytecode.control.IfStatement)25 BytecodeExpression (com.facebook.presto.bytecode.expression.BytecodeExpression)22 Block (com.facebook.presto.spi.block.Block)19 ImmutableList (com.google.common.collect.ImmutableList)16 ClassDefinition (com.facebook.presto.bytecode.ClassDefinition)11 ForLoop (com.facebook.presto.bytecode.control.ForLoop)9 BlockBuilder (com.facebook.presto.spi.block.BlockBuilder)9 List (java.util.List)9 BytecodeNode (com.facebook.presto.bytecode.BytecodeNode)8 DictionaryBlock (com.facebook.presto.spi.block.DictionaryBlock)8 LazyBlock (com.facebook.presto.spi.block.LazyBlock)8 RunLengthEncodedBlock (com.facebook.presto.spi.block.RunLengthEncodedBlock)8 Type (com.facebook.presto.spi.type.Type)8 LabelNode (com.facebook.presto.bytecode.instruction.LabelNode)7 ImmutableMap (com.google.common.collect.ImmutableMap)7