Search in sources :

Example 16 with ClassDefinition

use of io.airlift.bytecode.ClassDefinition in project hetu-core by openlookeng.

the class MapFilterFunction method generateFilter.

private static MethodHandle generateFilter(MapType mapType) {
    CallSiteBinder binder = new CallSiteBinder();
    Type keyType = mapType.getKeyType();
    Type valueType = mapType.getValueType();
    Class<?> keyJavaType = Primitives.wrap(keyType.getJavaType());
    Class<?> valueJavaType = Primitives.wrap(valueType.getJavaType());
    ClassDefinition definition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName("MapFilter"), type(Object.class));
    definition.declareDefaultConstructor(a(PRIVATE));
    Parameter state = arg("state", Object.class);
    Parameter block = arg("block", Block.class);
    Parameter function = arg("function", BinaryFunctionInterface.class);
    MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "filter", type(Block.class), ImmutableList.of(state, block, function));
    BytecodeBlock body = method.getBody();
    Scope scope = method.getScope();
    Variable positionCount = scope.declareVariable(int.class, "positionCount");
    Variable position = scope.declareVariable(int.class, "position");
    Variable pageBuilder = scope.declareVariable(PageBuilder.class, "pageBuilder");
    Variable mapBlockBuilder = scope.declareVariable(BlockBuilder.class, "mapBlockBuilder");
    Variable singleMapBlockWriter = scope.declareVariable(BlockBuilder.class, "singleMapBlockWriter");
    Variable keyElement = scope.declareVariable(keyJavaType, "keyElement");
    Variable valueElement = scope.declareVariable(valueJavaType, "valueElement");
    Variable keep = scope.declareVariable(Boolean.class, "keep");
    // invoke block.getPositionCount()
    body.append(positionCount.set(block.invoke("getPositionCount", int.class)));
    // prepare the single map block builder
    body.append(pageBuilder.set(state.cast(PageBuilder.class)));
    body.append(new IfStatement().condition(pageBuilder.invoke("isFull", boolean.class)).ifTrue(pageBuilder.invoke("reset", void.class)));
    body.append(mapBlockBuilder.set(pageBuilder.invoke("getBlockBuilder", BlockBuilder.class, constantInt(0))));
    body.append(singleMapBlockWriter.set(mapBlockBuilder.invoke("beginBlockEntry", BlockBuilder.class)));
    SqlTypeBytecodeExpression keySqlType = constantType(binder, keyType);
    BytecodeNode loadKeyElement;
    if (!keyType.equals(UNKNOWN)) {
        // key element must be non-null
        loadKeyElement = new BytecodeBlock().append(keyElement.set(keySqlType.getValue(block, position).cast(keyJavaType)));
    } else {
        loadKeyElement = new BytecodeBlock().append(keyElement.set(constantNull(keyJavaType)));
    }
    SqlTypeBytecodeExpression valueSqlType = constantType(binder, valueType);
    BytecodeNode loadValueElement;
    if (!valueType.equals(UNKNOWN)) {
        loadValueElement = new IfStatement().condition(block.invoke("isNull", boolean.class, add(position, constantInt(1)))).ifTrue(valueElement.set(constantNull(valueJavaType))).ifFalse(valueElement.set(valueSqlType.getValue(block, add(position, constantInt(1))).cast(valueJavaType)));
    } else {
        loadValueElement = new BytecodeBlock().append(valueElement.set(constantNull(valueJavaType)));
    }
    body.append(new ForLoop().initialize(position.set(constantInt(0))).condition(lessThan(position, positionCount)).update(incrementVariable(position, (byte) 2)).body(new BytecodeBlock().append(loadKeyElement).append(loadValueElement).append(keep.set(function.invoke("apply", Object.class, keyElement.cast(Object.class), valueElement.cast(Object.class)).cast(Boolean.class))).append(new IfStatement("if (keep != null && keep) ...").condition(and(notEqual(keep, constantNull(Boolean.class)), keep.cast(boolean.class))).ifTrue(new BytecodeBlock().append(keySqlType.invoke("appendTo", void.class, block, position, singleMapBlockWriter)).append(valueSqlType.invoke("appendTo", void.class, block, add(position, constantInt(1)), singleMapBlockWriter))))));
    body.append(mapBlockBuilder.invoke("closeEntry", BlockBuilder.class).pop());
    body.append(pageBuilder.invoke("declarePosition", void.class));
    body.append(constantType(binder, mapType).invoke("getObject", Object.class, mapBlockBuilder.cast(Block.class), subtract(mapBlockBuilder.invoke("getPositionCount", int.class), constantInt(1))).ret());
    Class<?> generatedClass = defineClass(definition, Object.class, binder.getBindings(), MapFilterFunction.class.getClassLoader());
    return methodHandle(generatedClass, "filter", Object.class, Block.class, BinaryFunctionInterface.class);
}
Also used : Variable(io.airlift.bytecode.Variable) VariableInstruction.incrementVariable(io.airlift.bytecode.instruction.VariableInstruction.incrementVariable) Signature.typeVariable(io.prestosql.spi.function.Signature.typeVariable) ForLoop(io.airlift.bytecode.control.ForLoop) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) ClassDefinition(io.airlift.bytecode.ClassDefinition) IfStatement(io.airlift.bytecode.control.IfStatement) SqlTypeBytecodeExpression.constantType(io.prestosql.sql.gen.SqlTypeBytecodeExpression.constantType) Type(io.prestosql.spi.type.Type) MapType(io.prestosql.spi.type.MapType) Scope(io.airlift.bytecode.Scope) MethodDefinition(io.airlift.bytecode.MethodDefinition) CallSiteBinder(io.prestosql.sql.gen.CallSiteBinder) TypeSignatureParameter(io.prestosql.spi.type.TypeSignatureParameter) Parameter(io.airlift.bytecode.Parameter) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) Block(io.prestosql.spi.block.Block) BytecodeNode(io.airlift.bytecode.BytecodeNode) SqlTypeBytecodeExpression(io.prestosql.sql.gen.SqlTypeBytecodeExpression)

