示例#1
0
 private TypeDeclaration createType() {
   SimpleName name = factory.newSimpleName(Naming.getCombineClass());
   importer.resolvePackageMember(name);
   List<TypeBodyDeclaration> members = new ArrayList<TypeBodyDeclaration>();
   members.addAll(prepareFields());
   members.add(createSetup());
   members.add(createCleanup());
   members.add(createGetRendezvous());
   return factory.newClassDeclaration(
       new JavadocBuilder(factory)
           .text("ステージ{0}の処理を担当するコンバイナープログラム。", shuffle.getStageBlock().getStageNumber())
           .toJavadoc(),
       new AttributeBuilder(factory)
           .annotation(t(SuppressWarnings.class), v("deprecation"))
           .Public()
           .Final()
           .toAttributes(),
       name,
       Collections.<TypeParameterDeclaration>emptyList(),
       importer.resolve(
           factory.newParameterizedType(
               Models.toType(factory, SegmentedCombiner.class),
               Arrays.asList(
                   importer.toType(shuffle.getCompiled().getKeyTypeName()),
                   importer.toType(shuffle.getCompiled().getValueTypeName())))),
       Collections.<Type>emptyList(),
       members);
 }
    private MethodDeclaration createGetter(Segment segment) {
      assert segment != null;
      String methodName = Naming.getShuffleValueGetter(segment.getPortId());

      List<Statement> statements = new ArrayList<Statement>();
      statements.add(
          factory.newIfStatement(
              new ExpressionBuilder(factory, factory.newThis())
                  .field(SEGMENT_ID_FIELD_NAME)
                  .apply(InfixOperator.NOT_EQUALS, v(segment.getPortId()))
                  .toExpression(),
              new TypeBuilder(factory, t(AssertionError.class)).newObject().toThrowStatement(),
              null));

      statements.add(
          new ExpressionBuilder(factory, factory.newThis())
              .field(createPropertyName(segment))
              .toReturnStatement());

      return factory.newMethodDeclaration(
          new JavadocBuilder(factory)
              .text(
                  "{0}#{1}のモデルオブジェクトを返す。",
                  segment.getPort().getOwner().getDescription().getName(),
                  segment.getPort().getDescription().getName())
              .toJavadoc(),
          new AttributeBuilder(factory).Public().toAttributes(),
          t(segment.getTarget().getType()),
          factory.newSimpleName(methodName),
          Collections.<FormalParameterDeclaration>emptyList(),
          statements);
    }
示例#3
0
    private List<FieldDeclaration> prepareFields() {
      List<FieldDeclaration> fields = new ArrayList<FieldDeclaration>();

      // shufles
      for (ShuffleModel.Segment segment : shuffle.getSegments()) {
        SimpleName shuffleName = names.create("shuffle");
        shuffleNames.put(segment, shuffleName);
        Name shuffleTypeName = segment.getCompiled().getCombineOutputType().getQualifiedName();
        fields.add(
            factory.newFieldDeclaration(
                null,
                new AttributeBuilder(factory).Private().toAttributes(),
                importer.toType(shuffleTypeName),
                shuffleName,
                null));
      }

      // rendezvous
      for (ReduceUnit unit : reduceUnits) {
        if (unit.canCombine() == false) {
          continue;
        }
        Fragment first = unit.getFragments().get(0);
        SimpleName rendezvousName = names.create("combine");
        rendezvousNames.put(first, rendezvousName);
        fields.add(
            factory.newFieldDeclaration(
                null,
                new AttributeBuilder(factory).Private().toAttributes(),
                importer.toType(first.getCompiled().getQualifiedName()),
                rendezvousName,
                null));
      }
      return fields;
    }
 private FieldDeclaration createSegmentIdField() {
   return factory.newFieldDeclaration(
       new JavadocBuilder(factory).text("セグメント番号。").toJavadoc(),
       new AttributeBuilder(factory).Public().toAttributes(),
       t(int.class),
       factory.newSimpleName(SEGMENT_ID_FIELD_NAME),
       v(-1));
 }
 @Override
 public List<Annotation> getTypeAnnotations(EmitContext context, ModelDeclaration model)
     throws IOException {
   Type type = generate(context, model);
   ModelFactory f = context.getModelFactory();
   return new AttributeBuilder(f)
       .annotation(
           context.resolve(ModelInputLocation.class), f.newClassLiteral(context.resolve(type)))
       .toAnnotations();
 }
 private TypeBodyDeclaration createSegmentIdGetter() {
   Statement body =
       new ExpressionBuilder(factory, factory.newThis())
           .field(SEGMENT_ID_FIELD_NAME)
           .toReturnStatement();
   return factory.newMethodDeclaration(
       null,
       new AttributeBuilder(factory).annotation(t(Override.class)).Public().toAttributes(),
       t(int.class),
       factory.newSimpleName(SegmentedWritable.ID_GETTER),
       Collections.<FormalParameterDeclaration>emptyList(),
       Collections.singletonList(body));
 }
 public Engine(FlowCompilingEnvironment environment, ShuffleModel model, Name keyTypeName) {
   assert environment != null;
   assert model != null;
   assert keyTypeName != null;
   this.model = model;
   this.factory = environment.getModelFactory();
   Name packageName = environment.getStagePackageName(model.getStageBlock().getStageNumber());
   this.importer =
       new ImportBuilder(
           factory,
           factory.newPackageDeclaration(packageName),
           ImportBuilder.Strategy.TOP_LEVEL);
   this.keyType = importer.resolve(factory.newNamedType(keyTypeName));
 }
示例#8
0
    private MethodDeclaration createSetup() {
      Map<FlowElementInput, Segment> segments = new HashMap<FlowElementInput, Segment>();
      List<Statement> statements = new ArrayList<Statement>();

      // shuffle outputs
      for (Map.Entry<ShuffleModel.Segment, SimpleName> entry : shuffleNames.entrySet()) {
        ShuffleModel.Segment segment = entry.getKey();
        SimpleName name = entry.getValue();
        Name shuffleTypeName = segment.getCompiled().getCombineOutputType().getQualifiedName();
        statements.add(
            new ExpressionBuilder(factory, factory.newThis())
                .field(name)
                .assignFrom(
                    new TypeBuilder(factory, importer.toType(shuffleTypeName))
                        .newObject(context)
                        .toExpression())
                .toStatement());
        segments.put(segment.getPort(), segment);
      }

      // rendezvous
      for (Map.Entry<Fragment, SimpleName> entry : rendezvousNames.entrySet()) {
        Fragment fragment = entry.getKey();
        Type rendezvousType = importer.toType(fragment.getCompiled().getQualifiedName());
        List<Expression> arguments = new ArrayList<Expression>();
        for (FlowElementInput input : fragment.getInputPorts()) {
          Segment segment = segments.get(input);
          assert segment != null;
          SimpleName shuffleName = shuffleNames.get(segment);
          assert shuffleName != null;
          arguments.add(
              new ExpressionBuilder(factory, factory.newThis()).field(shuffleName).toExpression());
        }
        SimpleName name = entry.getValue();
        statements.add(
            new ExpressionBuilder(factory, factory.newThis())
                .field(name)
                .assignFrom(
                    new TypeBuilder(factory, rendezvousType).newObject(arguments).toExpression())
                .toStatement());
      }

      return factory.newMethodDeclaration(
          null,
          new AttributeBuilder(factory).annotation(t(Override.class)).Public().toAttributes(),
          Collections.<TypeParameterDeclaration>emptyList(),
          t(void.class),
          factory.newSimpleName("setup"),
          Collections.singletonList(
              factory.newFormalParameterDeclaration(
                  factory.newNamedType(factory.newSimpleName("Context")), context)),
          0,
          Arrays.asList(t(IOException.class), t(InterruptedException.class)),
          factory.newBlock(statements));
    }
