Search in sources :

Example 16 with BytecodeExpression

use of com.facebook.presto.bytecode.expression.BytecodeExpression 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 17 with BytecodeExpression

use of com.facebook.presto.bytecode.expression.BytecodeExpression in project presto by prestodb.

the class PageProcessorCompiler method generateProjectDictionaryMethod.

private MethodDefinition generateProjectDictionaryMethod(ClassDefinition classDefinition, String methodName, RowExpression projection, MethodDefinition project, MethodDefinition projectColumnar, MethodDefinition projectRLE) {
    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);
    Parameter dictionarySourceIds = arg("dictionarySourceIds", Map.class);
    List<Parameter> params = ImmutableList.<Parameter>builder().add(session).add(page).add(selectedPositions).add(pageBuilder).add(projectionIndex).add(dictionarySourceIds).build();
    List<Parameter> columnarParams = 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();
    List<Integer> inputChannels = getInputChannels(projection);
    if (inputChannels.size() != 1 || !determinismEvaluator.isDeterministic(projection)) {
        body.append(thisVariable.invoke(projectColumnar, columnarParams).ret());
        return method;
    }
    Variable inputBlock = scope.declareVariable("inputBlock", body, page.invoke("getBlock", Block.class, constantInt(getOnlyElement(inputChannels))));
    body.append(new IfStatement().condition(inputBlock.instanceOf(RunLengthEncodedBlock.class)).ifTrue(thisVariable.invoke(projectRLE, columnarParams).ret()));
    body.append(new IfStatement().condition(inputBlock.instanceOf(DictionaryBlock.class)).ifFalse(thisVariable.invoke(projectColumnar, columnarParams).ret()));
    Variable blockBuilder = scope.declareVariable("blockBuilder", body, pageBuilder.invoke("getBlockBuilder", BlockBuilder.class, projectionIndex));
    Variable cardinality = scope.declareVariable("cardinality", body, selectedPositions.length());
    Variable dictionary = scope.declareVariable(Block.class, "dictionary");
    Variable dictionaryCount = scope.declareVariable(int.class, "dictionaryCount");
    Variable inputSourceId = scope.declareVariable(DictionaryId.class, "inputSourceId");
    Variable outputSourceId = scope.declareVariable(DictionaryId.class, "outputSourceId");
    Variable outputDictionary = scope.declareVariable(Block.class, "outputDictionary");
    Variable outputIds = scope.declareVariable(int[].class, "outputIds");
    BytecodeExpression inputDictionaries = thisVariable.getField("inputDictionaries", Block[].class);
    BytecodeExpression outputDictionaries = thisVariable.getField("outputDictionaries", Block[].class);
    Variable position = scope.declareVariable("position", body, constantInt(0));
    BytecodeExpression castDictionaryBlock = inputBlock.cast(DictionaryBlock.class);
    body.comment("Extract dictionary, ids, positionCount and dictionarySourceId").append(dictionary.set(castDictionaryBlock.invoke("getDictionary", Block.class))).append(dictionaryCount.set(dictionary.invoke("getPositionCount", int.class))).append(inputSourceId.set(castDictionaryBlock.invoke("getDictionarySourceId", DictionaryId.class)));
    BytecodeBlock projectDictionary = new BytecodeBlock().comment("Project dictionary").append(new ForLoop().initialize(position.set(constantInt(0))).condition(lessThan(position, dictionaryCount)).update(position.increment()).body(invokeProject(thisVariable, session, ImmutableList.of(dictionary), position, pageBuilder, projectionIndex, project))).append(outputDictionary.set(blockBuilder.invoke("build", Block.class))).append(inputDictionaries.setElement(projectionIndex, dictionary)).append(outputDictionaries.setElement(projectionIndex, outputDictionary));
    body.comment("Use processed dictionary, if available, else project it").append(new IfStatement().condition(equal(inputDictionaries.getElement(projectionIndex), dictionary)).ifTrue(outputDictionary.set(outputDictionaries.getElement(projectionIndex))).ifFalse(projectDictionary));
    body.comment("Filter ids").append(outputIds.set(newArray(type(int[].class), cardinality))).append(new ForLoop().initialize(position.set(constantInt(0))).condition(lessThan(position, cardinality)).update(position.increment()).body(outputIds.setElement(position, castDictionaryBlock.invoke("getId", int.class, selectedPositions.getElement(position)))));
    body.append(outputSourceId.set(dictionarySourceIds.invoke("get", Object.class, inputSourceId.cast(Object.class)).cast(DictionaryId.class)));
    body.append(new IfStatement().condition(equal(outputSourceId, constantNull(DictionaryId.class))).ifTrue(new BytecodeBlock().append(outputSourceId.set(invokeStatic(DictionaryId.class, "randomDictionaryId", DictionaryId.class))).append(dictionarySourceIds.invoke("put", Object.class, inputSourceId.cast(Object.class), outputSourceId.cast(Object.class))).pop()));
    body.append(newInstance(DictionaryBlock.class, cardinality, outputDictionary, outputIds, constantFalse(), outputSourceId).cast(Block.class).ret());
    return method;
}
Also used : Variable(com.facebook.presto.bytecode.Variable) ForLoop(com.facebook.presto.bytecode.control.ForLoop) 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) BytecodeExpression(com.facebook.presto.bytecode.expression.BytecodeExpression) BlockBuilder(com.facebook.presto.spi.block.BlockBuilder)

