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();
}
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();
}
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();
}
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();
}
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;
}
Aggregations