예제 #1
0
  private static BytecodeExpression invokeFilter(
      BytecodeExpression objRef,
      BytecodeExpression session,
      List<? extends BytecodeExpression> blockVariables,
      BytecodeExpression position) {
    List<BytecodeExpression> params =
        ImmutableList.<BytecodeExpression>builder()
            .add(session)
            .addAll(blockVariables)
            .add(position)
            .build();

    return objRef.invoke("filter", boolean.class, params);
  }
예제 #2
0
  private static MethodDefinition generateProjectDictionaryMethod(
      ClassDefinition classDefinition,
      String methodName,
      RowExpression projection,
      MethodDefinition project,
      MethodDefinition projectColumnar) {
    Parameter session = arg("session", ConnectorSession.class);
    Parameter page = arg("page", Page.class);
    Parameter selectedPositions = arg("selectedPositions", int[].class);
    Parameter pageBuilder = arg("pageBuilder", PageBuilder.class);
    Parameter projectionIndex = arg("projectionIndex", int.class);

    List<Parameter> params =
        ImmutableList.<Parameter>builder()
            .add(session)
            .add(page)
            .add(selectedPositions)
            .add(pageBuilder)
            .add(projectionIndex)
            .build();

    MethodDefinition method =
        classDefinition.declareMethod(a(PRIVATE), methodName, type(Block.class), params);
    BytecodeBlock body = method.getBody();
    Scope scope = method.getScope();
    Variable thisVariable = method.getThis();

    List<Integer> inputChannels = getInputChannels(projection);

    if (inputChannels.size() != 1) {
      body.append(thisVariable.invoke(projectColumnar, params).ret());
      return method;
    }

    Variable inputBlock =
        scope.declareVariable(
            "inputBlock",
            body,
            page.invoke(
                "getBlock", Block.class, constantInt(Iterables.getOnlyElement(inputChannels))));
    IfStatement ifStatement =
        new IfStatement()
            .condition(inputBlock.instanceOf(DictionaryBlock.class))
            .ifFalse(thisVariable.invoke(projectColumnar, params).ret());
    body.append(ifStatement);

    Variable blockBuilder =
        scope.declareVariable(
            "blockBuilder",
            body,
            pageBuilder.invoke("getBlockBuilder", BlockBuilder.class, projectionIndex));
    Variable cardinality = scope.declareVariable("cardinality", body, selectedPositions.length());

    Variable dictionary = scope.declareVariable(Block.class, "dictionary");
    Variable ids = scope.declareVariable(Slice.class, "ids");
    Variable dictionaryCount = scope.declareVariable(int.class, "dictionaryCount");

    Variable outputDictionary = scope.declareVariable(Block.class, "outputDictionary");
    Variable outputIds = scope.declareVariable(int[].class, "outputIds");

    BytecodeExpression inputDictionaries =
        thisVariable.getField("inputDictionaries", Block[].class);
    BytecodeExpression outputDictionaries =
        thisVariable.getField("outputDictionaries", Block[].class);

    Variable position = scope.declareVariable("position", body, constantInt(0));

    body.comment("Extract dictionary and ids")
        .append(
            dictionary.set(
                inputBlock.cast(DictionaryBlock.class).invoke("getDictionary", Block.class)))
        .append(ids.set(inputBlock.cast(DictionaryBlock.class).invoke("getIds", Slice.class)))
        .append(dictionaryCount.set(dictionary.invoke("getPositionCount", int.class)));

    BytecodeBlock projectDictionary =
        new BytecodeBlock()
            .comment("Project dictionary")
            .append(
                new ForLoop()
                    .initialize(position.set(constantInt(0)))
                    .condition(lessThan(position, dictionaryCount))
                    .update(position.increment())
                    .body(
                        invokeProject(
                            thisVariable,
                            session,
                            ImmutableList.of(dictionary),
                            position,
                            pageBuilder,
                            projectionIndex,
                            project)))
            .append(outputDictionary.set(blockBuilder.invoke("build", Block.class)))
            .append(inputDictionaries.setElement(projectionIndex, dictionary))
            .append(outputDictionaries.setElement(projectionIndex, outputDictionary));

    body.comment("Use processed dictionary, if available, else project it")
        .append(
            new IfStatement()
                .condition(equal(inputDictionaries.getElement(projectionIndex), dictionary))
                .ifTrue(outputDictionary.set(outputDictionaries.getElement(projectionIndex)))
                .ifFalse(projectDictionary));

    body.comment("Filter ids")
        .append(outputIds.set(newArray(type(int[].class), cardinality)))
        .append(
            new ForLoop()
                .initialize(position.set(constantInt(0)))
                .condition(lessThan(position, cardinality))
                .update(position.increment())
                .body(
                    outputIds.setElement(
                        position,
                        ids.invoke(
                            "getInt",
                            int.class,
                            multiply(
                                selectedPositions.getElement(position),
                                constantInt(SIZE_OF_INT))))));

    body.append(
        newInstance(
                DictionaryBlock.class,
                cardinality,
                outputDictionary,
                invokeStatic(Slices.class, "wrappedIntArray", Slice.class, outputIds))
            .cast(Block.class)
            .ret());
    return method;
  }