Search in sources :

Example 76 with MethodHandle

use of java.lang.invoke.MethodHandle in project presto by prestodb.

the class AbstractMinMaxBy method generateAggregation.

private InternalAggregationFunction generateAggregation(Type valueType, Type keyType, FunctionRegistry functionRegistry) {
    Class<?> stateClazz = getStateClass(keyType.getJavaType(), valueType.getJavaType());
    Map<String, Type> stateFieldTypes = ImmutableMap.of("First", keyType, "Second", valueType);
    DynamicClassLoader classLoader = new DynamicClassLoader(getClass().getClassLoader());
    AccumulatorStateFactory<?> stateFactory = StateCompiler.generateStateFactory(stateClazz, stateFieldTypes, classLoader);
    AccumulatorStateSerializer<?> stateSerializer = StateCompiler.generateStateSerializer(stateClazz, stateFieldTypes, classLoader);
    Type intermediateType = stateSerializer.getSerializedType();
    List<Type> inputTypes = ImmutableList.of(valueType, keyType);
    CallSiteBinder binder = new CallSiteBinder();
    OperatorType operator = min ? LESS_THAN : GREATER_THAN;
    MethodHandle compareMethod = functionRegistry.getScalarFunctionImplementation(functionRegistry.resolveOperator(operator, ImmutableList.of(keyType, keyType))).getMethodHandle();
    ClassDefinition definition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName("processMaxOrMinBy"), type(Object.class));
    definition.declareDefaultConstructor(a(PRIVATE));
    generateInputMethod(definition, binder, compareMethod, keyType, valueType, stateClazz);
    generateCombineMethod(definition, binder, compareMethod, keyType, valueType, stateClazz);
    generateOutputMethod(definition, binder, valueType, stateClazz);
    Class<?> generatedClass = defineClass(definition, Object.class, binder.getBindings(), classLoader);
    MethodHandle inputMethod = methodHandle(generatedClass, "input", stateClazz, Block.class, Block.class, int.class);
    MethodHandle combineMethod = methodHandle(generatedClass, "combine", stateClazz, stateClazz);
    MethodHandle outputMethod = methodHandle(generatedClass, "output", stateClazz, BlockBuilder.class);
    AggregationMetadata metadata = new AggregationMetadata(generateAggregationName(getSignature().getName(), valueType.getTypeSignature(), inputTypes.stream().map(Type::getTypeSignature).collect(toImmutableList())), createInputParameterMetadata(valueType, keyType), inputMethod, combineMethod, outputMethod, stateClazz, stateSerializer, stateFactory, valueType);
    GenericAccumulatorFactoryBinder factory = AccumulatorCompiler.generateAccumulatorFactoryBinder(metadata, classLoader);
    return new InternalAggregationFunction(getSignature().getName(), inputTypes, intermediateType, valueType, true, factory);
}
Also used : DynamicClassLoader(com.facebook.presto.bytecode.DynamicClassLoader) ClassDefinition(com.facebook.presto.bytecode.ClassDefinition) OperatorType(com.facebook.presto.spi.function.OperatorType) OperatorType(com.facebook.presto.spi.function.OperatorType) Type(com.facebook.presto.spi.type.Type) SqlTypeBytecodeExpression.constantType(com.facebook.presto.sql.gen.SqlTypeBytecodeExpression.constantType) CallSiteBinder(com.facebook.presto.sql.gen.CallSiteBinder) MethodHandle(java.lang.invoke.MethodHandle)

Example 77 with MethodHandle

use of java.lang.invoke.MethodHandle in project presto by prestodb.

the class AbstractMinMaxBy method generateInputMethod.

