Search in sources :

Example 16 with Parameter

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

the class CursorProcessorCompiler method generateProcessMethod.

private static void generateProcessMethod(ClassDefinition classDefinition, int projections) {
    Parameter session = arg("session", ConnectorSession.class);
    Parameter cursor = arg("cursor", RecordCursor.class);
    Parameter count = arg("count", int.class);
    Parameter pageBuilder = arg("pageBuilder", PageBuilder.class);
    MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), "process", type(int.class), session, cursor, count, pageBuilder);
    Scope scope = method.getScope();
    Variable completedPositionsVariable = scope.declareVariable(int.class, "completedPositions");
    method.getBody().comment("int completedPositions = 0;").putVariable(completedPositionsVariable, 0);
    //
    // for loop loop body
    //
    LabelNode done = new LabelNode("done");
    ForLoop forLoop = new ForLoop().initialize(NOP).condition(new BytecodeBlock().comment("completedPositions < count").getVariable(completedPositionsVariable).getVariable(count).invokeStatic(CompilerOperations.class, "lessThan", boolean.class, int.class, int.class)).update(new BytecodeBlock().comment("completedPositions++").incrementVariable(completedPositionsVariable, (byte) 1));
    BytecodeBlock forLoopBody = new BytecodeBlock().comment("if (pageBuilder.isFull()) break;").append(new BytecodeBlock().getVariable(pageBuilder).invokeVirtual(PageBuilder.class, "isFull", boolean.class).ifTrueGoto(done)).comment("if (!cursor.advanceNextPosition()) break;").append(new BytecodeBlock().getVariable(cursor).invokeInterface(RecordCursor.class, "advanceNextPosition", boolean.class).ifFalseGoto(done));
    forLoop.body(forLoopBody);
    // if (filter(cursor))
    IfStatement ifStatement = new IfStatement();
    ifStatement.condition().append(method.getThis()).getVariable(session).getVariable(cursor).invokeVirtual(classDefinition.getType(), "filter", type(boolean.class), type(ConnectorSession.class), type(RecordCursor.class));
    // pageBuilder.declarePosition();
    ifStatement.ifTrue().getVariable(pageBuilder).invokeVirtual(PageBuilder.class, "declarePosition", void.class);
    // this.project_43(session, cursor, pageBuilder.getBlockBuilder(42)));
    for (int projectionIndex = 0; projectionIndex < projections; projectionIndex++) {
        ifStatement.ifTrue().append(method.getThis()).getVariable(session).getVariable(cursor);
        // pageBuilder.getBlockBuilder(0)
        ifStatement.ifTrue().getVariable(pageBuilder).push(projectionIndex).invokeVirtual(PageBuilder.class, "getBlockBuilder", BlockBuilder.class, int.class);
        // project(block..., blockBuilder)gen
        ifStatement.ifTrue().invokeVirtual(classDefinition.getType(), "project_" + projectionIndex, type(void.class), type(ConnectorSession.class), type(RecordCursor.class), type(BlockBuilder.class));
    }
    forLoopBody.append(ifStatement);
    method.getBody().append(forLoop).visitLabel(done).comment("return completedPositions;").getVariable(completedPositionsVariable).retInt();
}
Also used : LabelNode(com.facebook.presto.bytecode.instruction.LabelNode) IfStatement(com.facebook.presto.bytecode.control.IfStatement) Variable(com.facebook.presto.bytecode.Variable) RecordCursor(com.facebook.presto.spi.RecordCursor) Scope(com.facebook.presto.bytecode.Scope) ForLoop(com.facebook.presto.bytecode.control.ForLoop) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Parameter(com.facebook.presto.bytecode.Parameter) ConnectorSession(com.facebook.presto.spi.ConnectorSession) BlockBuilder(com.facebook.presto.spi.block.BlockBuilder)

Example 17 with Parameter

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

the class PageProcessorCompiler method generateProjectMethod.

