private static BytecodeNode typeEqualsIgnoreNulls( BytecodeExpression type, BytecodeExpression leftBlock, BytecodeExpression leftBlockPosition, BytecodeExpression rightBlock, BytecodeExpression rightBlockPosition) { return type.invoke("equalTo", boolean.class, leftBlock, leftBlockPosition, rightBlock, rightBlockPosition); }
private static BytecodeNode typeHashCode(BytecodeExpression type, BytecodeExpression blockRef, BytecodeExpression blockPosition) { return new IfStatement() .condition(blockRef.invoke("isNull", boolean.class, blockPosition)) .ifTrue(constantLong(0L)) .ifFalse(type.invoke("hash", long.class, blockRef, blockPosition)); }
private static BytecodeNode typeEquals( BytecodeExpression type, BytecodeExpression leftBlock, BytecodeExpression leftBlockPosition, BytecodeExpression rightBlock, BytecodeExpression rightBlockPosition) { IfStatement ifStatement = new IfStatement(); ifStatement.condition() .append(leftBlock.invoke("isNull", boolean.class, leftBlockPosition)) .append(rightBlock.invoke("isNull", boolean.class, rightBlockPosition)) .append(OpCode.IOR); ifStatement.ifTrue() .append(leftBlock.invoke("isNull", boolean.class, leftBlockPosition)) .append(rightBlock.invoke("isNull", boolean.class, rightBlockPosition)) .append(OpCode.IAND); ifStatement.ifFalse().append(typeEqualsIgnoreNulls(type, leftBlock, leftBlockPosition, rightBlock, rightBlockPosition)); return ifStatement; }
private static void generateEnsureCapacity(Scope scope, List<FieldDefinition> stateFields, BytecodeBlock block) { Variable groupIdsBlock = scope.getVariable("groupIdsBlock"); for (FieldDefinition stateField : stateFields) { BytecodeExpression state = scope.getThis().getField(stateField); block.append(state.invoke("ensureCapacity", void.class, groupIdsBlock.invoke("getGroupCount", long.class))); } }
private static void generateSetGroupIdFromGroupIdsBlock(Scope scope, List<FieldDefinition> stateFields, BytecodeBlock block) { Variable groupIdsBlock = scope.getVariable("groupIdsBlock"); Variable position = scope.getVariable("position"); for (FieldDefinition stateField : stateFields) { BytecodeExpression state = scope.getThis().getField(stateField); block.append(state.invoke("setGroupId", void.class, groupIdsBlock.invoke("getGroupId", long.class, position))); } }
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 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 InputReferenceNode(CallSiteBinder callSiteBinder, Scope scope, Type type, BytecodeExpression block, BytecodeExpression position) { // Generate body based on block and position Variable wasNullVariable = scope.getVariable("wasNull"); Class<?> javaType = type.getJavaType(); if (!javaType.isPrimitive() && javaType != Slice.class) { javaType = Object.class; } IfStatement ifStatement = new IfStatement(); ifStatement.condition(block.invoke("isNull", boolean.class, position)); ifStatement.ifTrue() .putVariable(wasNullVariable, true) .pushJavaDefault(javaType); String methodName = "get" + Primitives.wrap(javaType).getSimpleName(); ifStatement.ifFalse(constantType(callSiteBinder, type).invoke(methodName, javaType, block, position)); this.body = ifStatement; this.block = block; this.position = position; }
.invoke("apply", Object.class, map.cast(Object.class)) .cast(returnType) .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 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 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()); }
.invoke("compareBlockValue", int.class, ImmutableList.of(Type.class, Block.class, int.class, Block.class, int.class),
.invoke("get", Object.class, blockIndex) .cast(Block.class);
BytecodeExpression leftBlock = thisVariable .getField(joinChannelFields.get(index)) .invoke("get", Object.class, leftBlockIndex) .cast(Block.class);
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; }
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()); }
body.append(size.set(add(size, getEstimatedSize.getThis().getField(field).invoke("sizeOf", long.class))));
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(); }
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();