private void generateInputMethod(ClassDefinition definition, CallSiteBinder binder, MethodHandle compareMethod, Type keyType, Type valueType, Class<?> stateClass) {
    Parameter state = arg("state", stateClass);
    Parameter value = arg("value", Block.class);
    Parameter key = arg("key", Block.class);
    Parameter position = arg("position", int.class);
    MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "input", type(void.class), state, value, key, position);
    if (keyType.equals(UNKNOWN)) {
        method.getBody().ret();
        return;
    }
    SqlTypeBytecodeExpression keySqlType = constantType(binder, keyType);
    BytecodeBlock ifBlock = new BytecodeBlock().append(state.invoke("setFirst", void.class, keySqlType.getValue(key, position))).append(state.invoke("setFirstNull", void.class, constantBoolean(false))).append(state.invoke("setSecondNull", void.class, value.invoke("isNull", boolean.class, position)));
    if (!valueType.equals(UNKNOWN)) {
        SqlTypeBytecodeExpression valueSqlType = constantType(binder, valueType);
        ifBlock.append(new IfStatement().condition(value.invoke("isNull", boolean.class, position)).ifFalse(state.invoke("setSecond", void.class, valueSqlType.getValue(value, position))));
    }
    method.getBody().append(new IfStatement().condition(or(state.invoke("isFirstNull", boolean.class), and(not(key.invoke("isNull", boolean.class, position)), loadConstant(binder, compareMethod, MethodHandle.class).invoke("invokeExact", boolean.class, keySqlType.getValue(key, position), state.invoke("getFirst", keyType.getJavaType()))))).ifTrue(ifBlock)).ret();
}
Also used : IfStatement(com.facebook.presto.bytecode.control.IfStatement) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Parameter(com.facebook.presto.bytecode.Parameter) Signature.orderableTypeParameter(com.facebook.presto.metadata.Signature.orderableTypeParameter) SqlTypeBytecodeExpression(com.facebook.presto.sql.gen.SqlTypeBytecodeExpression) MethodHandle(java.lang.invoke.MethodHandle)

Example 78 with MethodHandle

use of java.lang.invoke.MethodHandle in project presto by prestodb.

the class AbstractMinMaxBy method generateCombineMethod.

private void generateCombineMethod(ClassDefinition definition, CallSiteBinder binder, MethodHandle compareMethod, Type keyType, Type valueType, Class<?> stateClass) {
    Parameter state = arg("state", stateClass);
    Parameter otherState = arg("otherState", stateClass);
    MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "combine", type(void.class), state, otherState);
    if (keyType.equals(UNKNOWN)) {
        method.getBody().ret();
        return;
    }
    Class<?> keyJavaType = keyType.getJavaType();
    BytecodeBlock ifBlock = new BytecodeBlock().append(state.invoke("setFirst", void.class, otherState.invoke("getFirst", keyJavaType))).append(state.invoke("setFirstNull", void.class, otherState.invoke("isFirstNull", boolean.class))).append(state.invoke("setSecondNull", void.class, otherState.invoke("isSecondNull", boolean.class)));
    if (!valueType.equals(UNKNOWN)) {
        ifBlock.append(state.invoke("setSecond", void.class, otherState.invoke("getSecond", valueType.getJavaType())));
    }
    method.getBody().append(new IfStatement().condition(or(state.invoke("isFirstNull", boolean.class), and(not(otherState.invoke("isFirstNull", boolean.class)), loadConstant(binder, compareMethod, MethodHandle.class).invoke("invokeExact", boolean.class, otherState.invoke("getFirst", keyJavaType), state.invoke("getFirst", keyJavaType))))).ifTrue(ifBlock)).ret();
}
Also used : IfStatement(com.facebook.presto.bytecode.control.IfStatement) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Parameter(com.facebook.presto.bytecode.Parameter) Signature.orderableTypeParameter(com.facebook.presto.metadata.Signature.orderableTypeParameter) MethodHandle(java.lang.invoke.MethodHandle)

Example 79 with MethodHandle

use of java.lang.invoke.MethodHandle in project presto by prestodb.

the class Histogram method generateAggregation.

private static InternalAggregationFunction generateAggregation(Type keyType, Type valueType) {
    DynamicClassLoader classLoader = new DynamicClassLoader(Histogram.class.getClassLoader());
    List<Type> inputTypes = ImmutableList.of(keyType);
    Type outputType = new MapType(keyType, valueType);
    HistogramStateSerializer stateSerializer = new HistogramStateSerializer(keyType);
    Type intermediateType = stateSerializer.getSerializedType();
    MethodHandle inputFunction = INPUT_FUNCTION.bindTo(keyType);
    MethodHandle outputFunction = OUTPUT_FUNCTION.bindTo(outputType);
    AggregationMetadata metadata = new AggregationMetadata(generateAggregationName(NAME, outputType.getTypeSignature(), inputTypes.stream().map(Type::getTypeSignature).collect(toImmutableList())), createInputParameterMetadata(keyType), inputFunction, COMBINE_FUNCTION, outputFunction, HistogramState.class, stateSerializer, new HistogramStateFactory(), outputType);
    GenericAccumulatorFactoryBinder factory = AccumulatorCompiler.generateAccumulatorFactoryBinder(metadata, classLoader);
    return new InternalAggregationFunction(NAME, inputTypes, intermediateType, outputType, true, factory);
}
Also used : DynamicClassLoader(com.facebook.presto.bytecode.DynamicClassLoader) MapType(com.facebook.presto.type.MapType) Type(com.facebook.presto.spi.type.Type) BigintType(com.facebook.presto.spi.type.BigintType) HistogramStateFactory(com.facebook.presto.operator.aggregation.state.HistogramStateFactory) MapType(com.facebook.presto.type.MapType) HistogramStateSerializer(com.facebook.presto.operator.aggregation.state.HistogramStateSerializer) MethodHandle(java.lang.invoke.MethodHandle)

Example 80 with MethodHandle

use of java.lang.invoke.MethodHandle in project presto by prestodb.

the class ArrayAggregationFunction method generateAggregation.

private static InternalAggregationFunction generateAggregation(Type type, boolean legacyArrayAgg) {
    DynamicClassLoader classLoader = new DynamicClassLoader(ArrayAggregationFunction.class.getClassLoader());
    AccumulatorStateSerializer<?> stateSerializer = new ArrayAggregationStateSerializer(type);
    AccumulatorStateFactory<?> stateFactory = new ArrayAggregationStateFactory();
    List<Type> inputTypes = ImmutableList.of(type);
    Type outputType = new ArrayType(type);
    Type intermediateType = stateSerializer.getSerializedType();
    List<ParameterMetadata> inputParameterMetadata = createInputParameterMetadata(type, legacyArrayAgg);
    MethodHandle inputFunction = INPUT_FUNCTION.bindTo(type);
    MethodHandle combineFunction = COMBINE_FUNCTION.bindTo(type);
    MethodHandle outputFunction = OUTPUT_FUNCTION.bindTo(outputType);
    Class<? extends AccumulatorState> stateInterface = ArrayAggregationState.class;
    AggregationMetadata metadata = new AggregationMetadata(generateAggregationName(NAME, type.getTypeSignature(), inputTypes.stream().map(Type::getTypeSignature).collect(toImmutableList())), inputParameterMetadata, inputFunction, combineFunction, outputFunction, stateInterface, stateSerializer, stateFactory, outputType);
    GenericAccumulatorFactoryBinder factory = AccumulatorCompiler.generateAccumulatorFactoryBinder(metadata, classLoader);
    return new InternalAggregationFunction(NAME, inputTypes, intermediateType, outputType, true, factory);
}
Also used : DynamicClassLoader(com.facebook.presto.bytecode.DynamicClassLoader) ArrayAggregationStateSerializer(com.facebook.presto.operator.aggregation.state.ArrayAggregationStateSerializer) ParameterMetadata(com.facebook.presto.operator.aggregation.AggregationMetadata.ParameterMetadata) ArrayType(com.facebook.presto.type.ArrayType) ArrayType(com.facebook.presto.type.ArrayType) Type(com.facebook.presto.spi.type.Type) ArrayAggregationState(com.facebook.presto.operator.aggregation.state.ArrayAggregationState) ArrayAggregationStateFactory(com.facebook.presto.operator.aggregation.state.ArrayAggregationStateFactory) MethodHandle(java.lang.invoke.MethodHandle)

Aggregations

MethodHandle (java.lang.invoke.MethodHandle)302 Test (org.junit.Test)101 MethodType (java.lang.invoke.MethodType)44 Type (com.facebook.presto.spi.type.Type)37 Method (java.lang.reflect.Method)18 OperatorType (com.facebook.presto.spi.function.OperatorType)14 MethodHandles (java.lang.invoke.MethodHandles)13 DynamicClassLoader (com.facebook.presto.bytecode.DynamicClassLoader)11 Signature (com.facebook.presto.metadata.Signature)10 CallSite (java.lang.invoke.CallSite)10 ScriptObject (com.github.anba.es6draft.runtime.types.ScriptObject)9 ImmutableList (com.google.common.collect.ImmutableList)9 List (java.util.List)8 MethodDefinition (com.facebook.presto.bytecode.MethodDefinition)7 TypeSignature.parseTypeSignature (com.facebook.presto.spi.type.TypeSignature.parseTypeSignature)7 BytecodeBlock (com.facebook.presto.bytecode.BytecodeBlock)6 Parameter (com.facebook.presto.bytecode.Parameter)6 PrestoException (com.facebook.presto.spi.PrestoException)6 ComponentInjectionException (org.neo4j.kernel.api.exceptions.ComponentInjectionException)6 ProcedureException (org.neo4j.kernel.api.exceptions.ProcedureException)6