Search in sources :

Example 1 with MethodDefinition

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

the class AbstractMinMaxBy method generateInputMethod.

private void generateInputMethod(ClassDefinition definition, CallSiteBinder binder, MethodHandle compareMethod, Type keyType, Type valueType, Class<?> stateClass) {
    Parameter state = arg("state", stateClass);
    Parameter value = arg("value", Block.class);
    Parameter key = arg("key", Block.class);
    Parameter position = arg("position", int.class);
    MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "input", type(void.class), state, value, key, position);
    if (keyType.equals(UNKNOWN)) {
        method.getBody().ret();
        return;
    }
    SqlTypeBytecodeExpression keySqlType = constantType(binder, keyType);
    BytecodeBlock ifBlock = new BytecodeBlock().append(state.invoke("setFirst", void.class, keySqlType.getValue(key, position))).append(state.invoke("setFirstNull", void.class, constantBoolean(false))).append(state.invoke("setSecondNull", void.class, value.invoke("isNull", boolean.class, position)));
    if (!valueType.equals(UNKNOWN)) {
        SqlTypeBytecodeExpression valueSqlType = constantType(binder, valueType);
        ifBlock.append(new IfStatement().condition(value.invoke("isNull", boolean.class, position)).ifFalse(state.invoke("setSecond", void.class, valueSqlType.getValue(value, position))));
    }
    method.getBody().append(new IfStatement().condition(or(state.invoke("isFirstNull", boolean.class), and(not(key.invoke("isNull", boolean.class, position)), loadConstant(binder, compareMethod, MethodHandle.class).invoke("invokeExact", boolean.class, keySqlType.getValue(key, position), state.invoke("getFirst", keyType.getJavaType()))))).ifTrue(ifBlock)).ret();
}
Also used : IfStatement(com.facebook.presto.bytecode.control.IfStatement) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Parameter(com.facebook.presto.bytecode.Parameter) Signature.orderableTypeParameter(com.facebook.presto.metadata.Signature.orderableTypeParameter) SqlTypeBytecodeExpression(com.facebook.presto.sql.gen.SqlTypeBytecodeExpression) MethodHandle(java.lang.invoke.MethodHandle)

Example 2 with MethodDefinition

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

the class AbstractMinMaxBy method generateCombineMethod.

private void generateCombineMethod(ClassDefinition definition, CallSiteBinder binder, MethodHandle compareMethod, Type keyType, Type valueType, Class<?> stateClass) {
    Parameter state = arg("state", stateClass);
    Parameter otherState = arg("otherState", stateClass);
    MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "combine", type(void.class), state, otherState);
    if (keyType.equals(UNKNOWN)) {
        method.getBody().ret();
        return;
    }
    Class<?> keyJavaType = keyType.getJavaType();
    BytecodeBlock ifBlock = new BytecodeBlock().append(state.invoke("setFirst", void.class, otherState.invoke("getFirst", keyJavaType))).append(state.invoke("setFirstNull", void.class, otherState.invoke("isFirstNull", boolean.class))).append(state.invoke("setSecondNull", void.class, otherState.invoke("isSecondNull", boolean.class)));
    if (!valueType.equals(UNKNOWN)) {
        ifBlock.append(state.invoke("setSecond", void.class, otherState.invoke("getSecond", valueType.getJavaType())));
    }
    method.getBody().append(new IfStatement().condition(or(state.invoke("isFirstNull", boolean.class), and(not(otherState.invoke("isFirstNull", boolean.class)), loadConstant(binder, compareMethod, MethodHandle.class).invoke("invokeExact", boolean.class, otherState.invoke("getFirst", keyJavaType), state.invoke("getFirst", keyJavaType))))).ifTrue(ifBlock)).ret();
}
Also used : IfStatement(com.facebook.presto.bytecode.control.IfStatement) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Parameter(com.facebook.presto.bytecode.Parameter) Signature.orderableTypeParameter(com.facebook.presto.metadata.Signature.orderableTypeParameter) MethodHandle(java.lang.invoke.MethodHandle)

Example 3 with MethodDefinition

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

the class AccumulatorCompiler method generateAddIntermediateAsCombine.

private static void generateAddIntermediateAsCombine(ClassDefinition definition, FieldDefinition stateField, FieldDefinition stateSerializerField, FieldDefinition stateFactoryField, MethodHandle combineFunction, Class<?> singleStateClass, CallSiteBinder callSiteBinder, boolean grouped) {
    MethodDefinition method = declareAddIntermediate(definition, grouped);
    Scope scope = method.getScope();
    BytecodeBlock body = method.getBody();
    Variable thisVariable = method.getThis();
    Variable block = scope.getVariable("block");
    Variable scratchState = scope.declareVariable(singleStateClass, "scratchState");
    Variable position = scope.declareVariable(int.class, "position");
    body.comment("scratchState = stateFactory.createSingleState();").append(thisVariable.getField(stateFactoryField)).invokeInterface(AccumulatorStateFactory.class, "createSingleState", Object.class).checkCast(scratchState.getType()).putVariable(scratchState);
    if (grouped) {
        generateEnsureCapacity(scope, stateField, body);
    }
    BytecodeBlock loopBody = new BytecodeBlock();
    if (grouped) {
        Variable groupIdsBlock = scope.getVariable("groupIdsBlock");
        loopBody.append(thisVariable.getField(stateField).invoke("setGroupId", void.class, groupIdsBlock.invoke("getGroupId", long.class, position)));
    }
    loopBody.append(thisVariable.getField(stateSerializerField).invoke("deserialize", void.class, block, position, scratchState.cast(Object.class)));
    loopBody.comment("combine(state, scratchState)").append(thisVariable.getField(stateField)).append(scratchState).append(invoke(callSiteBinder.bind(combineFunction), "combine"));
    if (grouped) {
        // skip rows with null group id
        IfStatement ifStatement = new IfStatement("if (!groupIdsBlock.isNull(position))").condition(not(scope.getVariable("groupIdsBlock").invoke("isNull", boolean.class, position))).ifTrue(loopBody);
        loopBody = new BytecodeBlock().append(ifStatement);
    }
    body.append(generateBlockNonNullPositionForLoop(scope, position, loopBody)).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)

