Mercurial > jhg
diff src/org/tmatesoft/hg/repo/HgParentChildMap.java @ 646:3b7d51ed4c65
Push: phase3 - update matching remote bookmarks
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Fri, 21 Jun 2013 18:30:35 +0200 |
parents | 14dac192aa26 |
children | 3b275cc2d2aa |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/repo/HgParentChildMap.java Thu Jun 20 19:15:09 2013 +0200 +++ b/src/org/tmatesoft/hg/repo/HgParentChildMap.java Fri Jun 21 18:30:35 2013 +0200 @@ -57,14 +57,15 @@ */ public final class HgParentChildMap<T extends Revlog> implements ParentInspector { + // IMPORTANT: Nodeid instances shall be shared between all arrays + private Nodeid[] sequential; // natural repository order, childrenOf rely on ordering private Nodeid[] sorted; // for binary search - private int[] sorted2natural; + private int[] sorted2natural; // indexes in sorted to indexes in sequential private Nodeid[] firstParent; private Nodeid[] secondParent; private final T revlog; - // Nodeid instances shall be shared between all arrays public HgParentChildMap(T owner) { revlog = owner; @@ -254,4 +255,33 @@ public List<Nodeid> all() { return Arrays.asList(sequential); } + + /** + * Find out whether a given node is among descendants of another. + * + * @param root revision to check for being (grand-)*parent of a child + * @param wannaBeChild candidate descendant revision + * @return <code>true</code> if <code>wannaBeChild</code> is among children of <code>root</code> + */ + public boolean isChild(Nodeid root, Nodeid wannaBeChild) { + int x = Arrays.binarySearch(sorted, root); + assertSortedIndex(x); + root = sorted[x]; // canonical instance + int y = Arrays.binarySearch(sorted, wannaBeChild); + if (y < 0 || y <= x) { + // not found or comes earlier than root + return false; + } + wannaBeChild = sorted[y]; // canonicalize + final int start = sorted2natural[x]; + final int end = sorted2natural[y]; + HashSet<Nodeid> parents = new HashSet<Nodeid>(); + parents.add(root); + for (int i = start + 1; i < end; i++) { + if (parents.contains(firstParent[i]) || parents.contains(secondParent[i])) { + parents.add(sequential[i]); // collect ancestors line + } + } + return parents.contains(firstParent[end]) || parents.contains(secondParent[end]); + } } \ No newline at end of file