示例#9
0
 private MethodDeclaration createCleanup() {
   List<Statement> statements = new ArrayList<Statement>();
   for (SimpleName name : shuffleNames.values()) {
     statements.add(
         new ExpressionBuilder(factory, factory.newThis())
             .field(name)
             .assignFrom(Models.toNullLiteral(factory))
             .toStatement());
   }
   for (SimpleName name : rendezvousNames.values()) {
     statements.add(
         new ExpressionBuilder(factory, factory.newThis())
             .field(name)
             .assignFrom(Models.toNullLiteral(factory))
             .toStatement());
   }
   return factory.newMethodDeclaration(
       null,
       new AttributeBuilder(factory).annotation(t(Override.class)).Public().toAttributes(),
       Collections.<TypeParameterDeclaration>emptyList(),
       t(void.class),
       factory.newSimpleName("cleanup"),
       Collections.singletonList(
           factory.newFormalParameterDeclaration(
               factory.newNamedType(factory.newSimpleName("Context")), context)),
       0,
       Arrays.asList(t(IOException.class), t(InterruptedException.class)),
       factory.newBlock(statements));
 }
 private TypeBodyDeclaration createCloser() {
   return f.newMethodDeclaration(
       null,
       new AttributeBuilder(f)
           .annotation(context.resolve(Override.class))
           .Public()
           .toAttributes(),
       Collections.<TypeParameterDeclaration>emptyList(),
       context.resolve(void.class),
       f.newSimpleName("close"),
       Collections.<FormalParameterDeclaration>emptyList(),
       0,
       Collections.singletonList(context.resolve(IOException.class)),
       f.newBlock(createCloserBody()));
 }
 private TypeBodyDeclaration createConstructor() {
   return f.newConstructorDeclaration(
       new JavadocBuilder(f)
           .text("インスタンスを生成する。")
           .param(createParserFieldName())
           .text("利用するパーサー")
           .exception(context.resolve(IllegalArgumentException.class))
           .text("引数に<code>null</code>が指定された場合")
           .toJavadoc(),
       new AttributeBuilder(f).Public().toAttributes(),
       context.getTypeName(),
       Collections.singletonList(
           f.newFormalParameterDeclaration(
               context.resolve(RecordParser.class), createParserFieldName())),
       createConstructorBody());
 }
 private void emit() throws IOException {
   ClassDeclaration decl =
       f.newClassDeclaration(
           new JavadocBuilder(f)
               .text("TSVファイルなどのレコードを表すファイルを入力として<code>{0}</code>を読み出す", model.getName())
               .toJavadoc(),
           new AttributeBuilder(f).Public().Final().toAttributes(),
           context.getTypeName(),
           Collections.<TypeParameterDeclaration>emptyList(),
           null,
           Collections.singletonList(
               f.newParameterizedType(
                   context.resolve(ModelInput.class), context.resolve(model.getSymbol()))),
           createMembers());
   context.emit(decl);
 }
 private MethodDeclaration createReader() {
   return f.newMethodDeclaration(
       null,
       new AttributeBuilder(f)
           .annotation(context.resolve(Override.class))
           .Public()
           .toAttributes(),
       Collections.<TypeParameterDeclaration>emptyList(),
       context.resolve(boolean.class),
       f.newSimpleName("readTo"),
       Collections.singletonList(
           f.newFormalParameterDeclaration(
               context.resolve(model.getSymbol()), createModelParameterName())),
       0,
       Collections.singletonList(context.resolve(IOException.class)),
       f.newBlock(createReaderBody()));
 }
 private TypeBodyDeclaration createParserField() {
   return f.newFieldDeclaration(
       null,
       new AttributeBuilder(f).Private().Final().toAttributes(),
       context.resolve(RecordParser.class),
       createParserFieldName(),
       null);
 }
 public CompilationUnit generate() {
   TypeDeclaration type = createType();
   return factory.newCompilationUnit(
       importer.getPackageDeclaration(),
       importer.toImportDeclarations(),
       Collections.singletonList(type),
       Collections.<Comment>emptyList());
 }
 private FieldDeclaration createProperty(Segment segment) {
   assert segment != null;
   String name = createPropertyName(segment);
   DataClass target = segment.getTarget();
   return factory.newFieldDeclaration(
       new JavadocBuilder(factory)
           .text(
               "{0}#{1}が利用するモデル ({2})。",
               segment.getPort().getOwner().getDescription().getName(),
               segment.getPort().getDescription().getName(),
               segment.getPortId())
           .toJavadoc(),
       new AttributeBuilder(factory).Public().toAttributes(),
       t(target.getType()),
       factory.newSimpleName(name),
       target.createNewInstance(t(target.getType())));
 }
 private List<Statement> createConstructorBody() {
   List<Statement> results = new ArrayList<Statement>();
   results.add(
       f.newIfStatement(
           new ExpressionBuilder(f, createParserFieldName())
               .apply(InfixOperator.EQUALS, Models.toNullLiteral(f))
               .toExpression(),
           f.newBlock(
               new TypeBuilder(f, context.resolve(IllegalArgumentException.class))
                   .newObject(Models.toLiteral(f, createParserFieldName().getToken()))
                   .toThrowStatement())));
   results.add(
       new ExpressionBuilder(f, f.newThis(null))
           .field(createParserFieldName())
           .assignFrom(createParserFieldName())
           .toStatement());
   return results;
 }
    private List<Statement> createReaderBody() {
      List<Statement> results = new ArrayList<Statement>();

      results.add(
          f.newIfStatement(
              new ExpressionBuilder(f, createParserFieldName())
                  .method("next")
                  .apply(InfixOperator.EQUALS, Models.toLiteral(f, false))
                  .toExpression(),
              f.newBlock(
                  new ExpressionBuilder(f, Models.toLiteral(f, false)).toReturnStatement())));

      for (PropertyDeclaration property : model.getDeclaredProperties()) {
        results.add(createReaderStatement(property));
      }
      results.add(createEndRecordStatement());
      results.add(f.newReturnStatement(Models.toLiteral(f, true)));
      return results;
    }
 private TypeDeclaration createType() {
   SimpleName name = factory.newSimpleName(Naming.getShuffleValueClass());
   importer.resolvePackageMember(name);
   List<TypeBodyDeclaration> members = new ArrayList<TypeBodyDeclaration>();
   members.addAll(createSegmentDistinction());
   members.addAll(createProperties());
   members.addAll(createAccessors());
   members.addAll(createWritables());
   return factory.newClassDeclaration(
       createJavadoc(),
       new AttributeBuilder(factory)
           .annotation(t(SuppressWarnings.class), v("deprecation"))
           .Public()
           .Final()
           .toAttributes(),
       name,
       Collections.<TypeParameterDeclaration>emptyList(),
       null,
       Collections.singletonList(t(SegmentedWritable.class)),
       members);
 }