Example 18 with BytecodeExpression

use of com.facebook.presto.bytecode.expression.BytecodeExpression in project presto by prestodb.

the class PageProcessorCompiler method generateProcessColumnarDictionaryMethod.

private static void generateProcessColumnarDictionaryMethod(ClassDefinition classDefinition, List<RowExpression> projections, List<MethodDefinition> projectDictionaryMethods) {
    Parameter session = arg("session", ConnectorSession.class);
    Parameter page = arg("page", Page.class);
    Parameter types = arg("types", List.class);
    MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), "processColumnarDictionary", 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());
    Variable dictionarySourceIds = scope.declareVariable(type(Map.class, DictionaryId.class, DictionaryId.class), "dictionarySourceIds");
    body.append(dictionarySourceIds.set(newInstance(type(HashMap.class, DictionaryId.class, DictionaryId.class))));
    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;
    }
    // create PageBuilder
    Variable pageBuilder = scope.declareVariable("pageBuilder", body, newInstance(PageBuilder.class, cardinality, types));
    body.append(page.set(thisVariable.invoke("getNonLazyPage", Page.class, page)));
    // create outputBlocks
    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)).add(dictionarySourceIds).build();
        body.append(outputBlocks.setElement(projectionIndex, thisVariable.invoke(projectDictionaryMethods.get(projectionIndex), params)));
    }
    body.append(newInstance(Page.class, cardinality, outputBlocks).ret());
}
Also used : Variable(com.facebook.presto.bytecode.Variable) HashMap(java.util.HashMap) DictionaryId(com.facebook.presto.spi.block.DictionaryId) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Page(com.facebook.presto.spi.Page) PageBuilder(com.facebook.presto.spi.PageBuilder) 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) BytecodeExpression(com.facebook.presto.bytecode.expression.BytecodeExpression) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) HashMap(java.util.HashMap)

Example 19 with BytecodeExpression

use of com.facebook.presto.bytecode.expression.BytecodeExpression in project presto by prestodb.

the class JoinCompiler method generateAppendToMethod.

private static void generateAppendToMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> types, List<Integer> outputChannels, List<FieldDefinition> channelFields) {
    Parameter blockIndex = arg("blockIndex", int.class);
    Parameter blockPosition = arg("blockPosition", int.class);
    Parameter pageBuilder = arg("pageBuilder", PageBuilder.class);
    Parameter outputChannelOffset = arg("outputChannelOffset", int.class);
    MethodDefinition appendToMethod = classDefinition.declareMethod(a(PUBLIC), "appendTo", type(void.class), blockIndex, blockPosition, pageBuilder, outputChannelOffset);
    Variable thisVariable = appendToMethod.getThis();
    BytecodeBlock appendToBody = appendToMethod.getBody();
    int pageBuilderOutputChannel = 0;
    for (int outputChannel : outputChannels) {
        Type type = types.get(outputChannel);
        BytecodeExpression typeExpression = constantType(callSiteBinder, type);
        BytecodeExpression block = thisVariable.getField(channelFields.get(outputChannel)).invoke("get", Object.class, blockIndex).cast(Block.class);
        appendToBody.comment("%s.appendTo(channel_%s.get(outputChannel), blockPosition, pageBuilder.getBlockBuilder(outputChannelOffset + %s));", type.getClass(), outputChannel, pageBuilderOutputChannel).append(typeExpression).append(block).append(blockPosition).append(pageBuilder).append(outputChannelOffset).push(pageBuilderOutputChannel++).append(OpCode.IADD).invokeVirtual(PageBuilder.class, "getBlockBuilder", BlockBuilder.class, int.class).invokeInterface(Type.class, "appendTo", void.class, Block.class, int.class, BlockBuilder.class);
    }
    appendToBody.ret();
}
Also used : Type(com.facebook.presto.spi.type.Type) SqlTypeBytecodeExpression.constantType(com.facebook.presto.sql.gen.SqlTypeBytecodeExpression.constantType) BigintType(com.facebook.presto.spi.type.BigintType) Variable(com.facebook.presto.bytecode.Variable) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Parameter(com.facebook.presto.bytecode.Parameter) PageBuilder(com.facebook.presto.spi.PageBuilder) BytecodeExpression(com.facebook.presto.bytecode.expression.BytecodeExpression) BlockBuilder(com.facebook.presto.spi.block.BlockBuilder)

