Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 package com.facebook.presto.sql.gen;
 
 
 import java.util.List;
 
 import static com.facebook.presto.byteCode.Access.PUBLIC;
 import static com.facebook.presto.byteCode.Access.a;
 import static com.facebook.presto.byteCode.NamedParameterDefinition.arg;
 import static com.facebook.presto.byteCode.OpCode.NOP;
 import static com.facebook.presto.byteCode.ParameterizedType.type;
 import static com.facebook.presto.byteCode.control.ForLoop.ForLoopBuilder;
 import static com.facebook.presto.byteCode.control.IfStatement.IfStatementBuilder;
 import static com.facebook.presto.sql.gen.Bootstrap.BOOTSTRAP_METHOD;
 import static com.facebook.presto.sql.gen.ByteCodeUtils.generateWrite;
 import static com.facebook.presto.sql.gen.ByteCodeUtils.loadConstant;
 import static java.lang.String.format;
 import static java.util.Collections.nCopies;
 
 public class PageProcessorCompiler
         implements BodyCompiler<PageProcessor>
 {
     private final Metadata metadata;
 
     public PageProcessorCompiler(Metadata metadata)
     {
         this. = metadata;
     }
 
     @Override
     public void generateMethods(ClassDefinition classDefinitionCallSiteBinder callSiteBinderRowExpression filterList<RowExpressionprojections)
     {
         generateProcessMethod(classDefinitionfilterprojections);
         generateFilterMethod(classDefinitioncallSiteBinderfilter);
 
         for (int i = 0; i < projections.size(); i++) {
             generateProjectMethod(classDefinitioncallSiteBinder"project_" + iprojections.get(i));
         }
     }
 
     private void generateProcessMethod(ClassDefinition classDefinitionRowExpression filterList<RowExpressionprojections)
     {
         CompilerContext context = new CompilerContext();
         MethodDefinition method = classDefinition.declareMethod(context,
                 a(),
                 "process",
                 type(int.class),
                 arg("session"ConnectorSession.class),
                 arg("page"Page.class),
                 arg("start"int.class),
                 arg("end"int.class),
                 arg("pageBuilder"PageBuilder.class));
 
         Variable sessionVariable = context.getVariable("session");
         Variable pageVariable = context.getVariable("page");
         Variable startVariable = context.getVariable("start");
         Variable endVariable = context.getVariable("end");
         Variable pageBuilderVariable = context.getVariable("pageBuilder");
 
        Variable positionVariable = context.declareVariable(int.class"position");
        method.getBody()
                .comment("int position = start;")
                .getVariable(startVariable)
                .putVariable(positionVariable);
        List<IntegerallInputChannels = getInputChannels(Iterables.concat(projections, ImmutableList.of(filter)));
        for (int channel : allInputChannels) {
            Variable blockVariable = context.declareVariable(com.facebook.presto.spi.block.Block.class"block_" + channel);
            method.getBody()
                    .comment("Block %s = page.getBlock(%s);"blockVariable.getName(), channel)
                    .getVariable(pageVariable)
                    .push(channel)
                    .invokeVirtual(Page.class"getBlock"com.facebook.presto.spi.block.Block.classint.class)
                    .putVariable(blockVariable);
        }
        //
        // for loop loop body
        //
        LabelNode done = new LabelNode("done");
        Block loopBody = new Block(context);
        ForLoopBuilder loop = ForLoop.forLoopBuilder(context)
                .initialize()
                .condition(new Block(context)
                                .comment("position < end")
                                .getVariable(positionVariable)
                                .getVariable(endVariable)
                                .invokeStatic(CompilerOperations.class"lessThan"boolean.classint.classint.class)
                )
                .update(new Block(context)
                        .comment("position++")
                        .incrementVariable(positionVariable, (byte) 1))
                .body(loopBody);
        loopBody.comment("if (pageBuilder.isFull()) break;")
                .getVariable(pageBuilderVariable)
                .invokeVirtual(PageBuilder.class"isFull"boolean.class)
                .ifTrueGoto(done);
        // if (filter(cursor))
        IfStatementBuilder filterBlock = new IfStatementBuilder(context);
        Block trueBlock = new Block(context);
        filterBlock.condition(new Block(context)
                .pushThis()
                .getVariable(sessionVariable)
                .append(pushBlockVariables(contextgetInputChannels(filter)))
                .getVariable(positionVariable)
                .invokeVirtual(classDefinition.getType(),
                        "filter",
                        type(boolean.class),
                        ImmutableList.<ParameterizedType>builder()
                                .add(type(ConnectorSession.class))
                                .addAll(nCopies(getInputChannels(filter).size(), type(com.facebook.presto.spi.block.Block.class)))
                                .add(type(int.class))
                                .build()))
                .ifTrue(trueBlock);
        trueBlock.getVariable(pageBuilderVariable)
                .invokeVirtual(PageBuilder.class"declarePosition"void.class);
        for (int projectionIndex = 0; projectionIndex < projections.size(); projectionIndex++) {
            List<IntegerinputChannels = getInputChannels(projections.get(projectionIndex));
            trueBlock.pushThis()
                    .getVariable(sessionVariable)
                    .append(pushBlockVariables(contextinputChannels))
                    .getVariable(positionVariable);
            trueBlock.comment("pageBuilder.getBlockBuilder(" + projectionIndex + ")")
                    .getVariable(pageBuilderVariable)
                    .push(projectionIndex)
                    .invokeVirtual(PageBuilder.class"getBlockBuilder"BlockBuilder.classint.class);
            trueBlock.comment("project_" + projectionIndex + "(session, block_" + inputChannels + ", position, blockBuilder)")
                    .invokeVirtual(classDefinition.getType(),
                            "project_" + projectionIndex,
                            type(void.class),
                            ImmutableList.<ParameterizedType>builder()
                                    .add(type(ConnectorSession.class))
                                    .addAll(nCopies(inputChannels.size(), type(com.facebook.presto.spi.block.Block.class)))
                                    .add(type(int.class))
                                    .add(type(BlockBuilder.class))
                                    .build());
        }
        loopBody.append(filterBlock.build());
        method.getBody()
                .append(loop.build())
                .visitLabel(done)
                .comment("return position;")
                .getVariable(positionVariable)
                .retInt();
    }
    private void generateFilterMethod(ClassDefinition classDefinitionCallSiteBinder callSiteBinderRowExpression filter)
    {
        CompilerContext context = new CompilerContext();
        MethodDefinition method = classDefinition.declareMethod(context,
                a(),
                "filter",
                type(boolean.class),
                ImmutableList.<NamedParameterDefinition>builder()
                        .add(arg("session"ConnectorSession.class))
                        .addAll(toBlockParameters(getInputChannels(filter)))
                        .add(arg("position"int.class))
                        .build());
        method.comment("Filter: %s"filter.toString());
        Variable positionVariable = context.getVariable("position");
        Variable wasNullVariable = context.declareVariable(type(boolean.class), "wasNull");
        ByteCodeExpressionVisitor visitor = new ByteCodeExpressionVisitor(
                callSiteBinder,
                fieldReferenceCompiler(callSiteBinderpositionVariablewasNullVariable),
                .getFunctionRegistry());
        ByteCodeNode body = filter.accept(visitorcontext);
        LabelNode end = new LabelNode("end");
        method
                .getBody()
                .comment("boolean wasNull = false;")
                .putVariable(wasNullVariablefalse)
                .append(body)
                .getVariable(wasNullVariable)
                .ifFalseGoto(end)
                .pop(boolean.class)
                .push(false)
                .visitLabel(end)
                .retBoolean();
    }
    private void generateProjectMethod(ClassDefinition classDefinitionCallSiteBinder callSiteBinderString methodNameRowExpression projection)
    {
        CompilerContext context = new CompilerContext();
        MethodDefinition method = classDefinition.declareMethod(context,
                a(),
                methodName,
                type(void.class),
                ImmutableList.<NamedParameterDefinition>builder()
                        .add(arg("session"ConnectorSession.class))
                        .addAll(toBlockParameters(getInputChannels(projection)))
                        .add(arg("position"int.class))
                        .add(arg("output"BlockBuilder.class))
                        .build());
        method.comment("Projection: %s"projection.toString());
        Variable positionVariable = context.getVariable("position");
        Variable outputVariable = context.getVariable("output");
        Variable wasNullVariable = context.declareVariable(type(boolean.class), "wasNull");
        Block body = method.getBody()
                .comment("boolean wasNull = false;")
                .putVariable(wasNullVariableprojection.getType().getJavaType() == void.class);
        ByteCodeExpressionVisitor visitor = new ByteCodeExpressionVisitor(callSiteBinderfieldReferenceCompiler(callSiteBinderpositionVariablewasNullVariable), .getFunctionRegistry());
        body.getVariable(outputVariable)
                .comment("evaluate projection: " + projection.toString())
                .append(projection.accept(visitorcontext))
                .append(generateWrite(callSiteBindercontextwasNullVariableprojection.getType()))
                .ret();
    }
    private static List<IntegergetInputChannels(Iterable<RowExpressionexpressions)
    {
        TreeSet<Integerchannels = new TreeSet<>();
        for (RowExpression expression : Expressions.subExpressions(expressions)) {
            if (expression instanceof InputReferenceExpression) {
                channels.add(((InputReferenceExpressionexpression).getField());
            }
        }
        return ImmutableList.copyOf(channels);
    }
    private static List<IntegergetInputChannels(RowExpression expression)
    {
        return getInputChannels(ImmutableList.of(expression));
    }
    private static List<NamedParameterDefinitiontoBlockParameters(List<IntegerinputChannels)
    {
        ImmutableList.Builder<NamedParameterDefinitionparameters = ImmutableList.builder();
        for (int channel : inputChannels) {
            parameters.add(arg("block_" + channelcom.facebook.presto.spi.block.Block.class));
        }
        return parameters.build();
    }
    private static ByteCodeNode pushBlockVariables(CompilerContext contextList<Integerinputs)
    {
        Block block = new Block(context);
        for (int channel : inputs) {
            block.getVariable("block_" + channel);
        }
        return block;
    }
    private RowExpressionVisitor<CompilerContextByteCodeNodefieldReferenceCompiler(final CallSiteBinder callSiteBinderfinal Variable positionVariablefinal Variable wasNullVariable)
    {
        return new RowExpressionVisitor<CompilerContextByteCodeNode>()
        {
            @Override
            public ByteCodeNode visitInputReference(InputReferenceExpression nodeCompilerContext context)
            {
                int field = node.getField();
                Type type = node.getType();
                Class<?> javaType = type.getJavaType();
                Block isNullCheck = new Block(context)
                        .setDescription(format("block_%d.get%s()"fieldtype))
                        .getVariable("block_" + field)
                        .getVariable(positionVariable)
                        .invokeInterface(com.facebook.presto.spi.block.Block.class"isNull"boolean.classint.class);
                Block isNull = new Block(context)
                        .putVariable(wasNullVariabletrue)
                        .pushJavaDefault(javaType);
                String methodName = "get" + Primitives.wrap(javaType).getSimpleName();
                Block isNotNull = new Block(context)
                        .append(loadConstant(contextcallSiteBinder.bind(typeType.class)))
                        .getVariable("block_" + field)
                        .getVariable(positionVariable)
                        .invokeInterface(Type.classmethodNamejavaTypecom.facebook.presto.spi.block.Block.classint.class);
                return new IfStatement(contextisNullCheckisNullisNotNull);
            }
            @Override
            public ByteCodeNode visitCall(CallExpression callCompilerContext context)
            {
                throw new UnsupportedOperationException("not yet implemented");
            }
            @Override
            public ByteCodeNode visitConstant(ConstantExpression literalCompilerContext context)
            {
                throw new UnsupportedOperationException("not yet implemented");
            }
        };
    }
New to GrepCode? Check out our FAQ X