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