private MethodDefinition generateProjectMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, CachedInstanceBinder cachedInstanceBinder, String methodName, RowExpression projection) {
    PreGeneratedExpressions preGeneratedExpressions = generateMethodsForLambdaAndTry(classDefinition, callSiteBinder, cachedInstanceBinder, projection, methodName);
    Parameter session = arg("session", ConnectorSession.class);
    List<Parameter> blocks = toBlockParameters(getInputChannels(projection));
    Parameter position = arg("position", int.class);
    Parameter output = arg("output", BlockBuilder.class);
    MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), methodName, type(void.class), ImmutableList.<Parameter>builder().add(session).addAll(blocks).add(position).add(output).build());
    method.comment("Projection: %s", projection.toString());
    Scope scope = method.getScope();
    BytecodeBlock body = method.getBody();
    Variable wasNullVariable = scope.declareVariable("wasNull", body, constantFalse());
    BytecodeExpressionVisitor visitor = new BytecodeExpressionVisitor(callSiteBinder, cachedInstanceBinder, fieldReferenceCompiler(callSiteBinder), metadata.getFunctionRegistry(), preGeneratedExpressions);
    body.getVariable(output).comment("evaluate projection: " + projection.toString()).append(projection.accept(visitor, scope)).append(generateWrite(callSiteBinder, scope, wasNullVariable, projection.getType())).ret();
    return method;
}
Also used : 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)

Example 18 with Parameter

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

the class PageProcessorCompiler method generateGetNonLazyPageMethod.

private static void generateGetNonLazyPageMethod(ClassDefinition classDefinition, RowExpression filter, List<RowExpression> projections) {
    Parameter page = arg("page", Page.class);
    MethodDefinition method = classDefinition.declareMethod(a(PRIVATE), "getNonLazyPage", type(Page.class), page);
    Scope scope = method.getScope();
    BytecodeBlock body = method.getBody();
    List<Integer> allInputChannels = getInputChannels(concat(projections, ImmutableList.of(filter)));
    if (allInputChannels.isEmpty()) {
        body.append(page.ret());
        return;
    }
    Variable index = scope.declareVariable(int.class, "index");
    Variable channelCount = scope.declareVariable("channelCount", body, page.invoke("getChannelCount", int.class));
    Variable blocks = scope.declareVariable("blocks", body, newArray(type(Block[].class), channelCount));
    Variable inputBlock = scope.declareVariable(Block.class, "inputBlock");
    Variable positionCount = scope.declareVariable("positionCount", body, page.invoke("getPositionCount", int.class));
    Variable createNewPage = scope.declareVariable("createNewPage", body, constantFalse());
    ForLoop forLoop = new ForLoop().initialize(index.set(constantInt(0))).condition(lessThan(index, channelCount)).update(index.increment()).body(new BytecodeBlock().append(inputBlock.set(page.invoke("getBlock", Block.class, index))).append(new IfStatement().condition(inputBlock.instanceOf(LazyBlock.class)).ifTrue(new BytecodeBlock().append(blocks.setElement(index, inputBlock.cast(LazyBlock.class).invoke("getBlock", Block.class))).append(createNewPage.set(constantTrue()))).ifFalse(blocks.setElement(index, inputBlock))));
    body.append(forLoop);
    body.append(new IfStatement().condition(createNewPage).ifTrue(page.set(newInstance(Page.class, positionCount, blocks))));
    body.append(page.ret());
}
Also used : IfStatement(com.facebook.presto.bytecode.control.IfStatement) Variable(com.facebook.presto.bytecode.Variable) LazyBlock(com.facebook.presto.spi.block.LazyBlock) Scope(com.facebook.presto.bytecode.Scope) ForLoop(com.facebook.presto.bytecode.control.ForLoop) 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)

Example 19 with Parameter

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

the class PageProcessorCompiler method generateProjectColumnarMethod.

