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