Example 17 with ClassDefinition

use of io.airlift.bytecode.ClassDefinition in project hetu-core by openlookeng.

the class MapTransformValueFunction method generateTransform.

private static MethodHandle generateTransform(Type keyType, Type valueType, Type transformedValueType, Type resultMapType) {
    CallSiteBinder binder = new CallSiteBinder();
    Class<?> keyJavaType = Primitives.wrap(keyType.getJavaType());
    Class<?> valueJavaType = Primitives.wrap(valueType.getJavaType());
    Class<?> transformedValueJavaType = Primitives.wrap(transformedValueType.getJavaType());
    ClassDefinition definition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName("MapTransformValue"), type(Object.class));
    definition.declareDefaultConstructor(a(PRIVATE));
    // define transform method
    Parameter state = arg("state", Object.class);
    Parameter block = arg("block", Block.class);
    Parameter function = arg("function", BinaryFunctionInterface.class);
    MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "transform", type(Block.class), ImmutableList.of(state, block, function));
    BytecodeBlock body = method.getBody();
    Scope scope = method.getScope();
    Variable positionCount = scope.declareVariable(int.class, "positionCount");
    Variable position = scope.declareVariable(int.class, "position");
    Variable pageBuilder = scope.declareVariable(PageBuilder.class, "pageBuilder");
    Variable mapBlockBuilder = scope.declareVariable(BlockBuilder.class, "mapBlockBuilder");
    Variable blockBuilder = scope.declareVariable(BlockBuilder.class, "blockBuilder");
    Variable keyElement = scope.declareVariable(keyJavaType, "keyElement");
    Variable valueElement = scope.declareVariable(valueJavaType, "valueElement");
    Variable transformedValueElement = scope.declareVariable(transformedValueJavaType, "transformedValueElement");
    // invoke block.getPositionCount()
    body.append(positionCount.set(block.invoke("getPositionCount", int.class)));
    // prepare the single map block builder
    body.append(pageBuilder.set(state.cast(PageBuilder.class)));
    body.append(new IfStatement().condition(pageBuilder.invoke("isFull", boolean.class)).ifTrue(pageBuilder.invoke("reset", void.class)));
    body.append(mapBlockBuilder.set(pageBuilder.invoke("getBlockBuilder", BlockBuilder.class, constantInt(0))));
    body.append(blockBuilder.set(mapBlockBuilder.invoke("beginBlockEntry", BlockBuilder.class)));
    // throw null key exception block
    BytecodeNode throwNullKeyException = new BytecodeBlock().append(newInstance(PrestoException.class, getStatic(INVALID_FUNCTION_ARGUMENT.getDeclaringClass(), "INVALID_FUNCTION_ARGUMENT").cast(ErrorCodeSupplier.class), constantString("map key cannot be null"))).throwObject();
    SqlTypeBytecodeExpression keySqlType = constantType(binder, keyType);
    BytecodeNode loadKeyElement;
    if (!keyType.equals(UNKNOWN)) {
        loadKeyElement = new BytecodeBlock().append(keyElement.set(keySqlType.getValue(block, position).cast(keyJavaType)));
    } else {
        // make sure invokeExact will not take uninitialized keys during compile time
        // but if we reach this point during runtime, it is an exception
        // also close the block builder before throwing as we may be in a TRY() call
        // so that subsequent calls do not find it in an inconsistent state
        loadKeyElement = new BytecodeBlock().append(mapBlockBuilder.invoke("closeEntry", BlockBuilder.class).pop()).append(keyElement.set(constantNull(keyJavaType))).append(throwNullKeyException);
    }
    SqlTypeBytecodeExpression valueSqlType = constantType(binder, valueType);
    BytecodeNode loadValueElement;
    if (!valueType.equals(UNKNOWN)) {
        loadValueElement = new IfStatement().condition(block.invoke("isNull", boolean.class, add(position, constantInt(1)))).ifTrue(valueElement.set(constantNull(valueJavaType))).ifFalse(valueElement.set(valueSqlType.getValue(block, add(position, constantInt(1))).cast(valueJavaType)));
    } else {
        loadValueElement = new BytecodeBlock().append(valueElement.set(constantNull(valueJavaType)));
    }
    BytecodeNode writeTransformedValueElement;
    if (!transformedValueType.equals(UNKNOWN)) {
        writeTransformedValueElement = new IfStatement().condition(equal(transformedValueElement, constantNull(transformedValueJavaType))).ifTrue(blockBuilder.invoke("appendNull", BlockBuilder.class).pop()).ifFalse(constantType(binder, transformedValueType).writeValue(blockBuilder, transformedValueElement.cast(transformedValueType.getJavaType())));
    } else {
        writeTransformedValueElement = new BytecodeBlock().append(blockBuilder.invoke("appendNull", BlockBuilder.class).pop());
    }
    body.append(new ForLoop().initialize(position.set(constantInt(0))).condition(lessThan(position, positionCount)).update(incrementVariable(position, (byte) 2)).body(new BytecodeBlock().append(loadKeyElement).append(loadValueElement).append(transformedValueElement.set(function.invoke("apply", Object.class, keyElement.cast(Object.class), valueElement.cast(Object.class)).cast(transformedValueJavaType))).append(keySqlType.invoke("appendTo", void.class, block, position, blockBuilder)).append(writeTransformedValueElement)));
    body.append(mapBlockBuilder.invoke("closeEntry", BlockBuilder.class).pop());
    body.append(pageBuilder.invoke("declarePosition", void.class));
    body.append(constantType(binder, resultMapType).invoke("getObject", Object.class, mapBlockBuilder.cast(Block.class), subtract(mapBlockBuilder.invoke("getPositionCount", int.class), constantInt(1))).ret());
    Class<?> generatedClass = defineClass(definition, Object.class, binder.getBindings(), MapTransformValueFunction.class.getClassLoader());
    return methodHandle(generatedClass, "transform", Object.class, Block.class, BinaryFunctionInterface.class);
}
Also used : Variable(io.airlift.bytecode.Variable) VariableInstruction.incrementVariable(io.airlift.bytecode.instruction.VariableInstruction.incrementVariable) Signature.typeVariable(io.prestosql.spi.function.Signature.typeVariable) ErrorCodeSupplier(io.prestosql.spi.ErrorCodeSupplier) ForLoop(io.airlift.bytecode.control.ForLoop) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) ClassDefinition(io.airlift.bytecode.ClassDefinition) IfStatement(io.airlift.bytecode.control.IfStatement) Scope(io.airlift.bytecode.Scope) MethodDefinition(io.airlift.bytecode.MethodDefinition) CallSiteBinder(io.prestosql.sql.gen.CallSiteBinder) TypeSignatureParameter(io.prestosql.spi.type.TypeSignatureParameter) Parameter(io.airlift.bytecode.Parameter) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) Block(io.prestosql.spi.block.Block) BytecodeNode(io.airlift.bytecode.BytecodeNode) SqlTypeBytecodeExpression(io.prestosql.sql.gen.SqlTypeBytecodeExpression) BlockBuilder(io.prestosql.spi.block.BlockBuilder)

