mercurial/parsers.c
changeset 26053 b68c9d232db6
parent 26052 b970418bbafe
child 26054 5049e10fed14
equal deleted inserted replaced
26052:b970418bbafe 26053:b68c9d232db6
  1106 		phases[i] = phases[parent_1];
  1106 		phases[i] = phases[parent_1];
  1107 	if (parent_2 >= 0 && phases[parent_2] > phases[i])
  1107 	if (parent_2 >= 0 && phases[parent_2] > phases[i])
  1108 		phases[i] = phases[parent_2];
  1108 		phases[i] = phases[parent_2];
  1109 }
  1109 }
  1110 
  1110 
  1111 static PyObject *reachableroots(indexObject *self, PyObject *args)
  1111 static PyObject *reachableroots2(indexObject *self, PyObject *args)
  1112 {
  1112 {
  1113 
  1113 
  1114 	/* Input */
  1114 	/* Input */
  1115 	long minroot;
  1115 	long minroot;
  1116 	PyObject *includepatharg = NULL;
  1116 	PyObject *includepatharg = NULL;
  1117 	int includepath = 0;
  1117 	int includepath = 0;
  1118 	/* heads is a list */
  1118 	/* heads and roots are lists */
  1119 	PyObject *heads = NULL;
  1119 	PyObject *heads = NULL;
  1120 	/* roots is a set */
       
  1121 	PyObject *roots = NULL;
  1120 	PyObject *roots = NULL;
  1122 	PyObject *reachable = NULL;
  1121 	PyObject *reachable = NULL;
  1123 
  1122 
  1124 	PyObject *val;
  1123 	PyObject *val;
  1125 	Py_ssize_t len = index_length(self) - 1;
  1124 	Py_ssize_t len = index_length(self) - 1;
  1134 	/* Internal data structure:
  1133 	/* Internal data structure:
  1135 	 * 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
  1136 	 * revstates: array of length len+1 (all revs + nullrev) */
  1135 	 * revstates: array of length len+1 (all revs + nullrev) */
  1137 	int *tovisit = NULL;
  1136 	int *tovisit = NULL;
  1138 	long lentovisit = 0;
  1137 	long lentovisit = 0;
  1139 	enum { RS_SEEN = 1 };
  1138 	enum { RS_SEEN = 1, RS_ROOT = 2 };
  1140 	char *revstates = NULL;
  1139 	char *revstates = NULL;
  1141 
  1140 
  1142 	/* Get arguments */
  1141 	/* Get arguments */
  1143 	if (!PyArg_ParseTuple(args, "lO!O!O!", &minroot, &PyList_Type, &heads,
  1142 	if (!PyArg_ParseTuple(args, "lO!O!O!", &minroot, &PyList_Type, &heads,
  1144 				&PySet_Type, &roots, &PyBool_Type, &includepatharg))
  1143 			      &PyList_Type, &roots,
       
  1144 			      &PyBool_Type, &includepatharg))
  1145 		goto bail;
  1145 		goto bail;
  1146 
  1146 
  1147 	if (includepatharg == Py_True)
  1147 	if (includepatharg == Py_True)
  1148 		includepath = 1;
  1148 		includepath = 1;
  1149 
  1149 
  1165 	if (revstates == NULL) {
  1165 	if (revstates == NULL) {
  1166 		PyErr_NoMemory();
  1166 		PyErr_NoMemory();
  1167 		goto bail;
  1167 		goto bail;
  1168 	}
  1168 	}
  1169 
  1169 
       
  1170 	l = PyList_GET_SIZE(roots);
       
  1171 	for (i = 0; i < l; i++) {
       
  1172 		revnum = PyInt_AsLong(PyList_GET_ITEM(roots, i));
       
  1173 		if (revnum == -1 && PyErr_Occurred())
       
  1174 			goto bail;
       
  1175 		/* If root is out of range, e.g. wdir(), it must be unreachable
       
  1176 		 * from heads. So we can just ignore it. */
       
  1177 		if (revnum + 1 < 0 || revnum + 1 >= len + 1)
       
  1178 			continue;
       
  1179 		revstates[revnum + 1] |= RS_ROOT;
       
  1180 	}
       
  1181 
  1170 	/* Populate tovisit with all the heads */
  1182 	/* Populate tovisit with all the heads */
  1171 	l = PyList_GET_SIZE(heads);
  1183 	l = PyList_GET_SIZE(heads);
  1172 	for (i = 0; i < l; i++) {
  1184 	for (i = 0; i < l; i++) {
  1173 		revnum = PyInt_AsLong(PyList_GET_ITEM(heads, i));
  1185 		revnum = PyInt_AsLong(PyList_GET_ITEM(heads, i));
  1174 		if (revnum == -1 && PyErr_Occurred())
  1186 		if (revnum == -1 && PyErr_Occurred())
  1186 	/* Visit the tovisit list and find the reachable roots */
  1198 	/* Visit the tovisit list and find the reachable roots */
  1187 	k = 0;
  1199 	k = 0;
  1188 	while (k < lentovisit) {
  1200 	while (k < lentovisit) {
  1189 		/* Add the node to reachable if it is a root*/
  1201 		/* Add the node to reachable if it is a root*/
  1190 		revnum = tovisit[k++];
  1202 		revnum = tovisit[k++];
  1191 		val = PyInt_FromLong(revnum);
  1203 		if (revstates[revnum + 1] & RS_ROOT) {
  1192 		if (val == NULL)
  1204 			val = PyInt_FromLong(revnum);
  1193 			goto bail;
  1205 			if (val == NULL)
  1194 		if (PySet_Contains(roots, val) == 1) {
  1206 				goto bail;
  1195 			PySet_Add(reachable, val);
  1207 			PySet_Add(reachable, val);
  1196 			if (includepath == 0) {
  1208 			Py_DECREF(val);
  1197 				Py_DECREF(val);
  1209 			if (includepath == 0)
  1198 				continue;
  1210 				continue;
  1199 			}
  1211 		}
  1200 		}
       
  1201 		Py_DECREF(val);
       
  1202 
  1212 
  1203 		/* Add its parents to the list of nodes to visit */
  1213 		/* Add its parents to the list of nodes to visit */
  1204 		if (revnum == -1)
  1214 		if (revnum == -1)
  1205 			continue;
  1215 			continue;
  1206 		r = index_get_parents(self, revnum, parents, (int)len - 1);
  1216 		r = index_get_parents(self, revnum, parents, (int)len - 1);
  2432 	 "clear the index caches"},
  2442 	 "clear the index caches"},
  2433 	{"get", (PyCFunction)index_m_get, METH_VARARGS,
  2443 	{"get", (PyCFunction)index_m_get, METH_VARARGS,
  2434 	 "get an index entry"},
  2444 	 "get an index entry"},
  2435 	{"computephasesmapsets", (PyCFunction)compute_phases_map_sets,
  2445 	{"computephasesmapsets", (PyCFunction)compute_phases_map_sets,
  2436 			METH_VARARGS, "compute phases"},
  2446 			METH_VARARGS, "compute phases"},
  2437 	{"reachableroots", (PyCFunction)reachableroots, METH_VARARGS,
  2447 	{"reachableroots2", (PyCFunction)reachableroots2, METH_VARARGS,
  2438 		"reachableroots"},
  2448 		"reachableroots"},
  2439 	{"headrevs", (PyCFunction)index_headrevs, METH_VARARGS,
  2449 	{"headrevs", (PyCFunction)index_headrevs, METH_VARARGS,
  2440 	 "get head revisions"}, /* Can do filtering since 3.2 */
  2450 	 "get head revisions"}, /* Can do filtering since 3.2 */
  2441 	{"headrevsfiltered", (PyCFunction)index_headrevs, METH_VARARGS,
  2451 	{"headrevsfiltered", (PyCFunction)index_headrevs, METH_VARARGS,
  2442 	 "get filtered head revisions"}, /* Can always do filtering */
  2452 	 "get filtered head revisions"}, /* Can always do filtering */