use of com.facebook.presto.bytecode.Parameter in project presto by prestodb.
the class JoinProbeCompiler method internalCompileJoinOperatorFactory.
@VisibleForTesting
public HashJoinOperatorFactoryFactory internalCompileJoinOperatorFactory(List<Type> types, List<Integer> probeOutputChannels, List<Integer> probeJoinChannel, Optional<Integer> probeHashChannel) {
Class<? extends JoinProbe> joinProbeClass = compileJoinProbe(types, probeOutputChannels, probeJoinChannel, probeHashChannel);
ClassDefinition classDefinition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName("JoinProbeFactory"), type(Object.class), type(JoinProbeFactory.class));
classDefinition.declareDefaultConstructor(a(PUBLIC));
Parameter lookupSource = arg("lookupSource", LookupSource.class);
Parameter page = arg("page", Page.class);
MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), "createJoinProbe", type(JoinProbe.class), lookupSource, page);
method.getBody().newObject(joinProbeClass).dup().append(lookupSource).append(page).invokeConstructor(joinProbeClass, LookupSource.class, Page.class).retObject();
DynamicClassLoader classLoader = new DynamicClassLoader(joinProbeClass.getClassLoader());
JoinProbeFactory joinProbeFactory;
if (probeJoinChannel.isEmpty()) {
// see comment in PagesIndex#createLookupSource
joinProbeFactory = new SimpleJoinProbe.SimpleJoinProbeFactory(types, probeOutputChannels, probeJoinChannel, probeHashChannel);
} else {
Class<? extends JoinProbeFactory> joinProbeFactoryClass = defineClass(classDefinition, JoinProbeFactory.class, classLoader);
try {
joinProbeFactory = joinProbeFactoryClass.newInstance();
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
Class<? extends OperatorFactory> operatorFactoryClass = IsolatedClass.isolateClass(classLoader, OperatorFactory.class, LookupJoinOperatorFactory.class, LookupJoinOperator.class);
return new HashJoinOperatorFactoryFactory(joinProbeFactory, operatorFactoryClass);
}
use of com.facebook.presto.bytecode.Parameter in project presto by prestodb.
the class JoinCompiler method generateRowEqualsRowMethod.
private static void generateRowEqualsRowMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> joinChannelTypes) {
Parameter leftPosition = arg("leftPosition", int.class);
Parameter leftPage = arg("leftPage", Page.class);
Parameter rightPosition = arg("rightPosition", int.class);
Parameter rightPage = arg("rightPage", Page.class);
MethodDefinition rowEqualsRowMethod = classDefinition.declareMethod(a(PUBLIC), "rowEqualsRow", type(boolean.class), leftPosition, leftPage, rightPosition, rightPage);
for (int index = 0; index < joinChannelTypes.size(); index++) {
BytecodeExpression type = constantType(callSiteBinder, joinChannelTypes.get(index));
BytecodeExpression leftBlock = leftPage.invoke("getBlock", Block.class, constantInt(index));
BytecodeExpression rightBlock = rightPage.invoke("getBlock", Block.class, constantInt(index));
LabelNode checkNextField = new LabelNode("checkNextField");
rowEqualsRowMethod.getBody().append(typeEquals(type, leftBlock, leftPosition, rightBlock, rightPosition)).ifTrueGoto(checkNextField).push(false).retBoolean().visitLabel(checkNextField);
}
rowEqualsRowMethod.getBody().push(true).retInt();
}
use of com.facebook.presto.bytecode.Parameter in project presto by prestodb.
the class JoinCompiler method generatePositionEqualsRowMethod.
private static void generatePositionEqualsRowMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> joinChannelTypes, List<FieldDefinition> joinChannelFields, boolean ignoreNulls) {
Parameter leftBlockIndex = arg("leftBlockIndex", int.class);
Parameter leftBlockPosition = arg("leftBlockPosition", int.class);
Parameter rightPosition = arg("rightPosition", int.class);
Parameter rightPage = arg("rightPage", Page.class);
MethodDefinition positionEqualsRowMethod = classDefinition.declareMethod(a(PUBLIC), ignoreNulls ? "positionEqualsRowIgnoreNulls" : "positionEqualsRow", type(boolean.class), leftBlockIndex, leftBlockPosition, rightPosition, rightPage);
Variable thisVariable = positionEqualsRowMethod.getThis();
for (int index = 0; index < joinChannelTypes.size(); index++) {
BytecodeExpression type = constantType(callSiteBinder, joinChannelTypes.get(index));
BytecodeExpression leftBlock = thisVariable.getField(joinChannelFields.get(index)).invoke("get", Object.class, leftBlockIndex).cast(Block.class);
BytecodeExpression rightBlock = rightPage.invoke("getBlock", Block.class, constantInt(index));
BytecodeNode equalityCondition;
if (ignoreNulls) {
equalityCondition = typeEqualsIgnoreNulls(type, leftBlock, leftBlockPosition, rightBlock, rightPosition);
} else {
equalityCondition = typeEquals(type, leftBlock, leftBlockPosition, rightBlock, rightPosition);
}
LabelNode checkNextField = new LabelNode("checkNextField");
positionEqualsRowMethod.getBody().append(equalityCondition).ifTrueGoto(checkNextField).push(false).retBoolean().visitLabel(checkNextField);
}
positionEqualsRowMethod.getBody().push(true).retInt();
}
use of com.facebook.presto.bytecode.Parameter in project presto by prestodb.
the class JoinCompiler method generateHashPositionMethod.
private static void generateHashPositionMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> joinChannelTypes, List<FieldDefinition> joinChannelFields, FieldDefinition hashChannelField) {
Parameter blockIndex = arg("blockIndex", int.class);
Parameter blockPosition = arg("blockPosition", int.class);
MethodDefinition hashPositionMethod = classDefinition.declareMethod(a(PUBLIC), "hashPosition", type(long.class), blockIndex, blockPosition);
Variable thisVariable = hashPositionMethod.getThis();
BytecodeExpression hashChannel = thisVariable.getField(hashChannelField);
BytecodeExpression bigintType = constantType(callSiteBinder, BigintType.BIGINT);
IfStatement ifStatement = new IfStatement();
ifStatement.condition(notEqual(hashChannel, constantNull(hashChannelField.getType())));
ifStatement.ifTrue(bigintType.invoke("getLong", long.class, hashChannel.invoke("get", Object.class, blockIndex).cast(Block.class), blockPosition).ret());
hashPositionMethod.getBody().append(ifStatement);
Variable resultVariable = hashPositionMethod.getScope().declareVariable(long.class, "result");
hashPositionMethod.getBody().push(0L).putVariable(resultVariable);
for (int index = 0; index < joinChannelTypes.size(); index++) {
BytecodeExpression type = constantType(callSiteBinder, joinChannelTypes.get(index));
BytecodeExpression block = hashPositionMethod.getThis().getField(joinChannelFields.get(index)).invoke("get", Object.class, blockIndex).cast(Block.class);
hashPositionMethod.getBody().getVariable(resultVariable).push(31L).append(OpCode.LMUL).append(typeHashCode(type, block, blockPosition)).append(OpCode.LADD).putVariable(resultVariable);
}
hashPositionMethod.getBody().getVariable(resultVariable).retLong();
}
use of com.facebook.presto.bytecode.Parameter in project presto by prestodb.
the class JoinCompiler method generateConstructor.
private static void generateConstructor(ClassDefinition classDefinition, List<Integer> joinChannels, FieldDefinition sizeField, 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(Optional.class, Integer.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 = 0").append(thisVariable.setField(sizeField, constantLong(0L)));
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", int.class).cast(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("get", Object.class).cast(Integer.class).cast(int.class)))).ifFalse(thisVariable.setField(hashChannelField, constantNull(hashChannelField.getType()))));
constructor.ret();
}
Aggregations