Improve performance of the merging process

ComputeDiffsToMerge is very expensive. The primary public method is
getAllDiffsToMerge(Diff) and all the mergers that use this effectively
use it in a doubly nested loop, i.e., they loop over all diffs in the
comparison, and for each diff compute an order list of diffs that must
be processed in that order to properly process that one diff. Of course
that means the diffs are repeatedly visited in the inner loop, which is
most causes is guarded, but in
MergeNonConflictingRunnable.mergeWithConflicts it was not guarded, so we
were computing an order for a diff that didn't even need to be
processed.

It seems better if this class provided getAllDiffsToMerge(Iterable<?
extends Diff>) that returns on overall order for a collection of diffs
so that the caller can process diffs with a single loop that presents
the diffs in the right order.

The old implementation spent quite some time creating copies
of the diffPath set. This set can be maintained by adding and removing
the diff we're visiting.

MergeNonConflictingRunnable can make use of this new method to simplify
the loop and to make it more efficient. Same for BatchMerger.

The method AbstractMerger.getMergerDelegate is expensive and it
typically is called repeatedly for the same diff so we can cache the
result.

Finally ConflictMerger has some loop invariant computation issues.
In particular, isConflictVsMoveAndDelete is called repeatedly for a pair
of diffs doing repeated computation for a diff that's the same for each
call. Even pointless things like checking if there is a real conflict,
which must be the case because this merger is only for real conflicts.
This is changed to use a predicate that does computations while being
created (might return alwaysFalse()) or in the constructor such that
each call to the predicate only does minimal the work necessary. This
has a significant impact on performance.

Change-Id: Ia534e3f4b171637f552a113bcefb190153d5b970
Signed-off-by: Philip Langer <planger@eclipsesource.com>
5 files changed