private static MethodDefinition declareAddIntermediate(ClassDefinition definition, boolean grouped) { ImmutableList.Builder<Parameter> parameters = ImmutableList.builder(); if (grouped) { parameters.add(arg("groupIdsBlock", GroupByIdBlock.class)); } parameters.add(arg("block", Block.class)); return definition.declareMethod( a(PUBLIC), "addIntermediate", type(void.class), parameters.build()); }
public FieldDefinition getCachedInstance(MethodHandle methodHandle) { FieldDefinition field = classDefinition.declareField(a(PRIVATE, FINAL), "__cachedInstance" + nextId, methodHandle.type().returnType()); initializers.put(field, methodHandle); nextId++; return field; }
private Class<? extends PageWithPositionComparator> generatePageWithPositionComparatorClass(List<Type> sortTypes, List<Integer> sortChannels, List<SortOrder> sortOrders) { CallSiteBinder callSiteBinder = new CallSiteBinder(); ClassDefinition classDefinition = new ClassDefinition( a(PUBLIC, FINAL), makeClassName("PageWithPositionComparator"), type(Object.class), type(PageWithPositionComparator.class)); classDefinition.declareDefaultConstructor(a(PUBLIC)); generateMergeSortCompareTo(classDefinition, callSiteBinder, sortTypes, sortChannels, sortOrders); return defineClass(classDefinition, PageWithPositionComparator.class, callSiteBinder.getBindings(), getClass().getClassLoader()); }
private Class<? extends PagesIndexComparator> compilePagesIndexComparator( List<Type> sortTypes, List<Integer> sortChannels, List<SortOrder> sortOrders) { CallSiteBinder callSiteBinder = new CallSiteBinder(); ClassDefinition classDefinition = new ClassDefinition( a(PUBLIC, FINAL), makeClassName("PagesIndexComparator"), type(Object.class), type(PagesIndexComparator.class)); classDefinition.declareDefaultConstructor(a(PUBLIC)); generatePageIndexCompareTo(classDefinition, callSiteBinder, sortTypes, sortChannels, sortOrders); return defineClass(classDefinition, PagesIndexComparator.class, callSiteBinder.getBindings(), getClass().getClassLoader()); }
private static void generatePrepareFinal(ClassDefinition definition) { MethodDefinition method = definition.declareMethod( a(PUBLIC), "prepareFinal", type(void.class)); method.getBody().ret(); }
private static void generateGetSerializedType(ClassDefinition definition, List<StateField> fields, CallSiteBinder callSiteBinder) { BytecodeBlock body = definition.declareMethod(a(PUBLIC), "getSerializedType", type(Type.class)).getBody(); Type type; if (fields.size() > 1) { List<Type> types = fields.stream().map(StateField::getSqlType).collect(toImmutableList()); type = RowType.anonymous(types); } else if (fields.size() == 1) { type = getOnlyElement(fields).getSqlType(); } else { type = UNKNOWN; } body.comment("return %s", type.getTypeSignature()) .append(constantType(callSiteBinder, type)) .retObject(); }
private static void generateGetChannelCountMethod(ClassDefinition classDefinition, int outputChannelCount) { classDefinition.declareMethod( a(PUBLIC), "getChannelCount", type(int.class)) .getBody() .push(outputChannelCount) .retInt(); }
private void generateMethods(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, RowExpression filter, int leftBlocksSize) { CachedInstanceBinder cachedInstanceBinder = new CachedInstanceBinder(classDefinition, callSiteBinder); FieldDefinition sessionField = classDefinition.declareField(a(PRIVATE, FINAL), "session", ConnectorSession.class); Map<LambdaDefinitionExpression, CompiledLambda> compiledLambdaMap = generateMethodsForLambda(classDefinition, callSiteBinder, cachedInstanceBinder, leftBlocksSize, filter); generateFilterMethod(classDefinition, callSiteBinder, cachedInstanceBinder, compiledLambdaMap, filter, leftBlocksSize, sessionField); generateConstructor(classDefinition, sessionField, cachedInstanceBinder); }
private static MethodDefinition generateGetFinalType(ClassDefinition definition, CallSiteBinder callSiteBinder, Type type) { MethodDefinition methodDefinition = definition.declareMethod(a(PUBLIC), "getFinalType", type(Type.class)); methodDefinition.getBody() .append(constantType(callSiteBinder, type)) .retObject(); return methodDefinition; }
private static MethodDefinition generateGetIntermediateType(ClassDefinition definition, CallSiteBinder callSiteBinder, List<Type> type) { MethodDefinition methodDefinition = definition.declareMethod(a(PUBLIC), "getIntermediateType", type(Type.class)); if (type.size() == 1) { methodDefinition.getBody() .append(constantType(callSiteBinder, getOnlyElement(type))) .retObject(); } else { methodDefinition.getBody() .append(constantType(callSiteBinder, RowType.anonymous(type))) .retObject(); } return methodDefinition; }
private static void generateConstructor( ClassDefinition classDefinition, CachedInstanceBinder cachedInstanceBinder, Map<LambdaDefinitionExpression, CompiledLambda> compiledLambdaMap, Consumer<MethodDefinition> additionalStatements) { MethodDefinition constructorDefinition = classDefinition.declareConstructor(a(PUBLIC)); BytecodeBlock body = constructorDefinition.getBody(); Variable thisVariable = constructorDefinition.getThis(); body.comment("super();") .append(thisVariable) .invokeConstructor(Object.class); additionalStatements.accept(constructorDefinition); cachedInstanceBinder.generateInitializations(thisVariable, body); body.ret(); }
private static void generateToString(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, String string) { // bind constant via invokedynamic to avoid constant pool issues due to large strings classDefinition.declareMethod(a(PUBLIC), "toString", type(String.class)) .getBody() .append(invoke(callSiteBinder.bind(string, String.class), "toString")) .retObject(); }
private static void generateToString(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, String string) { // bind constant via invokedynamic to avoid constant pool issues due to large strings classDefinition.declareMethod(a(PUBLIC), "toString", type(String.class)) .getBody() .append(invoke(callSiteBinder.bind(string, String.class), "toString")) .retObject(); }
private static void generateGetSizeInBytesMethod(ClassDefinition classDefinition, FieldDefinition sizeField) { MethodDefinition getSizeInBytesMethod = classDefinition.declareMethod(a(PUBLIC), "getSizeInBytes", type(long.class)); Variable thisVariable = getSizeInBytesMethod.getThis(); getSizeInBytesMethod.getBody() .append(thisVariable.getField(sizeField)) .retLong(); }
private static void generateField(ClassDefinition definition, MethodDefinition constructor, StateField stateField) { FieldDefinition field = definition.declareField(a(PRIVATE), UPPER_CAMEL.to(LOWER_CAMEL, stateField.getName()) + "Value", stateField.getType()); // Generate getter MethodDefinition getter = definition.declareMethod(a(PUBLIC), stateField.getGetterName(), type(stateField.getType())); getter.getBody() .append(getter.getThis().getField(field).ret()); // Generate setter Parameter value = arg("value", stateField.getType()); MethodDefinition setter = definition.declareMethod(a(PUBLIC), stateField.getSetterName(), type(void.class), value); setter.getBody() .append(setter.getThis().setField(field, value)) .ret(); constructor.getBody() .append(constructor.getThis().setField(field, stateField.initialValueExpression())); }
private static FieldDefinition generateInstanceSize(ClassDefinition definition) { // Store instance size in static field FieldDefinition instanceSize = definition.declareField(a(PRIVATE, STATIC, FINAL), "INSTANCE_SIZE", long.class); definition.getClassInitializer() .getBody() .comment("INSTANCE_SIZE = ClassLayout.parseClass(%s.class).instanceSize()", definition.getName()) .push(definition.getType()) .invokeStatic(ClassLayout.class, "parseClass", ClassLayout.class, Class.class) .invokeVirtual(ClassLayout.class, "instanceSize", int.class) .intToLong() .putStaticField(instanceSize); return instanceSize; }
private static FieldDefinition generateInstanceSize(ClassDefinition definition) { // Store instance size in static field FieldDefinition instanceSize = definition.declareField(a(PRIVATE, STATIC, FINAL), "INSTANCE_SIZE", long.class); definition.getClassInitializer() .getBody() .comment("INSTANCE_SIZE = ClassLayout.parseClass(%s.class).instanceSize()", definition.getName()) .push(definition.getType()) .invokeStatic(ClassLayout.class, "parseClass", ClassLayout.class, Class.class) .invokeVirtual(ClassLayout.class, "instanceSize", int.class) .intToLong() .putStaticField(instanceSize); return instanceSize; }
private static void generateConstructor( ClassDefinition classDefinition, FieldDefinition sessionField, CachedInstanceBinder cachedInstanceBinder) { Parameter sessionParameter = arg("session", ConnectorSession.class); MethodDefinition constructorDefinition = classDefinition.declareConstructor(a(PUBLIC), sessionParameter); BytecodeBlock body = constructorDefinition.getBody(); Variable thisVariable = constructorDefinition.getThis(); body.comment("super();") .append(thisVariable) .invokeConstructor(Object.class); body.append(thisVariable.setField(sessionField, sessionParameter)); cachedInstanceBinder.generateInitializations(thisVariable, body); body.ret(); }
private static void generateGetEstimatedSize(ClassDefinition definition, List<FieldDefinition> stateFields) { MethodDefinition method = definition.declareMethod(a(PUBLIC), "getEstimatedSize", type(long.class)); Variable estimatedSize = method.getScope().declareVariable(long.class, "estimatedSize"); method.getBody().append(estimatedSize.set(constantLong(0L))); for (FieldDefinition stateField : stateFields) { method.getBody() .append(estimatedSize.set( BytecodeExpressions.add( estimatedSize, method.getThis().getField(stateField).invoke("getEstimatedSize", long.class)))); } method.getBody().append(estimatedSize.ret()); }
private void generateOutputMethod(ClassDefinition definition, CallSiteBinder binder, Type valueType, Class<?> stateClass) { Parameter state = arg("state", stateClass); Parameter out = arg("out", BlockBuilder.class); MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "output", type(void.class), state, out); IfStatement ifStatement = new IfStatement() .condition(or(state.invoke("isFirstNull", boolean.class), state.invoke("isSecondNull", boolean.class))) .ifTrue(new BytecodeBlock().append(out.invoke("appendNull", BlockBuilder.class)).pop()); SqlTypeBytecodeExpression valueSqlType = constantType(binder, valueType); BytecodeExpression getValueExpression; if (valueType.getJavaType().isPrimitive()) { getValueExpression = state.invoke("getSecond", valueType.getJavaType()); } else { getValueExpression = valueSqlType.getValue(state.invoke("getSecondBlock", Block.class), state.invoke("getSecondPosition", int.class)); } ifStatement.ifFalse(valueSqlType.writeValue(out, getValueExpression)); method.getBody().append(ifStatement).ret(); } }