示例#20
0
    private MethodDeclaration createGetRendezvous() {
      Map<FlowElement, SimpleName> fragments = new HashMap<FlowElement, SimpleName>();
      for (Map.Entry<Fragment, SimpleName> entry : rendezvousNames.entrySet()) {
        fragments.put(entry.getKey().getFactors().get(0).getElement(), entry.getValue());
      }

      List<Statement> cases = new ArrayList<Statement>();
      for (List<ShuffleModel.Segment> group : ShuffleEmiterUtil.groupByElement(shuffle)) {
        for (ShuffleModel.Segment segment : group) {
          cases.add(factory.newSwitchCaseLabel(v(segment.getPortId())));
        }
        FlowElement element = group.get(0).getPort().getOwner();
        SimpleName rendezvousName = fragments.get(element);
        if (rendezvousName == null) {
          cases.add(
              new ExpressionBuilder(factory, Models.toNullLiteral(factory)).toReturnStatement());
        } else {
          cases.add(
              new ExpressionBuilder(factory, factory.newThis())
                  .field(rendezvousName)
                  .toReturnStatement());
        }
      }
      cases.add(factory.newSwitchDefaultLabel());
      cases.add(new TypeBuilder(factory, t(AssertionError.class)).newObject().toThrowStatement());

      SimpleName argument = names.create("nextKey");
      List<Statement> statements = new ArrayList<Statement>();
      statements.add(
          factory.newSwitchStatement(
              new ExpressionBuilder(factory, argument)
                  .method(SegmentedWritable.ID_GETTER)
                  .toExpression(),
              cases));

      return factory.newMethodDeclaration(
          null,
          new AttributeBuilder(factory).annotation(t(Override.class)).Protected().toAttributes(),
          importer.resolve(
              factory.newParameterizedType(
                  Models.toType(factory, Rendezvous.class),
                  importer.toType(shuffle.getCompiled().getValueTypeName()))),
          factory.newSimpleName(SegmentedReducer.GET_RENDEZVOUS),
          Collections.singletonList(
              factory.newFormalParameterDeclaration(
                  importer.toType(shuffle.getCompiled().getKeyTypeName()), argument)),
          statements);
    }
 private TypeDeclaration createType() {
   SimpleName name = factory.newSimpleName(Naming.getShuffleGroupingComparatorClass());
   importer.resolvePackageMember(name);
   List<TypeBodyDeclaration> members = new ArrayList<TypeBodyDeclaration>();
   members.add(createCompareBytes());
   members.add(createCompareObjects());
   members.add(ShuffleEmiterUtil.createCompareInts(factory));
   members.add(ShuffleEmiterUtil.createPortToElement(factory, model));
   return factory.newClassDeclaration(
       createJavadoc(),
       new AttributeBuilder(factory)
           .annotation(t(SuppressWarnings.class), v("rawtypes"))
           .Public()
           .toAttributes(),
       name,
       Collections.<TypeParameterDeclaration>emptyList(),
       null,
       Collections.singletonList(
           importer.resolve(
               factory.newParameterizedType(
                   t(RawComparator.class), Collections.singletonList(keyType)))),
       members);
 }
示例#22
0
 Engine(FlowCompilingEnvironment environment, StageModel model) {
   assert environment != null;
   assert model != null;
   this.reduceUnits = model.getReduceUnits();
   this.shuffle = model.getShuffleModel();
   this.factory = environment.getModelFactory();
   Name packageName = environment.getStagePackageName(model.getStageBlock().getStageNumber());
   this.importer =
       new ImportBuilder(
           factory,
           factory.newPackageDeclaration(packageName),
           ImportBuilder.Strategy.TOP_LEVEL);
   this.names = new NameGenerator(factory);
   this.context = names.create("context");
   this.shuffleNames = new HashMap<ShuffleModel.Segment, SimpleName>();
   this.rendezvousNames = new HashMap<Fragment, SimpleName>();
 }
    private MethodDeclaration createSetter(Segment segment) {
      assert segment != null;
      String methodName = Naming.getShuffleValueSetter(segment.getPortId());
      DataClass type = segment.getTarget();

      SimpleName argument = factory.newSimpleName("model");

      List<Statement> statements = new ArrayList<Statement>();
      statements.add(
          new ExpressionBuilder(factory, factory.newThis())
              .field(factory.newSimpleName(SEGMENT_ID_FIELD_NAME))
              .assignFrom(v(segment.getPortId()))
              .toStatement());
      statements.add(
          type.assign(
              new ExpressionBuilder(factory, factory.newThis())
                  .field(createPropertyName(segment))
                  .toExpression(),
              argument));

      return factory.newMethodDeclaration(
          new JavadocBuilder(factory)
              .text(
                  "{0}#{1}で使用するモデルオブジェクトを設定する。",
                  segment.getPort().getOwner().getDescription().getName(),
                  segment.getPort().getDescription().getName())
              .param(argument)
              .text("設定するモデルオブジェクト")
              .toJavadoc(),
          new AttributeBuilder(factory).Public().toAttributes(),
          t(void.class),
          factory.newSimpleName(methodName),
          Collections.singletonList(
              factory.newFormalParameterDeclaration(t(type.getType()), argument)),
          statements);
    }
    private MethodDeclaration createReadFieldsMethod() {
      SimpleName in = factory.newSimpleName("in");

      Expression segmentId =
          new ExpressionBuilder(factory, factory.newThis())
              .field(SEGMENT_ID_FIELD_NAME)
              .toExpression();

      List<Statement> statements = new ArrayList<Statement>();
      statements.add(
          new ExpressionBuilder(factory, segmentId)
              .assignFrom(new ExpressionBuilder(factory, in).method("readInt").toExpression())
              .toStatement());

      List<Statement> cases = new ArrayList<Statement>();
      for (Segment segment : model.getSegments()) {
        cases.add(factory.newSwitchCaseLabel(v(segment.getPortId())));
        String fieldName = createPropertyName(segment);
        cases.add(
            segment
                .getTarget()
                .createReader(
                    new ExpressionBuilder(factory, factory.newThis())
                        .field(fieldName)
                        .toExpression(),
                    in));
        cases.add(factory.newBreakStatement());
      }
      cases.add(factory.newSwitchDefaultLabel());
      cases.add(
          new TypeBuilder(factory, t(AssertionError.class))
              .newObject(segmentId)
              .toThrowStatement());

      statements.add(factory.newSwitchStatement(segmentId, cases));

      return factory.newMethodDeclaration(
          null,
          new AttributeBuilder(factory).annotation(t(Override.class)).Public().toAttributes(),
          Collections.<TypeParameterDeclaration>emptyList(),
          t(void.class),
          factory.newSimpleName("readFields"),
          Collections.singletonList(factory.newFormalParameterDeclaration(t(DataInput.class), in)),
          0,
          Collections.singletonList(t(IOException.class)),
          factory.newBlock(statements));
    }
    private MethodDeclaration createCompareBytes() {
      SimpleName b1 = factory.newSimpleName("b1");
      SimpleName s1 = factory.newSimpleName("s1");
      SimpleName l1 = factory.newSimpleName("l1");
      SimpleName b2 = factory.newSimpleName("b2");
      SimpleName s2 = factory.newSimpleName("s2");
      SimpleName l2 = factory.newSimpleName("l2");

      List<Statement> statements = new ArrayList<Statement>();
      SimpleName segmentId1 = factory.newSimpleName("segmentId1");
      SimpleName segmentId2 = factory.newSimpleName("segmentId2");
      statements.add(
          new TypeBuilder(factory, t(WritableComparator.class))
              .method("readInt", b1, s1)
              .toLocalVariableDeclaration(t(int.class), segmentId1));
      statements.add(
          new TypeBuilder(factory, t(WritableComparator.class))
              .method("readInt", b2, s2)
              .toLocalVariableDeclaration(t(int.class), segmentId2));

      SimpleName diff = factory.newSimpleName("diff");
      statements.add(
          new ExpressionBuilder(factory, factory.newThis())
              .method(
                  ShuffleEmiterUtil.COMPARE_INT,
                  new ExpressionBuilder(factory, factory.newThis())
                      .method(ShuffleEmiterUtil.PORT_TO_ELEMENT, segmentId1)
                      .toExpression(),
                  new ExpressionBuilder(factory, factory.newThis())
                      .method(ShuffleEmiterUtil.PORT_TO_ELEMENT, segmentId2)
                      .toExpression())
              .toLocalVariableDeclaration(t(int.class), diff));
      statements.add(createDiffBranch(diff));

      SimpleName o1 = factory.newSimpleName("o1");
      SimpleName o2 = factory.newSimpleName("o2");
      SimpleName size1 = factory.newSimpleName("size1");
      SimpleName size2 = factory.newSimpleName("size2");
      statements.add(
          new ExpressionBuilder(factory, v(4)).toLocalVariableDeclaration(t(int.class), o1));
      statements.add(
          new ExpressionBuilder(factory, v(4)).toLocalVariableDeclaration(t(int.class), o2));
      statements.add(
          new ExpressionBuilder(factory, v(-1)).toLocalVariableDeclaration(t(int.class), size1));
      statements.add(
          new ExpressionBuilder(factory, v(-1)).toLocalVariableDeclaration(t(int.class), size2));

      List<Statement> cases = new ArrayList<Statement>();
      for (List<Segment> segments : ShuffleEmiterUtil.groupByElement(model)) {
        for (Segment segment : segments) {
          cases.add(factory.newSwitchCaseLabel(v(segment.getPortId())));
        }
        for (Term term : segments.get(0).getTerms()) {
          if (term.getArrangement() != Arrangement.GROUPING) {
            continue;
          }
          cases.add(
              new ExpressionBuilder(factory, size1)
                  .assignFrom(
                      term.getSource()
                          .createBytesSize(
                              b1,
                              factory.newInfixExpression(s1, InfixOperator.PLUS, o1),
                              factory.newInfixExpression(l1, InfixOperator.MINUS, o1)))
                  .toStatement());
          cases.add(
              new ExpressionBuilder(factory, size2)
                  .assignFrom(
                      term.getSource()
                          .createBytesSize(
                              b2,
                              factory.newInfixExpression(s2, InfixOperator.PLUS, o2),
                              factory.newInfixExpression(l2, InfixOperator.MINUS, o2)))
                  .toStatement());
          cases.add(
              new ExpressionBuilder(factory, diff)
                  .assignFrom(
                      term.getSource()
                          .createBytesDiff(
                              b1,
                              factory.newInfixExpression(s1, InfixOperator.PLUS, o1),
                              size1,
                              b2,
                              factory.newInfixExpression(s2, InfixOperator.PLUS, o2),
                              size2))
                  .toStatement());
          cases.add(createDiffBranch(diff));
          cases.add(
              new ExpressionBuilder(factory, o1)
                  .assignFrom(InfixOperator.PLUS, size1)
                  .toStatement());
          cases.add(
              new ExpressionBuilder(factory, o2)
                  .assignFrom(InfixOperator.PLUS, size2)
                  .toStatement());
        }
        cases.add(factory.newBreakStatement());
      }
      cases.add(factory.newSwitchDefaultLabel());
      cases.add(new TypeBuilder(factory, t(AssertionError.class)).newObject().toThrowStatement());

      statements.add(factory.newSwitchStatement(segmentId1, cases));
      statements.add(new ExpressionBuilder(factory, v(0)).toReturnStatement());

      return factory.newMethodDeclaration(
          null,
          new AttributeBuilder(factory).annotation(t(Override.class)).Public().toAttributes(),
          t(int.class),
          factory.newSimpleName("compare"),
          Arrays.asList(
              new FormalParameterDeclaration[] {
                factory.newFormalParameterDeclaration(t(byte[].class), b1),
                factory.newFormalParameterDeclaration(t(int.class), s1),
                factory.newFormalParameterDeclaration(t(int.class), l1),
                factory.newFormalParameterDeclaration(t(byte[].class), b2),
                factory.newFormalParameterDeclaration(t(int.class), s2),
                factory.newFormalParameterDeclaration(t(int.class), l2),
              }),
          statements);
    }
 private IfStatement createDiffBranch(SimpleName diff) {
   return factory.newIfStatement(
       new ExpressionBuilder(factory, diff).apply(InfixOperator.NOT_EQUALS, v(0)).toExpression(),
       new ExpressionBuilder(factory, diff).toReturnStatement(),
       null);
 }
    private TypeBodyDeclaration createCompareObjects() {
      SimpleName o1 = factory.newSimpleName("o1");
      SimpleName o2 = factory.newSimpleName("o2");

      List<Statement> statements = new ArrayList<Statement>();
      SimpleName segmentId1 = factory.newSimpleName("segmentId1");
      SimpleName segmentId2 = factory.newSimpleName("segmentId2");
      statements.add(
          new ExpressionBuilder(factory, o1)
              .method(SegmentedWritable.ID_GETTER)
              .toLocalVariableDeclaration(t(int.class), segmentId1));
      statements.add(
          new ExpressionBuilder(factory, o2)
              .method(SegmentedWritable.ID_GETTER)
              .toLocalVariableDeclaration(t(int.class), segmentId2));

      SimpleName diff = factory.newSimpleName("diff");
      statements.add(
          new ExpressionBuilder(factory, factory.newThis())
              .method(
                  ShuffleEmiterUtil.COMPARE_INT,
                  new ExpressionBuilder(factory, factory.newThis())
                      .method(ShuffleEmiterUtil.PORT_TO_ELEMENT, segmentId1)
                      .toExpression(),
                  new ExpressionBuilder(factory, factory.newThis())
                      .method(ShuffleEmiterUtil.PORT_TO_ELEMENT, segmentId2)
                      .toExpression())
              .toLocalVariableDeclaration(t(int.class), diff));
      statements.add(createDiffBranch(diff));

      List<Statement> cases = new ArrayList<Statement>();
      for (List<Segment> segments : ShuffleEmiterUtil.groupByElement(model)) {
        for (Segment segment : segments) {
          cases.add(factory.newSwitchCaseLabel(v(segment.getPortId())));
        }
        Segment segment = segments.get(0);
        for (Term term : segment.getTerms()) {
          if (term.getArrangement() != Arrangement.GROUPING) {
            continue;
          }
          String name = ShuffleEmiterUtil.getPropertyName(segment, term);
          Expression rhs =
              term.getSource()
                  .createValueDiff(
                      new ExpressionBuilder(factory, o1).field(name).toExpression(),
                      new ExpressionBuilder(factory, o2).field(name).toExpression());
          cases.add(new ExpressionBuilder(factory, diff).assignFrom(rhs).toStatement());
          cases.add(createDiffBranch(diff));
        }
        cases.add(factory.newBreakStatement());
      }
      cases.add(factory.newSwitchDefaultLabel());
      cases.add(new TypeBuilder(factory, t(AssertionError.class)).newObject().toThrowStatement());

      statements.add(factory.newSwitchStatement(segmentId1, cases));
      statements.add(new ExpressionBuilder(factory, v(0)).toReturnStatement());

      return factory.newMethodDeclaration(
          null,
          new AttributeBuilder(factory).annotation(t(Override.class)).Public().toAttributes(),
          t(int.class),
          factory.newSimpleName("compare"),
          Arrays.asList(
              new FormalParameterDeclaration[] {
                factory.newFormalParameterDeclaration(keyType, o1),
                factory.newFormalParameterDeclaration(keyType, o2),
              }),
          statements);
    }
 private SimpleName createParserFieldName() {
   return f.newSimpleName("parser");
 }
 private SimpleName createModelParameterName() {
   return f.newSimpleName("model");
 }