Example 18 with ClassDefinition

use of io.airlift.bytecode.ClassDefinition in project trino by trinodb.

the class AbstractGreatestLeast method generate.

private Class<?> generate(List<Class<?>> javaTypes, MethodHandle compareMethod) {
    Signature signature = getFunctionMetadata().getSignature();
    checkCondition(javaTypes.size() <= 127, NOT_SUPPORTED, "Too many arguments for function call %s()", signature.getName());
    String javaTypeName = javaTypes.stream().map(Class::getSimpleName).collect(joining());
    ClassDefinition definition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName(javaTypeName + "$" + signature.getName()), type(Object.class));
    definition.declareDefaultConstructor(a(PRIVATE));
    List<Parameter> parameters = IntStream.range(0, javaTypes.size()).mapToObj(i -> arg("arg" + i, javaTypes.get(i))).collect(toImmutableList());
    MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), signature.getName(), type(wrap(javaTypes.get(0))), parameters);
    Scope scope = method.getScope();
    BytecodeBlock body = method.getBody();
    CallSiteBinder binder = new CallSiteBinder();
    Variable value = scope.declareVariable(wrap(javaTypes.get(0)), "value");
    BytecodeExpression nullValue = constantNull(wrap(javaTypes.get(0)));
    body.append(value.set(nullValue));
    LabelNode done = new LabelNode("done");
    compareMethod = compareMethod.asType(methodType(boolean.class, compareMethod.type().wrap().parameterList()));
    for (int i = 0; i < javaTypes.size(); i++) {
        Parameter parameter = parameters.get(i);
        BytecodeExpression invokeCompare = invokeDynamic(BOOTSTRAP_METHOD, ImmutableList.of(binder.bind(compareMethod).getBindingId()), "compare", boolean.class, parameter, value);
        body.append(new IfStatement().condition(isNull(parameter)).ifTrue(new BytecodeBlock().append(value.set(nullValue)).gotoLabel(done)));
        body.append(new IfStatement().condition(or(isNull(value), invokeCompare)).ifTrue(value.set(parameter)));
    }
    body.visitLabel(done);
    body.append(value.ret());
    return defineClass(definition, Object.class, binder.getBindings(), new DynamicClassLoader(getClass().getClassLoader()));
}
Also used : FunctionDependencies(io.trino.metadata.FunctionDependencies) SCALAR(io.trino.metadata.FunctionKind.SCALAR) FAIL_ON_NULL(io.trino.spi.function.InvocationConvention.InvocationReturnConvention.FAIL_ON_NULL) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) FunctionNullability(io.trino.metadata.FunctionNullability) Scope(io.airlift.bytecode.Scope) DynamicClassLoader(io.airlift.bytecode.DynamicClassLoader) InvocationConvention.simpleConvention(io.trino.spi.function.InvocationConvention.simpleConvention) Access.a(io.airlift.bytecode.Access.a) BOOTSTRAP_METHOD(io.trino.sql.gen.Bootstrap.BOOTSTRAP_METHOD) Parameter.arg(io.airlift.bytecode.Parameter.arg) NOT_SUPPORTED(io.trino.spi.StandardErrorCode.NOT_SUPPORTED) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) CompilerUtils.makeClassName(io.trino.util.CompilerUtils.makeClassName) MinMaxCompare.getMinMaxCompare(io.trino.util.MinMaxCompare.getMinMaxCompare) BytecodeExpressions.constantNull(io.airlift.bytecode.expression.BytecodeExpressions.constantNull) FunctionMetadata(io.trino.metadata.FunctionMetadata) TypeSignature(io.trino.spi.type.TypeSignature) MethodDefinition(io.airlift.bytecode.MethodDefinition) FunctionDependencyDeclaration(io.trino.metadata.FunctionDependencyDeclaration) Collections.nCopies(java.util.Collections.nCopies) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) BytecodeExpression(io.airlift.bytecode.expression.BytecodeExpression) Collectors.joining(java.util.stream.Collectors.joining) CompilerUtils.defineClass(io.trino.util.CompilerUtils.defineClass) Signature.orderableTypeParameter(io.trino.metadata.Signature.orderableTypeParameter) List(java.util.List) PRIVATE(io.airlift.bytecode.Access.PRIVATE) BytecodeExpressions.or(io.airlift.bytecode.expression.BytecodeExpressions.or) Failures.checkCondition(io.trino.util.Failures.checkCondition) NEVER_NULL(io.trino.spi.function.InvocationConvention.InvocationArgumentConvention.NEVER_NULL) ClassDefinition(io.airlift.bytecode.ClassDefinition) IntStream(java.util.stream.IntStream) ParameterizedType.type(io.airlift.bytecode.ParameterizedType.type) Variable(io.airlift.bytecode.Variable) MethodHandle(java.lang.invoke.MethodHandle) Type(io.trino.spi.type.Type) Parameter(io.airlift.bytecode.Parameter) ImmutableList(com.google.common.collect.ImmutableList) LabelNode(io.airlift.bytecode.instruction.LabelNode) Signature(io.trino.metadata.Signature) NULLABLE_RETURN(io.trino.spi.function.InvocationConvention.InvocationReturnConvention.NULLABLE_RETURN) FINAL(io.airlift.bytecode.Access.FINAL) STATIC(io.airlift.bytecode.Access.STATIC) MethodType.methodType(java.lang.invoke.MethodType.methodType) BytecodeExpressions.invokeDynamic(io.airlift.bytecode.expression.BytecodeExpressions.invokeDynamic) BOXED_NULLABLE(io.trino.spi.function.InvocationConvention.InvocationArgumentConvention.BOXED_NULLABLE) SqlScalarFunction(io.trino.metadata.SqlScalarFunction) IfStatement(io.airlift.bytecode.control.IfStatement) CallSiteBinder(io.trino.sql.gen.CallSiteBinder) PUBLIC(io.airlift.bytecode.Access.PUBLIC) MinMaxCompare.getMinMaxCompareFunctionDependencies(io.trino.util.MinMaxCompare.getMinMaxCompareFunctionDependencies) BoundSignature(io.trino.metadata.BoundSignature) BytecodeExpressions.isNull(io.airlift.bytecode.expression.BytecodeExpressions.isNull) Primitives.wrap(com.google.common.primitives.Primitives.wrap) Reflection.methodHandle(io.trino.util.Reflection.methodHandle) LabelNode(io.airlift.bytecode.instruction.LabelNode) DynamicClassLoader(io.airlift.bytecode.DynamicClassLoader) Variable(io.airlift.bytecode.Variable) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) ClassDefinition(io.airlift.bytecode.ClassDefinition) IfStatement(io.airlift.bytecode.control.IfStatement) Scope(io.airlift.bytecode.Scope) MethodDefinition(io.airlift.bytecode.MethodDefinition) TypeSignature(io.trino.spi.type.TypeSignature) Signature(io.trino.metadata.Signature) BoundSignature(io.trino.metadata.BoundSignature) CallSiteBinder(io.trino.sql.gen.CallSiteBinder) Signature.orderableTypeParameter(io.trino.metadata.Signature.orderableTypeParameter) Parameter(io.airlift.bytecode.Parameter) BytecodeExpression(io.airlift.bytecode.expression.BytecodeExpression)

