Mercurial > jhg
diff src/org/tmatesoft/hg/repo/Revlog.java @ 171:2c3e96674e2a
Towards outgoing changes - initial detection logic, get connected with remote repo stub
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Fri, 25 Mar 2011 00:05:52 +0100 |
parents | d5268ca7715b |
children | 9807bf8f3a9c |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/repo/Revlog.java Wed Mar 23 20:46:00 2011 +0100 +++ b/src/org/tmatesoft/hg/repo/Revlog.java Fri Mar 25 00:05:52 2011 +0100 @@ -25,7 +25,10 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; import java.util.Map; import java.util.Set; @@ -199,11 +202,10 @@ public final class ParentWalker { private Map<Nodeid, Nodeid> firstParent; private Map<Nodeid, Nodeid> secondParent; - private Set<Nodeid> allNodes; + private final LinkedHashSet<Nodeid> allNodes = new LinkedHashSet<Nodeid>(); // childrenOf rely on ordering public ParentWalker() { firstParent = secondParent = Collections.emptyMap(); - allNodes = Collections.emptySet(); } public void init() { @@ -211,7 +213,6 @@ final int revisionCount = stream.revisionCount(); firstParent = new HashMap<Nodeid, Nodeid>(revisionCount); secondParent = new HashMap<Nodeid, Nodeid>(firstParent.size() >> 1); // assume branches/merges are less frequent - allNodes = new LinkedHashSet<Nodeid>(); RevlogStream.Inspector insp = new RevlogStream.Inspector() { final Nodeid[] sequentialRevisionNodeids = new Nodeid[revisionCount]; @@ -279,6 +280,36 @@ } return modified; } + + // XXX alternative (and perhaps more reliable) approach would be to make a copy of allNodes and remove + // nodes, their parents and so on. + + // @return ordered collection of all children rooted at supplied nodes. Nodes shall not be descendants of each other! + public List<Nodeid> childrenOf(List<Nodeid> nodes) { + HashSet<Nodeid> parents = new HashSet<Nodeid>(); + LinkedHashSet<Nodeid> result = new LinkedHashSet<Nodeid>(); + LinkedList<Nodeid> orderedResult = new LinkedList<Nodeid>(); + for(Nodeid next : allNodes) { + // i assume allNodes is sorted, hence do not check any parents unless we hit any common known node first + if (nodes.contains(next)) { + parents.add(next); + } else { + if (parents.isEmpty()) { + // didn't scroll up to any known yet + continue; + } + // record each and every node reported after first common known node hit + orderedResult.addLast(next); + if (parents.contains(firstParent(next)) || parents.contains(secondParent(next))) { + result.add(next); + parents.add(next); // to find next's children + } + } + } + // leave only those of interest in ordered sequence + orderedResult.retainAll(result); + return orderedResult; + } } protected static class ContentPipe implements RevlogStream.Inspector, CancelSupport {