use of com.facebook.presto.bytecode.expression.BytecodeExpression in project presto by prestodb.
the class JoinCompiler method generateHashRowMethod.
private static void generateHashRowMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> joinChannelTypes) {
Parameter position = arg("position", int.class);
Parameter page = arg("blocks", Page.class);
MethodDefinition hashRowMethod = classDefinition.declareMethod(a(PUBLIC), "hashRow", type(long.class), position, page);
Variable resultVariable = hashRowMethod.getScope().declareVariable(long.class, "result");
hashRowMethod.getBody().push(0L).putVariable(resultVariable);
for (int index = 0; index < joinChannelTypes.size(); index++) {
BytecodeExpression type = constantType(callSiteBinder, joinChannelTypes.get(index));
BytecodeExpression block = page.invoke("getBlock", Block.class, constantInt(index));
hashRowMethod.getBody().getVariable(resultVariable).push(31L).append(OpCode.LMUL).append(typeHashCode(type, block, position)).append(OpCode.LADD).putVariable(resultVariable);
}
hashRowMethod.getBody().getVariable(resultVariable).retLong();
}
use of com.facebook.presto.bytecode.expression.BytecodeExpression in project presto by prestodb.
the class JoinCompiler method generatePositionEqualsPositionMethod.
private static void generatePositionEqualsPositionMethod(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 rightBlockIndex = arg("rightBlockIndex", int.class);
Parameter rightBlockPosition = arg("rightBlockPosition", int.class);
MethodDefinition positionEqualsPositionMethod = classDefinition.declareMethod(a(PUBLIC), ignoreNulls ? "positionEqualsPositionIgnoreNulls" : "positionEqualsPosition", type(boolean.class), leftBlockIndex, leftBlockPosition, rightBlockIndex, rightBlockPosition);
Variable thisVariable = positionEqualsPositionMethod.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 = thisVariable.getField(joinChannelFields.get(index)).invoke("get", Object.class, rightBlockIndex).cast(Block.class);
BytecodeNode equalityCondition;
if (ignoreNulls) {
equalityCondition = typeEqualsIgnoreNulls(type, leftBlock, leftBlockPosition, rightBlock, rightBlockPosition);
} else {
equalityCondition = typeEquals(type, leftBlock, leftBlockPosition, rightBlock, rightBlockPosition);
}
LabelNode checkNextField = new LabelNode("checkNextField");
positionEqualsPositionMethod.getBody().append(equalityCondition).ifTrueGoto(checkNextField).push(false).retBoolean().visitLabel(checkNextField);
}
positionEqualsPositionMethod.getBody().push(true).retInt();
}
use of com.facebook.presto.bytecode.expression.BytecodeExpression in project presto by prestodb.
the class VarArgsToArrayAdapterGenerator method generateVarArgsToArrayAdapter.
public static MethodHandleAndConstructor generateVarArgsToArrayAdapter(Class<?> returnType, Class<?> javaType, int argsLength, MethodHandle function, MethodHandle userStateFactory) {
requireNonNull(returnType, "returnType is null");
requireNonNull(javaType, "javaType is null");
requireNonNull(function, "function is null");
requireNonNull(userStateFactory, "userStateFactory is null");
MethodType methodType = function.type();
Class<?> javaArrayType = toArrayClass(javaType);
checkArgument(methodType.returnType() == returnType, "returnType does not match");
checkArgument(methodType.parameterList().equals(ImmutableList.of(Object.class, javaArrayType)), "parameter types do not match");
CallSiteBinder callSiteBinder = new CallSiteBinder();
ClassDefinition classDefinition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName("VarArgsToListAdapter"), type(Object.class));
classDefinition.declareDefaultConstructor(a(PRIVATE));
// generate userState constructor
MethodDefinition stateFactoryDefinition = classDefinition.declareMethod(a(PUBLIC, STATIC), "createState", type(VarArgsToArrayAdapterState.class));
stateFactoryDefinition.getBody().comment("create userState for current instance").append(newInstance(VarArgsToArrayAdapterState.class, loadConstant(callSiteBinder, userStateFactory, MethodHandle.class).invoke("invokeExact", Object.class), newArray(type(javaArrayType), argsLength).cast(Object.class)).ret());
// generate adapter method
ImmutableList.Builder<Parameter> parameterListBuilder = ImmutableList.builder();
parameterListBuilder.add(arg("userState", VarArgsToArrayAdapterState.class));
for (int i = 0; i < argsLength; i++) {
parameterListBuilder.add(arg("input_" + i, javaType));
}
ImmutableList<Parameter> parameterList = parameterListBuilder.build();
MethodDefinition methodDefinition = classDefinition.declareMethod(a(PUBLIC, STATIC), "varArgsToArray", type(returnType), parameterList);
BytecodeBlock body = methodDefinition.getBody();
BytecodeExpression userState = parameterList.get(0).getField("userState", Object.class);
BytecodeExpression args = parameterList.get(0).getField("args", Object.class).cast(javaArrayType);
for (int i = 0; i < argsLength; i++) {
body.append(args.setElement(i, parameterList.get(i + 1)));
}
body.append(loadConstant(callSiteBinder, function, MethodHandle.class).invoke("invokeExact", returnType, userState, args).ret());
// define class
Class<?> generatedClass = defineClass(classDefinition, Object.class, callSiteBinder.getBindings(), VarArgsToArrayAdapterGenerator.class.getClassLoader());
return new MethodHandleAndConstructor(Reflection.methodHandle(generatedClass, "varArgsToArray", ImmutableList.builder().add(VarArgsToArrayAdapterState.class).addAll(nCopies(argsLength, javaType)).build().toArray(new Class<?>[argsLength])), Reflection.methodHandle(generatedClass, "createState"));
}
use of com.facebook.presto.bytecode.expression.BytecodeExpression in project presto by prestodb.
the class PageProcessorCompiler method invokeProject.
private static BytecodeNode invokeProject(Variable objRef, Variable session, List<? extends Variable> blockVariables, BytecodeExpression position, Variable pageBuilder, BytecodeExpression projectionIndex, MethodDefinition projectionMethod) {
BytecodeExpression blockBuilder = pageBuilder.invoke("getBlockBuilder", BlockBuilder.class, projectionIndex);
List<BytecodeExpression> params = ImmutableList.<BytecodeExpression>builder().add(session).addAll(blockVariables).add(position).add(blockBuilder).build();
return new BytecodeBlock().append(objRef.invoke(projectionMethod, params));
}
use of com.facebook.presto.bytecode.expression.BytecodeExpression in project presto by prestodb.
the class PageProcessorCompiler method getBytecodeFilterOnDictionary.
private static BytecodeBlock getBytecodeFilterOnDictionary(Parameter session, Scope scope, Variable blockVariable) {
Variable position = scope.getVariable("position");
Variable positionCount = scope.getVariable("positionCount");
Variable selectedCount = scope.getVariable("selectedCount");
Variable selectedPositions = scope.getVariable("selectedPositions");
Variable thisVariable = scope.getThis();
BytecodeExpression inputFilterDictionary = thisVariable.getField("inputFilterDictionary", Block.class);
BytecodeExpression filterResult = thisVariable.getField("filterResult", boolean[].class);
BytecodeBlock ifFilterOnDictionaryBlock = new BytecodeBlock();
Variable dictionaryBlock = scope.declareVariable("dictionaryBlock", ifFilterOnDictionaryBlock, blockVariable.cast(DictionaryBlock.class));
Variable dictionary = scope.declareVariable("dictionary", ifFilterOnDictionaryBlock, dictionaryBlock.invoke("getDictionary", Block.class));
Variable dictionaryPositionCount = scope.declareVariable("dictionaryPositionCount", ifFilterOnDictionaryBlock, dictionary.invoke("getPositionCount", int.class));
Variable selectedDictionaryPositions = scope.declareVariable("selectedDictionaryPositions", ifFilterOnDictionaryBlock, newArray(type(boolean[].class), dictionaryPositionCount));
// if cached value is available use it else filter dictionary and cache it
ifFilterOnDictionaryBlock.append(new IfStatement().condition(equal(dictionary, inputFilterDictionary)).ifTrue(selectedDictionaryPositions.set(filterResult)).ifFalse(new BytecodeBlock().append(new ForLoop().initialize(position.set(constantInt(0))).condition(lessThan(position, dictionaryPositionCount)).update(position.increment()).body(selectedDictionaryPositions.setElement(position, invokeFilter(thisVariable, session, singletonList(dictionary), position)))).append(thisVariable.setField("inputFilterDictionary", dictionary)).append(thisVariable.setField("filterResult", selectedDictionaryPositions))));
// create selected positions
ifFilterOnDictionaryBlock.append(new ForLoop().initialize(position.set(constantInt(0))).condition(lessThan(position, positionCount)).update(position.increment()).body(new IfStatement().condition(selectedDictionaryPositions.getElement(dictionaryBlock.invoke("getId", int.class, position))).ifTrue(new BytecodeBlock().append(selectedPositions.setElement(selectedCount, position)).append(selectedCount.increment()))));
// return selectedPositions
ifFilterOnDictionaryBlock.append(invokeStatic(Arrays.class, "copyOf", int[].class, selectedPositions, selectedCount).ret());
return ifFilterOnDictionaryBlock;
}
Aggregations