Example 19 with ClassDefinition

use of io.airlift.bytecode.ClassDefinition in project trino by trinodb.

the class RowToRowCast method generateRowCast.

private static Class<?> generateRowCast(Type fromType, Type toType, FunctionDependencies functionDependencies) {
    List<Type> toTypes = toType.getTypeParameters();
    List<Type> fromTypes = fromType.getTypeParameters();
    CallSiteBinder binder = new CallSiteBinder();
    // Embed the MD5 hash code of input and output types into the generated class name instead of the raw type names,
    // which could prevent the class name from hitting the length limitation and invalid characters.
    byte[] md5Suffix = Hashing.md5().hashBytes((fromType + "$" + toType).getBytes(UTF_8)).asBytes();
    ClassDefinition definition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName(Joiner.on("$").join("RowCast", BaseEncoding.base16().encode(md5Suffix))), type(Object.class));
    Parameter session = arg("session", ConnectorSession.class);
    Parameter row = arg("row", Block.class);
    MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "castRow", type(Block.class), session, row);
    Scope scope = method.getScope();
    BytecodeBlock body = method.getBody();
    Variable wasNull = scope.declareVariable(boolean.class, "wasNull");
    Variable blockBuilder = scope.createTempVariable(BlockBuilder.class);
    Variable singleRowBlockWriter = scope.createTempVariable(BlockBuilder.class);
    body.append(wasNull.set(constantBoolean(false)));
    CachedInstanceBinder cachedInstanceBinder = new CachedInstanceBinder(definition, binder);
    // create the row block builder
    body.append(blockBuilder.set(constantType(binder, toType).invoke("createBlockBuilder", BlockBuilder.class, constantNull(BlockBuilderStatus.class), constantInt(1))));
    body.append(singleRowBlockWriter.set(blockBuilder.invoke("beginBlockEntry", BlockBuilder.class)));
    // loop through to append member blocks
    for (int i = 0; i < toTypes.size(); i++) {
        Type fromElementType = fromTypes.get(i);
        Type toElementType = toTypes.get(i);
        Type currentFromType = fromElementType;
        if (currentFromType.equals(UNKNOWN)) {
            body.append(singleRowBlockWriter.invoke("appendNull", BlockBuilder.class).pop());
            continue;
        }
        MethodHandle castMethod = getNullSafeCast(functionDependencies, fromElementType, toElementType);
        MethodHandle writeMethod = getNullSafeWrite(toElementType);
        MethodHandle castAndWrite = collectArguments(writeMethod, 1, castMethod);
        body.append(invokeDynamic(BOOTSTRAP_METHOD, ImmutableList.of(binder.bind(castAndWrite).getBindingId()), "castAndWriteField", castAndWrite.type(), singleRowBlockWriter, scope.getVariable("session"), row, constantInt(i)));
    }
    // call blockBuilder.closeEntry() and return the single row block
    body.append(blockBuilder.invoke("closeEntry", BlockBuilder.class).pop());
    body.append(constantType(binder, toType).invoke("getObject", Object.class, blockBuilder.cast(Block.class), constantInt(0)).cast(Block.class).ret());
    // create constructor
    MethodDefinition constructorDefinition = definition.declareConstructor(a(PUBLIC));
    BytecodeBlock constructorBody = constructorDefinition.getBody();
    Variable thisVariable = constructorDefinition.getThis();
    constructorBody.comment("super();").append(thisVariable).invokeConstructor(Object.class);
    cachedInstanceBinder.generateInitializations(thisVariable, constructorBody);
    constructorBody.ret();
    return defineClass(definition, Object.class, binder.getBindings(), RowToRowCast.class.getClassLoader());
}
Also used : Variable(io.airlift.bytecode.Variable) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) ClassDefinition(io.airlift.bytecode.ClassDefinition) TypeVariableConstraint(io.trino.metadata.TypeVariableConstraint) SqlTypeBytecodeExpression.constantType(io.trino.sql.gen.SqlTypeBytecodeExpression.constantType) Type(io.trino.spi.type.Type) MethodType.methodType(java.lang.invoke.MethodType.methodType) CachedInstanceBinder(io.trino.sql.gen.CachedInstanceBinder) Scope(io.airlift.bytecode.Scope) MethodDefinition(io.airlift.bytecode.MethodDefinition) CallSiteBinder(io.trino.sql.gen.CallSiteBinder) Parameter(io.airlift.bytecode.Parameter) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) Block(io.trino.spi.block.Block) BlockBuilderStatus(io.trino.spi.block.BlockBuilderStatus) MethodHandle(java.lang.invoke.MethodHandle)

