diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogJoiner.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogJoiner.java index 1a4c81ad3662..43dd771f60a0 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogJoiner.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogJoiner.java @@ -208,54 +208,55 @@ public class VcsLogJoiner { /*package*/ static class NewCommitIntegrator { private final List list; private final Map newCommitsMap; - private final Collection newCommits; + + private final Stack commitsStack; public NewCommitIntegrator(@NotNull List list, @NotNull Collection newCommits) { this.list = list; newCommitsMap = ContainerUtil.newHashMap(); - this.newCommits = newCommits; for (Commit commit : newCommits) { newCommitsMap.put(commit.getHash(), commit); } + commitsStack = new Stack(); } - // return insert Index - private void insertToList(@NotNull Commit commit) { - if (!newCommitsMap.containsKey(commit.getHash())) { - throw new IllegalStateException("Commit was inserted, but insert call again. Commit hash: " + commit.getHash()); - } - //insert all parents commits - for (Hash parentHash : commit.getParents()) { - Commit parentCommit = newCommitsMap.get(parentHash); - if (parentCommit != null) { - insertToList(parentCommit); - } - } + private void insertAllUseStack() { + while (!newCommitsMap.isEmpty()) { + commitsStack.push(newCommitsMap.values().iterator().next()); + while (!commitsStack.isEmpty()) { + Commit currentCommit = commitsStack.peek(); + boolean allParentsWereAdded = true; + for (Hash parentHash : currentCommit.getParents()) { + Commit parentCommit = newCommitsMap.get(parentHash); + if (parentCommit != null) { + commitsStack.push(parentCommit); + allParentsWereAdded = false; + break; + } + } - int insertIndex; - HashSet parents = new HashSet(commit.getParents()); - for (insertIndex = 0; insertIndex < list.size(); insertIndex++) { - Commit currentCommit = list.get(insertIndex); - if (parents.contains(currentCommit.getHash())) - break; - if (currentCommit.getTime() < commit.getTime()) - break; - } + if (!allParentsWereAdded) + continue; - list.add(insertIndex, commit); - newCommitsMap.remove(commit.getHash()); - } + int insertIndex; + HashSet parents = new HashSet(currentCommit.getParents()); + for (insertIndex = 0; insertIndex < list.size(); insertIndex++) { + Commit someCommit = list.get(insertIndex); + if (parents.contains(someCommit.getHash())) + break; + if (someCommit.getTime() < currentCommit.getTime()) + break; + } - private void insertAllCommits() { - for (Commit commit : newCommits) { - if (newCommitsMap.get(commit.getHash()) != null) { - insertToList(commit); + list.add(insertIndex, currentCommit); + newCommitsMap.remove(currentCommit.getHash()); + commitsStack.pop(); } } } public List getResultList() { - insertAllCommits(); + insertAllUseStack(); return list; } }