comparison mercurial/parsers.c @ 26054:5049e10fed14

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%
author Yuya Nishihara <yuya@tcha.org>
date Fri, 14 Aug 2015 15:49:11 +0900
parents b68c9d232db6
children 607868eccaa7
comparison
equal deleted inserted replaced
26053:b68c9d232db6 26054:5049e10fed14
1133 /* Internal data structure: 1133 /* Internal data structure:
1134 * tovisit: array of length len+1 (all revs + nullrev), filled upto lentovisit 1134 * tovisit: array of length len+1 (all revs + nullrev), filled upto lentovisit
1135 * revstates: array of length len+1 (all revs + nullrev) */ 1135 * revstates: array of length len+1 (all revs + nullrev) */
1136 int *tovisit = NULL; 1136 int *tovisit = NULL;
1137 long lentovisit = 0; 1137 long lentovisit = 0;
1138 enum { RS_SEEN = 1, RS_ROOT = 2 }; 1138 enum { RS_SEEN = 1, RS_ROOT = 2, RS_REACHABLE = 4 };
1139 char *revstates = NULL; 1139 char *revstates = NULL;
1140 1140
1141 /* Get arguments */ 1141 /* Get arguments */
1142 if (!PyArg_ParseTuple(args, "lO!O!O!", &minroot, &PyList_Type, &heads, 1142 if (!PyArg_ParseTuple(args, "lO!O!O!", &minroot, &PyList_Type, &heads,
1143 &PyList_Type, &roots, 1143 &PyList_Type, &roots,
1199 k = 0; 1199 k = 0;
1200 while (k < lentovisit) { 1200 while (k < lentovisit) {
1201 /* Add the node to reachable if it is a root*/ 1201 /* Add the node to reachable if it is a root*/
1202 revnum = tovisit[k++]; 1202 revnum = tovisit[k++];
1203 if (revstates[revnum + 1] & RS_ROOT) { 1203 if (revstates[revnum + 1] & RS_ROOT) {
1204 revstates[revnum + 1] |= RS_REACHABLE;
1204 val = PyInt_FromLong(revnum); 1205 val = PyInt_FromLong(revnum);
1205 if (val == NULL) 1206 if (val == NULL)
1206 goto bail; 1207 goto bail;
1207 PySet_Add(reachable, val); 1208 PySet_Add(reachable, val);
1208 Py_DECREF(val); 1209 Py_DECREF(val);
1238 /* Corrupted index file, error is set from 1239 /* Corrupted index file, error is set from
1239 * index_get_parents */ 1240 * index_get_parents */
1240 if (r < 0) 1241 if (r < 0)
1241 goto bail; 1242 goto bail;
1242 for (k = 0; k < 2; k++) { 1243 for (k = 0; k < 2; k++) {
1243 PyObject *p = PyInt_FromLong(parents[k]); 1244 if (revstates[parents[k] + 1] & RS_REACHABLE) {
1244 if (p == NULL) 1245 revstates[i + 1] |= RS_REACHABLE;
1245 goto bail;
1246 if (PySet_Contains(reachable, p) == 1) {
1247 val = PyInt_FromLong(i); 1246 val = PyInt_FromLong(i);
1248 if (val == NULL) 1247 if (val == NULL)
1249 goto bail; 1248 goto bail;
1250 PySet_Add(reachable, val); 1249 PySet_Add(reachable, val);
1251 Py_DECREF(val); 1250 Py_DECREF(val);
1252 } 1251 }
1253 Py_DECREF(p);
1254 } 1252 }
1255 } 1253 }
1256 } 1254 }
1257 1255
1258 free(revstates); 1256 free(revstates);