Example 20 with ClassDefinition

use of io.airlift.bytecode.ClassDefinition in project trino by trinodb.

the class JoinCompiler method internalCompileHashStrategy.

private Class<? extends PagesHashStrategy> internalCompileHashStrategy(List<Type> types, List<Integer> outputChannels, List<Integer> joinChannels, Optional<Integer> sortChannel) {
    CallSiteBinder callSiteBinder = new CallSiteBinder();
    ClassDefinition classDefinition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName("PagesHashStrategy"), type(Object.class), type(PagesHashStrategy.class));
    FieldDefinition instanceSizeField = generateInstanceSize(classDefinition);
    FieldDefinition sizeField = classDefinition.declareField(a(PRIVATE, FINAL), "size", type(long.class));
    List<FieldDefinition> channelFields = new ArrayList<>();
    for (int i = 0; i < types.size(); i++) {
        FieldDefinition channelField = classDefinition.declareField(a(PRIVATE, FINAL), "channel_" + i, type(List.class, Block.class));
        channelFields.add(channelField);
    }
    List<Type> joinChannelTypes = new ArrayList<>();
    List<FieldDefinition> joinChannelFields = new ArrayList<>();
    for (int i = 0; i < joinChannels.size(); i++) {
        joinChannelTypes.add(types.get(joinChannels.get(i)));
        FieldDefinition channelField = classDefinition.declareField(a(PRIVATE, FINAL), "joinChannel_" + i, type(List.class, Block.class));
        joinChannelFields.add(channelField);
    }
    FieldDefinition hashChannelField = classDefinition.declareField(a(PRIVATE, FINAL), "hashChannel", type(List.class, Block.class));
    generateConstructor(classDefinition, joinChannels, sizeField, instanceSizeField, channelFields, joinChannelFields, hashChannelField);
    generateGetChannelCountMethod(classDefinition, outputChannels.size());
    generateGetSizeInBytesMethod(classDefinition, sizeField);
    generateAppendToMethod(classDefinition, callSiteBinder, types, outputChannels, channelFields);
    generateHashPositionMethod(classDefinition, callSiteBinder, joinChannelTypes, joinChannelFields, hashChannelField);
    generateHashRowMethod(classDefinition, callSiteBinder, joinChannelTypes);
    generateRowEqualsRowMethod(classDefinition, callSiteBinder, joinChannelTypes);
    generateRowNotDistinctFromRowMethod(classDefinition, callSiteBinder, joinChannelTypes);
    generatePositionEqualsRowMethod(classDefinition, callSiteBinder, joinChannelTypes, joinChannelFields, true);
    generatePositionEqualsRowMethod(classDefinition, callSiteBinder, joinChannelTypes, joinChannelFields, false);
    generatePositionNotDistinctFromRowMethod(classDefinition, callSiteBinder, joinChannelTypes, joinChannelFields);
    generatePositionNotDistinctFromRowWithPageMethod(classDefinition, callSiteBinder, joinChannelTypes, joinChannelFields);
    generatePositionEqualsPositionMethod(classDefinition, callSiteBinder, joinChannelTypes, joinChannelFields, true);
    generatePositionEqualsPositionMethod(classDefinition, callSiteBinder, joinChannelTypes, joinChannelFields, false);
    generatePositionNotDistinctFromPositionMethod(classDefinition, callSiteBinder, joinChannelTypes, joinChannelFields);
    generateIsPositionNull(classDefinition, joinChannelFields);
    generateCompareSortChannelPositionsMethod(classDefinition, callSiteBinder, types, channelFields, sortChannel);
    generateIsSortChannelPositionNull(classDefinition, channelFields, sortChannel);
    return defineClass(classDefinition, PagesHashStrategy.class, callSiteBinder.getBindings(), getClass().getClassLoader());
}
Also used : SqlTypeBytecodeExpression.constantType(io.trino.sql.gen.SqlTypeBytecodeExpression.constantType) Type(io.trino.spi.type.Type) BigintType(io.trino.spi.type.BigintType) PagesHashStrategy(io.trino.operator.PagesHashStrategy) FieldDefinition(io.airlift.bytecode.FieldDefinition) LongArrayList(it.unimi.dsi.fastutil.longs.LongArrayList) ArrayList(java.util.ArrayList) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) Block(io.trino.spi.block.Block) LongArrayList(it.unimi.dsi.fastutil.longs.LongArrayList) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) ClassDefinition(io.airlift.bytecode.ClassDefinition)

