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 void declareBlockVariables(RowExpression expression, Parameter page, Scope scope, BytecodeBlock body) { for (int channel : getInputChannels(expression)) { scope.declareVariable("block_" + channel, body, page.invoke("getBlock", Block.class, constantInt(channel))); } }
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(); } }
.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))); BytecodeNode setValueNode; if (valueType.getJavaType().isPrimitive()) { SqlTypeBytecodeExpression valueSqlType = constantType(binder, valueType); setValueNode = state.invoke("setSecond", void.class, valueSqlType.getValue(value, position)); .append(state.invoke("setSecondBlock", void.class, value)) .append(state.invoke("setSecondPosition", void.class, position)); .condition(value.invoke("isNull", boolean.class, position)) .ifFalse(setValueNode)); 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();
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 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(); } }
serializerBody.append(out.invoke("appendNull", BlockBuilder.class).pop()); serializerBody.append(new IfStatement() .condition(equal(fieldValue, constantNull(getter.getReturnType()))) .ifTrue(out.invoke("appendNull", BlockBuilder.class).pop()) .ifFalse(sqlType.writeValue(out, fieldValue))); serializerBody.append(rowBuilder.set(out.invoke("beginBlockEntry", BlockBuilder.class))); for (StateField field : fields) { Method getter = getGetter(clazz, field); serializerBody.append(out.invoke("closeEntry", BlockBuilder.class).pop());
.cast(Block.class); BytecodeExpression rightBlock = page.invoke("getBlock", Block.class, rightChannels.getElement(index)); body.append(new IfStatement() .condition(typeEquals(type, leftBlock, leftBlockPosition, rightBlock, rightPosition))
body.append(thisVariable.setField( stateFieldAndDescriptors.get(i).getStateSerializerField(), stateDescriptors.invoke("get", Object.class, constantInt(i)) .cast(AccumulatorStateDescriptor.class) .invoke("getSerializer", AccumulatorStateSerializer.class))); body.append(thisVariable.setField( stateFieldAndDescriptors.get(i).getStateFactoryField(), stateDescriptors.invoke("get", Object.class, constantInt(i)) .cast(AccumulatorStateDescriptor.class) .invoke("getFactory", AccumulatorStateFactory.class))); body.append(thisVariable.setField( lambdaProviderFields.get(i), lambdaProviders.invoke("get", Object.class, constantInt(i)) .cast(LambdaProvider.class)));
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(); }
BytecodeExpression channel = channels.invoke("get", Object.class, constantInt(index)) .cast(type(List.class, Block.class)); BytecodeExpression joinChannel = channels.invoke("get", Object.class, constantInt(joinChannels.get(index))) .cast(type(List.class, Block.class)); .condition(hashChannel.invoke("isPresent", boolean.class)) .ifTrue(thisVariable.setField( hashChannelField, channels.invoke("get", Object.class, hashChannel.invoke("getAsInt", int.class)))) .ifFalse(thisVariable.setField( hashChannelField,
.invoke("get", Object.class, leftBlockIndex) .cast(Block.class); BytecodeExpression rightBlock = page.invoke("getBlock", Block.class, rightChannels.getElement(index)); Type type = joinChannelTypes.get(index);
.cast(Block.class); BytecodeExpression rightBlock = rightPage.invoke("getBlock", Block.class, constantInt(index)); BytecodeNode equalityCondition; if (ignoreNulls) {
if (!field.isPrimitiveType()) { deserializerBody.append(new IfStatement() .condition(block.invoke("isNull", boolean.class, index)) .ifTrue(state.cast(setter.getDeclaringClass()).invoke(setter, constantNull(field.getType()))) .ifFalse(state.cast(setter.getDeclaringClass()).invoke(setter, constantType(binder, field.getSqlType()).getValue(block, index)))); deserializerBody.append(row.set(block.invoke("getObject", Object.class, index, constantClass(Block.class)).cast(Block.class))); int position = 0; for (StateField field : fields) {
BytecodeBlock body = method.getBody(); Variable positionCount = scope.declareVariable("positionCount", body, page.invoke("getPositionCount", int.class));
.append(new IfStatement() .condition(or( pageBuilder.invoke("isFull", boolean.class), yieldSignal.invoke("isSet", boolean.class))) .ifTrue(jump(done))) .comment("if (!cursor.advanceNextPosition()) return new CursorProcessorOutput(completedPositions, true);") .append(new IfStatement() .condition(cursor.invoke("advanceNextPosition", boolean.class)) .ifFalse(new BytecodeBlock() .putVariable(finishedVariable, true)
.append(thisVariable.setField(pageField, page)) .append(thisVariable.setField(selectedPositionsField, selectedPositions)) .append(thisVariable.setField(nextIndexOrPositionField, selectedPositions.invoke("getOffset", int.class))) .append(thisVariable.setField(resultField, constantNull(Block.class)));