Skip to content

Remove redundant type parameters and enforce some other style and inspection rules#5980

Merged
leventov merged 30 commits intoapache:masterfrom
asdf2014:various_changes
Jul 27, 2018
Merged

Remove redundant type parameters and enforce some other style and inspection rules#5980
leventov merged 30 commits intoapache:masterfrom
asdf2014:various_changes

Conversation

@asdf2014
Copy link
Copy Markdown
Member

@asdf2014 asdf2014 commented Jul 9, 2018

Various changes:

  1. Fix calling to toArray() with pre-sized array argument for better performance;
  2. Use lambda to complete the initialization of Module / Runnable / Accumulator;
  3. Remove unuesed import;
  4. Improve if-return clause;
  5. Use Set#addAll instead of for loop;
  6. Use Collections.<...>singletonList instead of Arrays.<...>asList for single element situation;
  7. Use file.toURI().toURL() instead of file.toURL();
  8. Remove unnecessary unboxing;
  9. Put the string object in front of the equals method;
  10. Use Collections.<StorageLocationConfig>emptyList() instead of Arrays.<StorageLocationConfig>asList();
  11. Add a few coding inspection rules, includes ArraysAsListWithZeroOrOneArgument, RedundantTypeArguments and ToArrayCallWithZeroLengthArrayArgument;
  12. Add a few regexps about String#equals and toArray(new Object[0]) into checkstyle config file.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Please make this final.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be Collections.singletonList.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be final.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be Collections.emptyList().

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please break the line per comma like below:

binder, 
Key.get(MetadataStorageConnectorConfig.class), 
new MetadataStorageConnectorConfig()
{
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be final.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a corresponding inspection in IntelliJ, could you assign it ERROR severity (you could do it via IntelliJ interface; the change should appear in https://github.com/apache/incubator-druid/blob/master/.idea/inspectionProfiles/Druid.xml) so such problems are caught by CI.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Indeed, in this way, such a similar work will be more effective. By the way, can we learn from Alibaba's Java coding specification project P3C. Although the specifications in it are not completely correct... For example, i just submitted the issue about the pre-allocated size toArray method to P3C a few days ago. 😅

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already add ToArrayCallWithZeroLengthArrayArgument specification into profile.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because, File.toURL() is deprecated.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add this method to our forbidden-apis file: https://github.com/apache/incubator-druid/blob/master/codestyle/druid-forbidden-apis.txt. When adding, please check that it works by intentionally leaving one call to this method in the code, and see if mvn clean install -DskipTests fails locally. For syntax, see https://github.com/policeman-tools/forbidden-apis/wiki/SignaturesSyntax.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Boolean.parseBoolean returns a primitive

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need for the .booleanValue() method, cuz Java will automatically unbox Boolean primitive after JDK 5+.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean there is no need to get a boxed Boolean either, Boolean.parseBoolean() is a direct equivalent which returns a primitive.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. I will fix it.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also worth catching this consistently, via IntelliJ inspection

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Original intellij inspection profile only catches obj != null && obj.equals("") situation, rather than obj.equals("")

image

After adding AliEqualsAvoidNull inspection into profile, it can recognizes obj.equals("") case

image

But, AliEqualsAvoidNull inspection need P3C plugin... What you think? @leventov

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PS: The origin intellij inspection about string equals is SimplifiableEqualsExpression

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you could catch those things merely using a regex, [a-z][a-zA-Z0-9_]*\.equals\((\"|[A-Z_]+\)) (intended to catch javaVar.equals("string") and javaVar.equals(STRING_CONSTANT)). You could add this regex to the checkstyle config: https://github.com/apache/incubator-druid/blob/master/codestyle/checkstyle.xml#L168

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you wish you could also fix all occurrences of this, via IntelliJ inspection "Too few arguments of Arrays.asList()", and prohibit it on CI level. There are hundreds of such issues in the codebase, but since there is an automatic fix in IntelliJ, it could be even not very hard to do this.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I will add this situation to the Intellij inspection configuration file. In this way, each newly added developer will notice this coding specification without having to read some sort of HOW TO CONTRIBUTE documents. 👍

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already add ArraysAsListWithZeroOrOneArgument specification into profile.

@asdf2014 asdf2014 changed the title Various changes about druid-services module Various changes about a few coding specifications Jul 11, 2018
@asdf2014
Copy link
Copy Markdown
Member Author

job-402722329 and job-402722330 both failed...

job-402722329:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.19.1:test (default-test) on project druid-processing: ExecutionException The forked VM terminated without properly saying goodbye. VM crash or System.exit called?
[ERROR] Command was /bin/sh -c cd /home/travis/build/apache/incubator-druid/processing && /usr/lib/jvm/java-8-oracle/jre/bin/java -Xmx768m -Duser.language=en -Duser.country=US -Dfile.encoding=UTF-8 -Duser.timezone=UTC -Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager -Ddruid.indexing.doubleStorage=double -jar /home/travis/build/apache/incubator-druid/processing/target/surefire/surefirebooter678641966742689650.jar /home/travis/build/apache/incubator-druid/processing/target/surefire/surefire1266228946009469426tmp /home/travis/build/apache/incubator-druid/processing/target/surefire/surefire_14722988346361641729tmp

It seems that -Xmx768m is not enough, may we should add -Xmx2048m -Xms512m for maven-surefire-plugin in druid-processing module?

job-402722330:

CuratorDruidCoordinatorTest.testMoveSegment:369 »  test timed out after 60000 ...

After PR#5978, sometimes the timeout value is still not enough.

…ease the timeout value for testMoveSegment testcase
@jihoonson
Copy link
Copy Markdown
Contributor

The last commit is not related to this PR. Please make it as another one.

@asdf2014
Copy link
Copy Markdown
Member Author

Hi, @jihoonson . Already roll back the latest commit. I will create a independent PR for it. But, if the travis happens VM crash or testcase timeout cases again, please help me to rebuild the failed job. Thanks. 😃

@jihoonson
Copy link
Copy Markdown
Contributor

@asdf2014 sure, I'll restart failed jobs if they're transient. BTW, the size of this PR looks suddenly increased. What commit has increased the size?

@asdf2014
Copy link
Copy Markdown
Member Author

These commits are a bit large.. 😅

image

@asdf2014
Copy link
Copy Markdown
Member Author

Under the advice of @leventov . After adding ToArrayCallWithZeroLengthArrayArgument & ArraysAsListWithZeroOrOneArgument & AliEqualsAvoidNull into intellij inspection profile, I automatically fix the entire project's coding inspection problems through the intellij idea tool.

@jihoonson
Copy link
Copy Markdown
Contributor

@asdf2014 thanks. I'll take another look.

@asdf2014
Copy link
Copy Markdown
Member Author

asdf2014 commented Jul 12, 2018

@jihoonson You are welcome. The amount of code is large and very troublesome. May have to trouble you. 👍

@asdf2014
Copy link
Copy Markdown
Member Author

Hi, @jihoonson . jobs-403482349 failed again.. Could you please rebuild it?

@jihoonson
Copy link
Copy Markdown
Contributor

jihoonson commented Jul 13, 2018

@asdf2014 restarted the test. Will take a look again.

@asdf2014
Copy link
Copy Markdown
Member Author

@jihoonson Thanks a lot :D

@asdf2014
Copy link
Copy Markdown
Member Author

@jihoonson It works. Thx again. 👍

@asdf2014
Copy link
Copy Markdown
Member Author

asdf2014 commented Jul 17, 2018

@leventov PTAL.

  1. Set the level of ArraysAsListWithZeroOrOneArgument inspection as warning, because use Collections.singletonList will cause a ClassCastException in io.druid.server.coordinator.CostBalancerStrategyBenchmark#factoryClasses and io.druid.collections.bitmap.WrappedRoaringBitmapTest#factoryClasses.

  2. Also set the level of ToArrayCallWithZeroLengthArrayArgument coding inspection as warning and add BY_LEVEL option, because teamcity is misunderstanding this inspection, teamcity think pre-size way is better, but it is not.

@State(Scope.Thread)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@BenchmarkMode(Mode.AverageTime)
public class ToArrayBenchmark {

    @Param({"1", "100", "1000", "5000", "10000", "100000"})
    private int n;

    private final List<Object> list = new ArrayList<>();

    @Setup
    public void populateList() {
        for (int i = 0; i < n; i++) {
            list.add(0);
        }
    }

    @Benchmark
    public Object[] preSize() {
        return list.toArray(new Object[n]);
    }

    @Benchmark
    public Object[] resize() {
        return list.toArray(new Object[0]);
    }

    /*
    Integer List:
    Benchmark                    (n)  Mode  Cnt       Score        Error  Units
    ToArrayBenchmark.preSize       1  avgt    3      41.552 ±    108.030  ns/op
    ToArrayBenchmark.preSize     100  avgt    3     216.449 ±    799.501  ns/op
    ToArrayBenchmark.preSize    1000  avgt    3    2087.965 ±   6027.778  ns/op
    ToArrayBenchmark.preSize    5000  avgt    3    9098.358 ±  14603.493  ns/op
    ToArrayBenchmark.preSize   10000  avgt    3   24204.199 ± 121468.232  ns/op
    ToArrayBenchmark.preSize  100000  avgt    3  188183.618 ± 369455.090  ns/op
    ToArrayBenchmark.resize        1  avgt    3      18.987 ±     36.449  ns/op
    ToArrayBenchmark.resize      100  avgt    3     265.549 ±   1125.008  ns/op
    ToArrayBenchmark.resize     1000  avgt    3    1560.713 ±   2922.186  ns/op
    ToArrayBenchmark.resize     5000  avgt    3    7804.810 ±   8333.390  ns/op
    ToArrayBenchmark.resize    10000  avgt    3   24791.026 ±  78459.936  ns/op
    ToArrayBenchmark.resize   100000  avgt    3  158891.642 ±  56055.895  ns/op
    Object List:
    Benchmark                    (n)  Mode  Cnt      Score       Error  Units
    ToArrayBenchmark.preSize       1  avgt    3     36.306 ±    96.612  ns/op
    ToArrayBenchmark.preSize     100  avgt    3     52.372 ±    84.159  ns/op
    ToArrayBenchmark.preSize    1000  avgt    3    449.807 ±   215.692  ns/op
    ToArrayBenchmark.preSize    5000  avgt    3   2080.172 ±  2003.726  ns/op
    ToArrayBenchmark.preSize   10000  avgt    3   4657.937 ±  8432.624  ns/op
    ToArrayBenchmark.preSize  100000  avgt    3  51980.829 ± 46920.314  ns/op
    ToArrayBenchmark.resize        1  avgt    3     16.747 ±    85.131  ns/op
    ToArrayBenchmark.resize      100  avgt    3     43.803 ±    28.704  ns/op
    ToArrayBenchmark.resize     1000  avgt    3    404.681 ±   132.986  ns/op
    ToArrayBenchmark.resize     5000  avgt    3   1972.649 ±   174.691  ns/op
    ToArrayBenchmark.resize    10000  avgt    3   4021.440 ±  1114.212  ns/op
    ToArrayBenchmark.resize   100000  avgt    3  44204.167 ± 76714.850  ns/op
     */
    public static void main(String[] args) throws Exception {
        Options opt = new OptionsBuilder()
                .include(ToArrayBenchmark.class.getSimpleName())
                .forks(1)
                .warmupIterations(1)
                .measurementIterations(3)
                .threads(1)
                .build();
        new Runner(opt).run();
    }
}

Tips: Full code is here.

  1. Added [a-z][a-zA-Z0-9_]*\.equals\((\"|[A-Z_]+\)) into checkstyle config file.

  2. Added java.io.File#toURL() into druid-forbidden-apis.

@leventov
Copy link
Copy Markdown
Member

@asdf2014

  1. I don't know why CostBalancerStrategyBenchmark and WrappedRoaringBitmapTest are written in such an obscure way, you could fix the code to create arrays directly: new CostBalancerStrategy[] { new CostBalancerStrategy(MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(1))) }, etc. and retain the inspection at the ERROR level.

  2. It was fixed only recently: https://youtrack.jetbrains.com/issue/IDEA-184862, probably Youtrack didn't pick up the fix yet. I think you could also catch all such situations using a regex, something like toArray\([\s\n]*new [a-zA-Z0-9_]+\[[^0]

@asdf2014
Copy link
Copy Markdown
Member Author

Hi, @leventov . It has been fixed. BTW, jobs-405249198 failed because vm crashed. Would you please help me rebuild it once?

…ck the level of ToArrayCallWithZeroLengthArrayArgument as WARNING until Youtrack fix it
@asdf2014
Copy link
Copy Markdown
Member Author

@leventov It seems that both travis and teamcity have succeeded. Any other good suggestions?

Comment thread codestyle/checkstyle.xml
<property name="message" value="Use java.lang.Primitive.BYTES instead."/>
</module>

<module name="Regexp">
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a comment that this regex should be replaced with an IntelliJ inspection when teamcity.jetbrains.com updates to at least IntelliJ 2018.1 (currently it uses 2017.2)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

Sequence<Result<TopNResultValue>> queryResult = theRunner.run(
QueryPlus.wrap(query),
Maps.<String, Object>newHashMap()
Maps.newHashMap()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you remove redundant type arguments in the whole codebase? If so, you could try to change the level of the corresponding IntelliJ inspection ("Redundant type arguments") to ERROR.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

{
return Arrays.<AggregatorFactory>asList(new DistinctCountAggregatorFactory(fieldName, fieldName, bitMapFactory));
return Collections.singletonList(
new DistinctCountAggregatorFactory(fieldName, fieldName, bitMapFactory));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not formatted properly, the closing ); should be on the next line (or the whole expression on a single line).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

public List<AggregatorFactory> getRequiredColumns()
{
return Arrays.<AggregatorFactory>asList(new TimestampAggregatorFactory(fieldName, fieldName, timeFormat, comparator, initValue));
return Collections.singletonList(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@asdf2014
Copy link
Copy Markdown
Member Author

Hi, @leventov . Thanks for your review. The RedundantTypeArguments has been added as an ERROR level check and teamcity has also been passed. PTAL.

Copy link
Copy Markdown
Member

@leventov leventov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for this contribution, cleaning up the source is important but nobody usually does this.

@asdf2014
Copy link
Copy Markdown
Member Author

You are welcome. In the process, I also learned a lot. 👍

@leventov leventov changed the title Various changes about a few coding specifications Remove redundant type parameters and enforce some other style and inspection rules Jul 21, 2018
@jihoonson
Copy link
Copy Markdown
Contributor

@asdf2014 would you update the PR description to include additional changes? E.g., Added new inspection/checkstyle rules.

@asdf2014
Copy link
Copy Markdown
Member Author

Hi, @jihoonson . Thanks for you comments. Added.

@jihoonson
Copy link
Copy Markdown
Contributor

Thanks @asdf2014! The latest change looks good to me.

One side comment: usually, you can expect your PR can be reviewed faster as your PR contains less changes because it's much easier to review. It would be great if you can split your PRs if possible in the future.

@leventov leventov merged commit 331a0af into apache:master Jul 27, 2018
@asdf2014
Copy link
Copy Markdown
Member Author

@jihoonson Thanks for your suggestion about the PR stuff. This is very helpful for me. I will notice it. 👍

@asdf2014 asdf2014 deleted the various_changes branch July 30, 2018 03:03
@dclim dclim added this to the 0.13.0 milestone Oct 8, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants