use of io.airlift.bytecode.control.ForLoop in project trino by trinodb.
the class AccumulatorCompiler method generateAddOrRemoveInputWindowIndex.
private static void generateAddOrRemoveInputWindowIndex(ClassDefinition definition, List<FieldDefinition> stateField, List<Boolean> argumentNullable, List<FieldDefinition> lambdaProviderFields, MethodHandle inputFunction, String generatedFunctionName, CallSiteBinder callSiteBinder) {
// TODO: implement masking based on maskChannel field once Window Functions support DISTINCT arguments to the functions.
Parameter index = arg("index", WindowIndex.class);
Parameter startPosition = arg("startPosition", int.class);
Parameter endPosition = arg("endPosition", int.class);
MethodDefinition method = definition.declareMethod(a(PUBLIC), generatedFunctionName, type(void.class), ImmutableList.of(index, startPosition, endPosition));
Scope scope = method.getScope();
Variable position = scope.declareVariable(int.class, "position");
Binding binding = callSiteBinder.bind(inputFunction);
BytecodeExpression invokeInputFunction = invokeDynamic(BOOTSTRAP_METHOD, ImmutableList.of(binding.getBindingId()), generatedFunctionName, binding.getType(), getInvokeFunctionOnWindowIndexParameters(scope, argumentNullable.size(), lambdaProviderFields, stateField, index, position));
method.getBody().append(new ForLoop().initialize(position.set(startPosition)).condition(BytecodeExpressions.lessThanOrEqual(position, endPosition)).update(position.increment()).body(new IfStatement().condition(anyParametersAreNull(argumentNullable, index, position)).ifFalse(invokeInputFunction))).ret();
}
use of io.airlift.bytecode.control.ForLoop in project trino by trinodb.
the class AccumulatorCompiler method generateInputForLoop.
private static BytecodeBlock generateInputForLoop(Variable arguments, List<FieldDefinition> stateField, List<Boolean> argumentNullable, MethodHandle inputFunction, Scope scope, List<Variable> parameterVariables, List<FieldDefinition> lambdaProviderFields, Variable masksBlock, CallSiteBinder callSiteBinder, boolean grouped) {
// For-loop over rows
Variable positionVariable = scope.declareVariable(int.class, "position");
Variable rowsVariable = scope.declareVariable(int.class, "rows");
BytecodeBlock block = new BytecodeBlock().append(arguments).invokeVirtual(Page.class, "getPositionCount", int.class).putVariable(rowsVariable).initializeVariable(positionVariable);
BytecodeNode loopBody = generateInvokeInputFunction(scope, stateField, positionVariable, parameterVariables, lambdaProviderFields, inputFunction, callSiteBinder, grouped);
// Wrap with null checks
for (int parameterIndex = 0; parameterIndex < parameterVariables.size(); parameterIndex++) {
if (!argumentNullable.get(parameterIndex)) {
Variable variableDefinition = parameterVariables.get(parameterIndex);
loopBody = new IfStatement("if(!%s.isNull(position))", variableDefinition.getName()).condition(new BytecodeBlock().getVariable(variableDefinition).getVariable(positionVariable).invokeInterface(Block.class, "isNull", boolean.class, int.class)).ifFalse(loopBody);
}
}
loopBody = new IfStatement("if(testMask(%s, position))", masksBlock.getName()).condition(new BytecodeBlock().getVariable(masksBlock).getVariable(positionVariable).invokeStatic(CompilerOperations.class, "testMask", boolean.class, Block.class, int.class)).ifTrue(loopBody);
ForLoop forLoop = new ForLoop().initialize(new BytecodeBlock().putVariable(positionVariable, 0)).condition(new BytecodeBlock().getVariable(positionVariable).getVariable(rowsVariable).invokeStatic(CompilerOperations.class, "lessThan", boolean.class, int.class, int.class)).update(new BytecodeBlock().incrementVariable(positionVariable, (byte) 1)).body(loopBody);
block.append(new IfStatement("if(!maskGuaranteedToFilterAllRows(%s, %s))", rowsVariable.getName(), masksBlock.getName()).condition(new BytecodeBlock().getVariable(rowsVariable).getVariable(masksBlock).invokeStatic(AggregationUtils.class, "maskGuaranteedToFilterAllRows", boolean.class, int.class, Block.class)).ifFalse(forLoop));
return block;
}
use of io.airlift.bytecode.control.ForLoop in project trino by trinodb.
the class PageFunctionCompiler method generateProcessMethod.
private static MethodDefinition generateProcessMethod(ClassDefinition classDefinition, FieldDefinition blockBuilder, FieldDefinition session, FieldDefinition page, FieldDefinition selectedPositions, FieldDefinition nextIndexOrPosition, FieldDefinition result) {
MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), "process", type(boolean.class), ImmutableList.of());
Scope scope = method.getScope();
Variable thisVariable = method.getThis();
BytecodeBlock body = method.getBody();
Variable from = scope.declareVariable("from", body, thisVariable.getField(nextIndexOrPosition));
Variable to = scope.declareVariable("to", body, add(thisVariable.getField(selectedPositions).invoke("getOffset", int.class), thisVariable.getField(selectedPositions).invoke("size", int.class)));
Variable positions = scope.declareVariable(int[].class, "positions");
Variable index = scope.declareVariable(int.class, "index");
IfStatement ifStatement = new IfStatement().condition(thisVariable.getField(selectedPositions).invoke("isList", boolean.class));
body.append(ifStatement);
ifStatement.ifTrue(new BytecodeBlock().append(positions.set(thisVariable.getField(selectedPositions).invoke("getPositions", int[].class))).append(new ForLoop("positions loop").initialize(index.set(from)).condition(lessThan(index, to)).update(index.increment()).body(new BytecodeBlock().append(thisVariable.invoke("evaluate", void.class, thisVariable.getField(session), thisVariable.getField(page), positions.getElement(index))))));
ifStatement.ifFalse(new ForLoop("range based loop").initialize(index.set(from)).condition(lessThan(index, to)).update(index.increment()).body(new BytecodeBlock().append(thisVariable.invoke("evaluate", void.class, thisVariable.getField(session), thisVariable.getField(page), index))));
body.comment("result = this.blockBuilder.build(); return true;").append(thisVariable.setField(result, thisVariable.getField(blockBuilder).invoke("build", Block.class))).push(true).retBoolean();
return method;
}
use of io.airlift.bytecode.control.ForLoop in project trino by trinodb.
the class PageFunctionCompiler method generatePageFilterMethod.
private static MethodDefinition generatePageFilterMethod(ClassDefinition classDefinition, FieldDefinition selectedPositionsField) {
Parameter session = arg("session", ConnectorSession.class);
Parameter page = arg("page", Page.class);
MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), "filter", type(SelectedPositions.class), ImmutableList.<Parameter>builder().add(session).add(page).build());
Scope scope = method.getScope();
Variable thisVariable = method.getThis();
BytecodeBlock body = method.getBody();
Variable positionCount = scope.declareVariable("positionCount", body, page.invoke("getPositionCount", int.class));
body.append(new IfStatement("grow selectedPositions if necessary").condition(lessThan(thisVariable.getField(selectedPositionsField).length(), positionCount)).ifTrue(thisVariable.setField(selectedPositionsField, newArray(type(boolean[].class), positionCount))));
Variable selectedPositions = scope.declareVariable("selectedPositions", body, thisVariable.getField(selectedPositionsField));
Variable position = scope.declareVariable(int.class, "position");
body.append(new ForLoop().initialize(position.set(constantInt(0))).condition(lessThan(position, positionCount)).update(position.increment()).body(selectedPositions.setElement(position, thisVariable.invoke("filter", boolean.class, session, page, position))));
body.append(invokeStatic(PageFilter.class, "positionsArrayToSelectedPositions", SelectedPositions.class, selectedPositions, positionCount).ret());
return method;
}
use of io.airlift.bytecode.control.ForLoop in project trino by trinodb.
the class JoinCompiler method generateConstructor.
private static void generateConstructor(ClassDefinition classDefinition, List<Integer> joinChannels, FieldDefinition sizeField, FieldDefinition instanceSizeField, List<FieldDefinition> channelFields, List<FieldDefinition> joinChannelFields, FieldDefinition hashChannelField) {
Parameter channels = arg("channels", type(List.class, type(List.class, Block.class)));
Parameter hashChannel = arg("hashChannel", type(OptionalInt.class));
MethodDefinition constructorDefinition = classDefinition.declareConstructor(a(PUBLIC), channels, hashChannel);
Variable thisVariable = constructorDefinition.getThis();
Variable blockIndex = constructorDefinition.getScope().declareVariable(int.class, "blockIndex");
BytecodeBlock constructor = constructorDefinition.getBody().comment("super();").append(thisVariable).invokeConstructor(Object.class);
constructor.comment("this.size = INSTANCE_SIZE").append(thisVariable.setField(sizeField, getStatic(instanceSizeField)));
constructor.comment("Set channel fields");
for (int index = 0; index < channelFields.size(); index++) {
BytecodeExpression channel = channels.invoke("get", Object.class, constantInt(index)).cast(type(List.class, Block.class));
constructor.append(thisVariable.setField(channelFields.get(index), channel));
BytecodeBlock loopBody = new BytecodeBlock();
constructor.comment("for(blockIndex = 0; blockIndex < channel.size(); blockIndex++) { size += channel.get(i).getRetainedSizeInBytes() }").append(new ForLoop().initialize(blockIndex.set(constantInt(0))).condition(new BytecodeBlock().append(blockIndex).append(channel.invoke("size", int.class)).invokeStatic(CompilerOperations.class, "lessThan", boolean.class, int.class, int.class)).update(new BytecodeBlock().incrementVariable(blockIndex, (byte) 1)).body(loopBody));
loopBody.append(thisVariable).append(thisVariable).getField(sizeField).append(channel.invoke("get", Object.class, blockIndex).cast(type(Block.class)).invoke("getRetainedSizeInBytes", long.class)).longAdd().putField(sizeField);
}
constructor.comment("Set join channel fields");
for (int index = 0; index < joinChannelFields.size(); index++) {
BytecodeExpression joinChannel = channels.invoke("get", Object.class, constantInt(joinChannels.get(index))).cast(type(List.class, Block.class));
constructor.append(thisVariable.setField(joinChannelFields.get(index), joinChannel));
}
constructor.comment("Set hashChannel");
constructor.append(new IfStatement().condition(hashChannel.invoke("isPresent", boolean.class)).ifTrue(thisVariable.setField(hashChannelField, channels.invoke("get", Object.class, hashChannel.invoke("getAsInt", int.class)))).ifFalse(thisVariable.setField(hashChannelField, constantNull(hashChannelField.getType()))));
constructor.ret();
}
Aggregations