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 BytecodeExpression generateCheckedAdd(BytecodeExpression x, BytecodeExpression y) { return invokeStatic(ConcatFunction.class, "checkedAdd", int.class, x, y); }
private static BytecodeExpression generateRequireNotNull(Variable variable) { return invokeStatic(Objects.class, "requireNonNull", Object.class, variable.cast(Object.class), constantString(variable.getName() + " is null")) .cast(variable.getType()); }
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()); }
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 BytecodeExpression anyParametersAreNull( List<ParameterMetadata> parameterMetadatas, Variable index, Variable channels, Variable position) { int inputChannel = 0; BytecodeExpression isNull = constantFalse(); for (ParameterMetadata parameterMetadata : parameterMetadatas) { switch (parameterMetadata.getParameterType()) { case BLOCK_INPUT_CHANNEL: case INPUT_CHANNEL: BytecodeExpression getChannel = channels.invoke("get", Object.class, constantInt(inputChannel)).cast(int.class); isNull = BytecodeExpressions.or(isNull, index.invoke("isNull", boolean.class, getChannel, position)); inputChannel++; break; case NULLABLE_BLOCK_INPUT_CHANNEL: inputChannel++; break; } } return isNull; }
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 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()); }
public BytecodeExpression initialValueExpression() { if (initialValue == null) { return defaultValue(type); } if (initialValue instanceof Number) { return constantNumber((Number) initialValue); } else if (initialValue instanceof Boolean) { return constantBoolean((boolean) initialValue); } else { throw new IllegalArgumentException("Unsupported initial value type: " + initialValue.getClass()); } } }
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)); }
public BytecodeExpression getValue(BytecodeExpression block, BytecodeExpression position) { Class<?> fromJavaElementType = type.getJavaType(); if (fromJavaElementType == boolean.class) { return invoke("getBoolean", boolean.class, block, position); } if (fromJavaElementType == long.class) { return invoke("getLong", long.class, block, position); } if (fromJavaElementType == double.class) { return invoke("getDouble", double.class, block, position); } if (fromJavaElementType == Slice.class) { return invoke("getSlice", Slice.class, block, position); } return invoke("getObject", Object.class, block, position).cast(fromJavaElementType); }
private static RowExpressionVisitor<BytecodeNode, Scope> fieldReferenceCompiler( final CallSiteBinder callSiteBinder, final Variable leftPosition, final Variable leftPage, final Variable rightPosition, final Variable rightPage, final int leftBlocksSize) { return new InputReferenceCompiler( (scope, field) -> { if (field < leftBlocksSize) { return leftPage.invoke("getBlock", Block.class, constantInt(field)); } return rightPage.invoke("getBlock", Block.class, constantInt(field - leftBlocksSize)); }, (scope, field) -> field < leftBlocksSize ? leftPosition : rightPosition, callSiteBinder); }
public static BytecodeExpression invoke(Binding binding, String name) { return invokeDynamic(BOOTSTRAP_METHOD, ImmutableList.of(binding.getBindingId()), name, binding.getType()); }
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; }
public BytecodeExpression writeValue(BytecodeExpression blockBuilder, BytecodeExpression value) { Class<?> fromJavaElementType = type.getJavaType(); if (fromJavaElementType == boolean.class) { return invoke("writeBoolean", void.class, blockBuilder, value); } if (fromJavaElementType == long.class) { return invoke("writeLong", void.class, blockBuilder, value); } if (fromJavaElementType == double.class) { return invoke("writeDouble", void.class, blockBuilder, value); } if (fromJavaElementType == Slice.class) { return invoke("writeSlice", void.class, blockBuilder, value); } return invoke("writeObject", void.class, blockBuilder, value.cast(Object.class)); } }
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))); } }
public static BytecodeExpression loadConstant(Binding binding) { return invokeDynamic( BOOTSTRAP_METHOD, ImmutableList.of(binding.getBindingId()), "constant_" + binding.getBindingId(), binding.getType().returnType()); }
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 BytecodeBlock generateBlockNonNullPositionForLoop(Scope scope, Variable positionVariable, BytecodeBlock loopBody) { Variable rowsVariable = scope.declareVariable(int.class, "rows"); Variable blockVariable = scope.getVariable("block"); BytecodeBlock block = new BytecodeBlock() .append(blockVariable) .invokeInterface(Block.class, "getPositionCount", int.class) .putVariable(rowsVariable); IfStatement ifStatement = new IfStatement("if(!block.isNull(position))") .condition(new BytecodeBlock() .append(blockVariable) .append(positionVariable) .invokeInterface(Block.class, "isNull", boolean.class, int.class)) .ifFalse(loopBody); block.append(new ForLoop() .initialize(positionVariable.set(constantInt(0))) .condition(new BytecodeBlock() .append(positionVariable) .append(rowsVariable) .invokeStatic(CompilerOperations.class, "lessThan", boolean.class, int.class, int.class)) .update(new BytecodeBlock().incrementVariable(positionVariable, (byte) 1)) .body(ifStatement)); return block; }
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))); } }