Example 20 with BytecodeExpression

use of com.facebook.presto.bytecode.expression.BytecodeExpression in project presto by prestodb.

the class JoinProbeCompiler method generateGetCurrentJoinPosition.

private static void generateGetCurrentJoinPosition(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, FieldDefinition lookupSourceField, FieldDefinition probePageField, FieldDefinition pageField, Optional<Integer> probeHashChannel, FieldDefinition probeHashBlockField, FieldDefinition positionField) {
    MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), "getCurrentJoinPosition", type(long.class));
    Variable thisVariable = method.getThis();
    BytecodeBlock body = method.getBody().append(new IfStatement().condition(thisVariable.invoke("currentRowContainsNull", boolean.class)).ifTrue(constantLong(-1).ret()));
    BytecodeExpression position = thisVariable.getField(positionField);
    BytecodeExpression hashChannelsPage = thisVariable.getField(probePageField);
    BytecodeExpression allChannelsPage = thisVariable.getField(pageField);
    BytecodeExpression probeHashBlock = thisVariable.getField(probeHashBlockField);
    if (probeHashChannel.isPresent()) {
        body.append(thisVariable.getField(lookupSourceField).invoke("getJoinPosition", long.class, position, hashChannelsPage, allChannelsPage, constantType(callSiteBinder, BigintType.BIGINT).invoke("getLong", long.class, probeHashBlock, position))).retLong();
    } else {
        body.append(thisVariable.getField(lookupSourceField).invoke("getJoinPosition", long.class, position, hashChannelsPage, allChannelsPage)).retLong();
    }
}
Also used : IfStatement(com.facebook.presto.bytecode.control.IfStatement) Variable(com.facebook.presto.bytecode.Variable) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) BytecodeExpression(com.facebook.presto.bytecode.expression.BytecodeExpression)

Aggregations

BytecodeExpression (com.facebook.presto.bytecode.expression.BytecodeExpression)29 Variable (com.facebook.presto.bytecode.Variable)24 MethodDefinition (com.facebook.presto.bytecode.MethodDefinition)23 Parameter (com.facebook.presto.bytecode.Parameter)21 BytecodeBlock (com.facebook.presto.bytecode.BytecodeBlock)18 IfStatement (com.facebook.presto.bytecode.control.IfStatement)14 Block (com.facebook.presto.spi.block.Block)9 Scope (com.facebook.presto.bytecode.Scope)7 LabelNode (com.facebook.presto.bytecode.instruction.LabelNode)5 BlockBuilder (com.facebook.presto.spi.block.BlockBuilder)5 DictionaryBlock (com.facebook.presto.spi.block.DictionaryBlock)5 LazyBlock (com.facebook.presto.spi.block.LazyBlock)5 RunLengthEncodedBlock (com.facebook.presto.spi.block.RunLengthEncodedBlock)5 Type (com.facebook.presto.spi.type.Type)5 ImmutableList (com.google.common.collect.ImmutableList)5 ForLoop (com.facebook.presto.bytecode.control.ForLoop)4 SqlTypeBytecodeExpression.constantType (com.facebook.presto.sql.gen.SqlTypeBytecodeExpression.constantType)4 ClassDefinition (com.facebook.presto.bytecode.ClassDefinition)3 PageBuilder (com.facebook.presto.spi.PageBuilder)3 BytecodeNode (com.facebook.presto.bytecode.BytecodeNode)2