private static List<Parameter> toBlockParameters(List<Integer> inputChannels) { ImmutableList.Builder<Parameter> parameters = ImmutableList.builder(); for (int channel : inputChannels) { parameters.add(arg("block_" + channel, Block.class)); } return parameters.build(); }
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()); }
List<FieldDefinition> joinChannelFields) Parameter leftBlockIndex = arg("leftBlockIndex", int.class); Parameter leftBlockPosition = arg("leftBlockPosition", int.class); Parameter rightPosition = arg("rightPosition", int.class); Parameter page = arg("page", Page.class); Parameter rightChannels = arg("rightChannels", int[].class);
private static void generateAppendToMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> types, List<Integer> outputChannels, List<FieldDefinition> channelFields) Parameter blockIndex = arg("blockIndex", int.class); Parameter blockPosition = arg("blockPosition", int.class); Parameter pageBuilder = arg("pageBuilder", PageBuilder.class); Parameter outputChannelOffset = arg("outputChannelOffset", int.class); MethodDefinition appendToMethod = classDefinition.declareMethod(a(PUBLIC), "appendTo", type(void.class), blockIndex, blockPosition, pageBuilder, outputChannelOffset);
private static void generateGroupedEvaluateFinal( ClassDefinition definition, List<FieldDefinition> stateFields, MethodHandle outputFunction, CallSiteBinder callSiteBinder) { Parameter groupId = arg("groupId", int.class); Parameter out = arg("out", BlockBuilder.class); MethodDefinition method = definition.declareMethod(a(PUBLIC), "evaluateFinal", type(void.class), groupId, out); BytecodeBlock body = method.getBody(); Variable thisVariable = method.getThis(); List<BytecodeExpression> states = new ArrayList<>(); for (FieldDefinition stateField : stateFields) { BytecodeExpression state = thisVariable.getField(stateField); body.append(state.invoke("setGroupId", void.class, groupId.cast(long.class))); states.add(state); } body.comment("output(state_0, state_1, ..., out)"); states.forEach(body::append); body.append(out); body.append(invoke(callSiteBinder.bind(outputFunction), "output")); body.ret(); }
private static void generateIsSortChannelPositionNull( ClassDefinition classDefinition, List<FieldDefinition> channelFields, Optional<Integer> sortChannel) { Parameter blockIndex = arg("blockIndex", int.class); Parameter blockPosition = arg("blockPosition", int.class); MethodDefinition isSortChannelPositionNullMethod = classDefinition.declareMethod( a(PUBLIC), "isSortChannelPositionNull", type(boolean.class), blockIndex, blockPosition); if (!sortChannel.isPresent()) { isSortChannelPositionNullMethod.getBody() .append(newInstance(UnsupportedOperationException.class)) .throwObject(); return; } Variable thisVariable = isSortChannelPositionNullMethod.getThis(); int index = sortChannel.get(); BytecodeExpression block = thisVariable .getField(channelFields.get(index)) .invoke("get", Object.class, blockIndex) .cast(Block.class); BytecodeNode isNull = block.invoke("isNull", boolean.class, blockPosition).ret(); isSortChannelPositionNullMethod .getBody() .append(isNull); }
private static void generateEvaluateFinal( ClassDefinition definition, List<FieldDefinition> stateFields, MethodHandle outputFunction, CallSiteBinder callSiteBinder) { Parameter out = arg("out", BlockBuilder.class); MethodDefinition method = definition.declareMethod( a(PUBLIC), "evaluateFinal", type(void.class), out); BytecodeBlock body = method.getBody(); Variable thisVariable = method.getThis(); List<BytecodeExpression> states = new ArrayList<>(); for (FieldDefinition stateField : stateFields) { BytecodeExpression state = thisVariable.getField(stateField); states.add(state); } body.comment("output(state_0, state_1, ..., out)"); states.forEach(body::append); body.append(out); body.append(invoke(callSiteBinder.bind(outputFunction), "output")); body.ret(); }
private void generateProjectMethod( ClassDefinition classDefinition, CallSiteBinder callSiteBinder, CachedInstanceBinder cachedInstanceBinder, Map<LambdaDefinitionExpression, CompiledLambda> compiledLambdaMap, String methodName, RowExpression projection) { Parameter session = arg("session", ConnectorSession.class); Parameter cursor = arg("cursor", RecordCursor.class); Parameter output = arg("output", BlockBuilder.class); MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), methodName, type(void.class), session, cursor, output); method.comment("Projection: %s", projection.toString()); Scope scope = method.getScope(); Variable wasNullVariable = scope.declareVariable(type(boolean.class), "wasNull"); RowExpressionCompiler compiler = new RowExpressionCompiler( callSiteBinder, cachedInstanceBinder, fieldReferenceCompiler(cursor), metadata.getFunctionRegistry(), compiledLambdaMap); method.getBody() .comment("boolean wasNull = false;") .putVariable(wasNullVariable, false) .comment("evaluate projection: " + projection.toString()) .append(compiler.compile(projection, scope, Optional.of(output))) .ret(); }
private static void generateGroupedEvaluateIntermediate(ClassDefinition definition, List<StateFieldAndDescriptor> stateFieldAndDescriptors) { Parameter groupId = arg("groupId", int.class); Parameter out = arg("out", BlockBuilder.class); MethodDefinition method = definition.declareMethod(a(PUBLIC), "evaluateIntermediate", type(void.class), groupId, out); Variable thisVariable = method.getThis(); BytecodeBlock body = method.getBody(); if (stateFieldAndDescriptors.size() == 1) { BytecodeExpression stateSerializer = thisVariable.getField(getOnlyElement(stateFieldAndDescriptors).getStateSerializerField()); BytecodeExpression state = thisVariable.getField(getOnlyElement(stateFieldAndDescriptors).getStateField()); body.append(state.invoke("setGroupId", void.class, groupId.cast(long.class))) .append(stateSerializer.invoke("serialize", void.class, state.cast(Object.class), out)) .ret(); } else { Variable rowBuilder = method.getScope().declareVariable(BlockBuilder.class, "rowBuilder"); body.append(rowBuilder.set(out.invoke("beginBlockEntry", BlockBuilder.class))); for (int i = 0; i < stateFieldAndDescriptors.size(); i++) { BytecodeExpression stateSerializer = thisVariable.getField(stateFieldAndDescriptors.get(i).getStateSerializerField()); BytecodeExpression state = thisVariable.getField(stateFieldAndDescriptors.get(i).getStateField()); body.append(state.invoke("setGroupId", void.class, groupId.cast(long.class))) .append(stateSerializer.invoke("serialize", void.class, state.cast(Object.class), rowBuilder)); } body.append(out.invoke("closeEntry", BlockBuilder.class).pop()) .ret(); } }
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(); }
private static void generateEvaluateIntermediate(ClassDefinition definition, List<StateFieldAndDescriptor> stateFieldAndDescriptors) { Parameter out = arg("out", BlockBuilder.class); MethodDefinition method = definition.declareMethod( a(PUBLIC), "evaluateIntermediate", type(void.class), out); Variable thisVariable = method.getThis(); BytecodeBlock body = method.getBody(); if (stateFieldAndDescriptors.size() == 1) { BytecodeExpression stateSerializer = thisVariable.getField(getOnlyElement(stateFieldAndDescriptors).getStateSerializerField()); BytecodeExpression state = thisVariable.getField(getOnlyElement(stateFieldAndDescriptors).getStateField()); body.append(stateSerializer.invoke("serialize", void.class, state.cast(Object.class), out)) .ret(); } else { Variable rowBuilder = method.getScope().declareVariable(BlockBuilder.class, "rowBuilder"); body.append(rowBuilder.set(out.invoke("beginBlockEntry", BlockBuilder.class))); for (int i = 0; i < stateFieldAndDescriptors.size(); i++) { BytecodeExpression stateSerializer = thisVariable.getField(stateFieldAndDescriptors.get(i).getStateSerializerField()); BytecodeExpression state = thisVariable.getField(stateFieldAndDescriptors.get(i).getStateField()); body.append(stateSerializer.invoke("serialize", void.class, state.cast(Object.class), rowBuilder)); } body.append(out.invoke("closeEntry", BlockBuilder.class).pop()) .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(); } }
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(); }
.mapToObj(i -> arg("arg" + i, Slice.class)) .collect(toImmutableList());
private static void generateIsPositionNull(ClassDefinition classDefinition, List<FieldDefinition> joinChannelFields) { Parameter blockIndex = arg("blockIndex", int.class); Parameter blockPosition = arg("blockPosition", int.class); MethodDefinition isPositionNullMethod = classDefinition.declareMethod( a(PUBLIC), "isPositionNull", type(boolean.class), blockIndex, blockPosition); for (FieldDefinition joinChannelField : joinChannelFields) { BytecodeExpression block = isPositionNullMethod .getThis() .getField(joinChannelField) .invoke("get", Object.class, blockIndex) .cast(Block.class); IfStatement ifStatement = new IfStatement(); ifStatement.condition(block.invoke( "isNull", boolean.class, blockPosition)); ifStatement.ifTrue(constantTrue().ret()); isPositionNullMethod.getBody().append(ifStatement); } isPositionNullMethod .getBody() .append(constantFalse().ret()); }
@Inject public EmbedVersion(ServerConfig serverConfig) { ClassDefinition classDefinition = new ClassDefinition( a(PUBLIC, FINAL), makeClassName(baseClassName(serverConfig)), type(Object.class), type(Runnable.class)); FieldDefinition field = classDefinition.declareField(a(PRIVATE), "runnable", Runnable.class); Parameter parameter = arg("runnable", type(Runnable.class)); MethodDefinition constructor = classDefinition.declareConstructor(a(PUBLIC), parameter); constructor.getBody() .comment("super(runnable);") .append(constructor.getThis()) .invokeConstructor(Object.class) .append(constructor.getThis()) .append(parameter) .putField(field) .ret(); MethodDefinition run = classDefinition.declareMethod(a(PUBLIC), "run", type(void.class)); run.getBody() .comment("runnable.run();") .append(run.getThis()) .getField(field) .invokeInterface(Runnable.class, "run", void.class) .ret(); Class<? extends Runnable> generatedClass = defineClass(classDefinition, Runnable.class, ImmutableMap.of(), getClass().getClassLoader()); this.runnableConstructor = constructorMethodHandle(generatedClass, Runnable.class); }
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 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); 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.getJavaType().isPrimitive()) { ifBlock.append(state.invoke("setSecond", void.class, otherState.invoke("getSecond", valueType.getJavaType()))); } else { ifBlock.append(new BytecodeBlock() .append(state.invoke("setSecondBlock", void.class, otherState.invoke("getSecondBlock", Block.class))) .append(state.invoke("setSecondPosition", void.class, otherState.invoke("getSecondPosition", int.class)))); } 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(); }
private static FieldDefinition generateGroupedField(ClassDefinition definition, MethodDefinition constructor, MethodDefinition ensureCapacity, StateField stateField) { Class<?> bigArrayType = getBigArrayType(stateField.getType()); FieldDefinition field = definition.declareField(a(PRIVATE), UPPER_CAMEL.to(LOWER_CAMEL, stateField.getName()) + "Values", bigArrayType); // Generate getter MethodDefinition getter = definition.declareMethod(a(PUBLIC), stateField.getGetterName(), type(stateField.getType())); getter.getBody() .append(getter.getThis().getField(field).invoke( "get", stateField.getType(), getter.getThis().invoke("getGroupId", long.class)) .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().getField(field).invoke( "set", void.class, setter.getThis().invoke("getGroupId", long.class), value)) .ret(); Scope ensureCapacityScope = ensureCapacity.getScope(); ensureCapacity.getBody() .append(ensureCapacity.getThis().getField(field).invoke("ensureCapacity", void.class, ensureCapacityScope.getVariable("size"))); // Initialize field in constructor constructor.getBody() .append(constructor.getThis().setField(field, newInstance(field.getType(), stateField.initialValueExpression()))); return field; }