Patchwork [6,of,7] reachableroots: use internal "revstates" array to test if rev is reachable

login
register
mail settings
Submitter Yuya Nishihara
Date Aug. 18, 2015, 2:42 p.m.
Message ID <9a0ff0541db15438c019.1439908978@mimosa>
Download mbox | patch
Permalink /patch/10228/
State Accepted
Delegated to: Augie Fackler
Headers show

Comments

Yuya Nishihara - Aug. 18, 2015, 2:42 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1439534951 -32400
#      Fri Aug 14 15:49:11 2015 +0900
# Node ID 9a0ff0541db15438c019d5a3db6184c84c6b4c25
# Parent  93e5cd30d2ff9b63f11616054cb647d6ac998053
reachableroots: use internal "revstates" array to test if rev is reachable

This is faster than using PySet_Contains().

  revset #0: 0::tip
  1) 0.003678
  2) 0.002536  68%

Patch

diff --git a/mercurial/parsers.c b/mercurial/parsers.c
--- a/mercurial/parsers.c
+++ b/mercurial/parsers.c
@@ -1132,7 +1132,7 @@  static PyObject *reachableroots(indexObj
 	 * revstates: array of length len+1 (all revs + nullrev) */
 	int *tovisit = NULL;
 	long lentovisit = 0;
-	enum { RS_SEEN = 1, RS_ROOT = 2 };
+	enum { RS_SEEN = 1, RS_ROOT = 2, RS_REACHABLE = 4 };
 	char *revstates = NULL;
 
 	/* Get arguments */
@@ -1198,6 +1198,7 @@  static PyObject *reachableroots(indexObj
 		/* Add the node to reachable if it is a root*/
 		revnum = tovisit[k++];
 		if (revstates[revnum + 1] & RS_ROOT) {
+			revstates[revnum + 1] |= RS_REACHABLE;
 			val = PyInt_FromLong(revnum);
 			if (val == NULL)
 				goto bail;
@@ -1237,17 +1238,14 @@  static PyObject *reachableroots(indexObj
 			if (r < 0)
 				goto bail;
 			for (k = 0; k < 2; k++) {
-				PyObject *p = PyInt_FromLong(parents[k]);
-				if (p == NULL)
-					goto bail;
-				if (PySet_Contains(reachable, p) == 1) {
+				if (revstates[parents[k] + 1] & RS_REACHABLE) {
+					revstates[i + 1] |= RS_REACHABLE;
 					val = PyInt_FromLong(i);
 					if (val == NULL)
 						goto bail;
 					PySet_Add(reachable, val);
 					Py_DECREF(val);
 				}
-				Py_DECREF(p);
 			}
 		}
 	}