Example 4 with MethodDefinition

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

the class AccumulatorCompiler method generateAddInput.

private static void generateAddInput(ClassDefinition definition, FieldDefinition stateField, FieldDefinition inputChannelsField, FieldDefinition maskChannelField, List<ParameterMetadata> parameterMetadatas, MethodHandle inputFunction, CallSiteBinder callSiteBinder, boolean grouped) {
    ImmutableList.Builder<Parameter> parameters = ImmutableList.builder();
    if (grouped) {
        parameters.add(arg("groupIdsBlock", GroupByIdBlock.class));
    }
    Parameter page = arg("page", Page.class);
    parameters.add(page);
    MethodDefinition method = definition.declareMethod(a(PUBLIC), "addInput", type(void.class), parameters.build());
    Scope scope = method.getScope();
    BytecodeBlock body = method.getBody();
    Variable thisVariable = method.getThis();
    if (grouped) {
        generateEnsureCapacity(scope, stateField, body);
    }
    List<Variable> parameterVariables = new ArrayList<>();
    for (int i = 0; i < countInputChannels(parameterMetadatas); i++) {
        parameterVariables.add(scope.declareVariable(Block.class, "block" + i));
    }
    Variable masksBlock = scope.declareVariable(Block.class, "masksBlock");
    body.comment("masksBlock = maskChannel.map(page.blockGetter()).orElse(null);").append(thisVariable.getField(maskChannelField)).append(page).invokeStatic(type(AggregationUtils.class), "pageBlockGetter", type(Function.class, Integer.class, Block.class), type(Page.class)).invokeVirtual(Optional.class, "map", Optional.class, Function.class).pushNull().invokeVirtual(Optional.class, "orElse", Object.class, Object.class).checkCast(Block.class).putVariable(masksBlock);
    // Get all parameter blocks
    for (int i = 0; i < countInputChannels(parameterMetadatas); i++) {
        body.comment("%s = page.getBlock(inputChannels.get(%d));", parameterVariables.get(i).getName(), i).append(page).append(thisVariable.getField(inputChannelsField)).push(i).invokeInterface(List.class, "get", Object.class, int.class).checkCast(Integer.class).invokeVirtual(Integer.class, "intValue", int.class).invokeVirtual(Page.class, "getBlock", Block.class, int.class).putVariable(parameterVariables.get(i));
    }
    BytecodeBlock block = generateInputForLoop(stateField, parameterMetadatas, inputFunction, scope, parameterVariables, masksBlock, callSiteBinder, grouped);
    body.append(block);
    body.ret();
}
Also used : GroupByIdBlock(com.facebook.presto.operator.GroupByIdBlock) Variable(com.facebook.presto.bytecode.Variable) ImmutableList(com.google.common.collect.ImmutableList) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) ArrayList(java.util.ArrayList) Page(com.facebook.presto.spi.Page) 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) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) GroupByIdBlock(com.facebook.presto.operator.GroupByIdBlock)

Example 5 with MethodDefinition

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

the class AccumulatorCompiler method generateGetFinalType.

private static MethodDefinition generateGetFinalType(ClassDefinition definition, CallSiteBinder callSiteBinder, Type type) {
    MethodDefinition methodDefinition = definition.declareMethod(a(PUBLIC), "getFinalType", type(Type.class));
    methodDefinition.getBody().append(constantType(callSiteBinder, type)).retObject();
    return methodDefinition;
}
Also used : Type(com.facebook.presto.spi.type.Type) SqlTypeBytecodeExpression.constantType(com.facebook.presto.sql.gen.SqlTypeBytecodeExpression.constantType) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition)

Aggregations

MethodDefinition (com.facebook.presto.bytecode.MethodDefinition)74 Parameter (com.facebook.presto.bytecode.Parameter)56 Variable (com.facebook.presto.bytecode.Variable)54 BytecodeBlock (com.facebook.presto.bytecode.BytecodeBlock)45 Scope (com.facebook.presto.bytecode.Scope)30 IfStatement (com.facebook.presto.bytecode.control.IfStatement)27 BytecodeExpression (com.facebook.presto.bytecode.expression.BytecodeExpression)24 Block (com.facebook.presto.spi.block.Block)20 ImmutableList (com.google.common.collect.ImmutableList)16 ClassDefinition (com.facebook.presto.bytecode.ClassDefinition)14 FieldDefinition (com.facebook.presto.bytecode.FieldDefinition)11 BytecodeNode (com.facebook.presto.bytecode.BytecodeNode)10 Type (com.facebook.presto.spi.type.Type)10 ForLoop (com.facebook.presto.bytecode.control.ForLoop)9 LabelNode (com.facebook.presto.bytecode.instruction.LabelNode)9 BlockBuilder (com.facebook.presto.spi.block.BlockBuilder)9 DictionaryBlock (com.facebook.presto.spi.block.DictionaryBlock)9 LazyBlock (com.facebook.presto.spi.block.LazyBlock)9 RunLengthEncodedBlock (com.facebook.presto.spi.block.RunLengthEncodedBlock)9 List (java.util.List)9