private static MethodDefinition generateProjectColumnarMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, String methodName, RowExpression projection, MethodDefinition projectionMethod) {
    Parameter session = arg("session", ConnectorSession.class);
    Parameter page = arg("page", Page.class);
    Parameter selectedPositions = arg("selectedPositions", int[].class);
    Parameter pageBuilder = arg("pageBuilder", PageBuilder.class);
    Parameter projectionIndex = arg("projectionIndex", int.class);
    List<Parameter> params = ImmutableList.<Parameter>builder().add(session).add(page).add(selectedPositions).add(pageBuilder).add(projectionIndex).build();
    MethodDefinition method = classDefinition.declareMethod(a(PRIVATE), methodName, type(Block.class), params);
    BytecodeBlock body = method.getBody();
    Scope scope = method.getScope();
    Variable thisVariable = method.getThis();
    ImmutableList.Builder<Variable> builder = ImmutableList.builder();
    for (int channel : getInputChannels(projection)) {
        Variable blockVariable = scope.declareVariable("block_" + channel, body, page.invoke("getBlock", Block.class, constantInt(channel)));
        builder.add(blockVariable);
    }
    List<Variable> inputs = builder.build();
    Variable positionCount = scope.declareVariable("positionCount", body, page.invoke("getPositionCount", int.class));
    Variable position = scope.declareVariable("position", body, constantInt(0));
    Variable cardinality = scope.declareVariable("cardinality", body, selectedPositions.length());
    Variable outputBlock = scope.declareVariable(Block.class, "outputBlock");
    Variable blockBuilder = scope.declareVariable("blockBuilder", body, pageBuilder.invoke("getBlockBuilder", BlockBuilder.class, projectionIndex));
    Variable type = scope.declareVariable("type", body, pageBuilder.invoke("getType", Type.class, projectionIndex));
    BytecodeBlock projectBlock = new BytecodeBlock().append(new ForLoop().initialize(position.set(constantInt(0))).condition(lessThan(position, cardinality)).update(position.increment()).body(invokeProject(thisVariable, session, inputs, selectedPositions.getElement(position), pageBuilder, projectionIndex, projectionMethod))).append(outputBlock.set(blockBuilder.invoke("build", Block.class)));
    if (isIdentityExpression(projection)) {
        // if nothing is filtered out, copy the entire block, else project it
        body.append(new IfStatement().condition(equal(cardinality, positionCount)).ifTrue(new BytecodeBlock().append(inputs.get(0).invoke("assureLoaded", void.class)).append(outputBlock.set(inputs.get(0)))).ifFalse(projectBlock));
    } else if (isConstantExpression(projection)) {
        // if projection is a constant, create RLE block of constant expression with cardinality positions
        ConstantExpression constantExpression = (ConstantExpression) projection;
        verify(getInputChannels(projection).isEmpty());
        BytecodeExpression value = loadConstant(callSiteBinder, constantExpression.getValue(), Object.class);
        body.append(outputBlock.set(invokeStatic(RunLengthEncodedBlock.class, "create", Block.class, type, value, cardinality)));
    } else {
        body.append(projectBlock);
    }
    body.append(outputBlock.ret());
    return method;
}
Also used : Variable(com.facebook.presto.bytecode.Variable) ForLoop(com.facebook.presto.bytecode.control.ForLoop) ImmutableList(com.google.common.collect.ImmutableList) ConstantExpression(com.facebook.presto.sql.relational.ConstantExpression) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) IfStatement(com.facebook.presto.bytecode.control.IfStatement) Type(com.facebook.presto.spi.type.Type) 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) BytecodeExpression(com.facebook.presto.bytecode.expression.BytecodeExpression) RunLengthEncodedBlock(com.facebook.presto.spi.block.RunLengthEncodedBlock) BlockBuilder(com.facebook.presto.spi.block.BlockBuilder)

Example 20 with Parameter

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

the class PageProcessorCompiler method generateFilterMethod.

private void generateFilterMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, CachedInstanceBinder cachedInstanceBinder, RowExpression filter) {
    PreGeneratedExpressions preGeneratedExpressions = generateMethodsForLambdaAndTry(classDefinition, callSiteBinder, cachedInstanceBinder, filter, "filter");
    Parameter session = arg("session", ConnectorSession.class);
    List<Parameter> blocks = toBlockParameters(getInputChannels(filter));
    Parameter position = arg("position", int.class);
    MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), "filter", type(boolean.class), ImmutableList.<Parameter>builder().add(session).addAll(blocks).add(position).build());
    method.comment("Filter: %s", filter.toString());
    BytecodeBlock body = method.getBody();
    Scope scope = method.getScope();
    Variable wasNullVariable = scope.declareVariable("wasNull", body, constantFalse());
    BytecodeExpressionVisitor visitor = new BytecodeExpressionVisitor(callSiteBinder, cachedInstanceBinder, fieldReferenceCompiler(callSiteBinder), metadata.getFunctionRegistry(), preGeneratedExpressions);
    BytecodeNode visitorBody = filter.accept(visitor, scope);
    Variable result = scope.declareVariable(boolean.class, "result");
    body.append(visitorBody).putVariable(result).append(new IfStatement().condition(wasNullVariable).ifTrue(constantFalse().ret()).ifFalse(result.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) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode)

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