Aggregations

ClassDefinition (io.airlift.bytecode.ClassDefinition)57 MethodDefinition (io.airlift.bytecode.MethodDefinition)32 BytecodeBlock (io.airlift.bytecode.BytecodeBlock)31 Variable (io.airlift.bytecode.Variable)30 Parameter (io.airlift.bytecode.Parameter)29 Scope (io.airlift.bytecode.Scope)21 ImmutableList (com.google.common.collect.ImmutableList)16 FieldDefinition (io.airlift.bytecode.FieldDefinition)16 IfStatement (io.airlift.bytecode.control.IfStatement)16 CallSiteBinder (io.prestosql.sql.gen.CallSiteBinder)12 DynamicClassLoader (io.airlift.bytecode.DynamicClassLoader)11 CallSiteBinder (io.trino.sql.gen.CallSiteBinder)11 BytecodeNode (io.airlift.bytecode.BytecodeNode)10 List (java.util.List)10 ForLoop (io.airlift.bytecode.control.ForLoop)9 BytecodeExpression (io.airlift.bytecode.expression.BytecodeExpression)9 Block (io.prestosql.spi.block.Block)9 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)8 VariableInstruction.incrementVariable (io.airlift.bytecode.instruction.VariableInstruction.incrementVariable)8 BlockBuilder (io.prestosql.spi.block.BlockBuilder)8