##// END OF EJS Templates
reachableroots: add a C implementation...
Laurent Charignon -
r26004:ff89383a default
parent child Browse files
Show More
@@ -1105,6 +1105,134 b' static inline void set_phase_from_parent'
1105 phases[i] = phases[parent_2];
1105 phases[i] = phases[parent_2];
1106 }
1106 }
1107
1107
1108 static PyObject *reachableroots(indexObject *self, PyObject *args)
1109 {
1110
1111 /* Input */
1112 long minroot;
1113 PyObject *includepatharg = NULL;
1114 int includepath = 0;
1115 PyObject *heads = NULL;
1116 Py_ssize_t numheads;
1117 PyObject *roots = NULL;
1118 PyObject *reachable = NULL;
1119
1120 PyObject *val;
1121 Py_ssize_t len = index_length(self) - 1;
1122 long revnum;
1123 Py_ssize_t k;
1124 Py_ssize_t i;
1125 int r;
1126 int minidx;
1127 int parents[2];
1128
1129 /* Internal data structure:
1130 * tovisit: array of length len+1 (all revs + nullrev), filled upto lentovisit
1131 * seen: array of length len+1 (all revs + nullrev) 0: not seen, 1 seen*/
1132 int *tovisit = NULL;
1133 long lentovisit = 0;
1134 char *seen = NULL;
1135
1136 /* Get arguments */
1137 if (!PyArg_ParseTuple(args, "lO!O!O!", &minroot, &PySet_Type, &heads,
1138 &PyList_Type, &roots, &PyBool_Type, &includepatharg))
1139 goto bail;
1140
1141 if (includepatharg == Py_True)
1142 includepath = 1;
1143
1144 /* Initialize return set */
1145 reachable = PySet_New(0);
1146 if (reachable == NULL)
1147 goto bail;
1148
1149 /* Initialize internal datastructures */
1150 tovisit = (int *)malloc((len + 1) * sizeof(int));
1151 if (tovisit == NULL) {
1152 PyErr_SetNone(PyExc_MemoryError);
1153 goto release_reachable;
1154 }
1155
1156 seen = (char *)calloc(len+1, 1);
1157 if (seen == NULL) {
1158 PyErr_SetNone(PyExc_MemoryError);
1159 goto release_seen_and_tovisit;
1160 }
1161
1162 /* Populate tovisit with all the heads */
1163 numheads = PyList_GET_SIZE(heads);
1164 for (i = 0; i < numheads; i++) {
1165 revnum = PyInt_AS_LONG(PyList_GET_ITEM(heads, i));
1166 if (seen[revnum+1] == 0) {
1167 tovisit[lentovisit++] = revnum;
1168 seen[revnum+1]=1;
1169 }
1170 }
1171
1172 /* Visit the tovisit list and find the reachable roots */
1173 k = 0;
1174 while (k < lentovisit) {
1175 /* Add the node to reachable if it is a root*/
1176 revnum = tovisit[k++];
1177 val = PyInt_FromLong(revnum);
1178 if (PySet_Contains(roots, val) == 1) {
1179 PySet_Add(reachable, val);
1180 if (includepath == 0) {
1181 Py_XDECREF(val);
1182 continue;
1183 }
1184 }
1185 Py_XDECREF(val);
1186
1187 /* Add its parents to the list of nodes to visit */
1188 if (revnum != -1) {
1189 r = index_get_parents(self, revnum, parents, (int)len - 1);
1190 if (r < 0)
1191 goto release_seen_and_tovisit;
1192
1193 for (i = 0; i < 2; i++) {
1194 if (seen[parents[i] + 1] == 0 && parents[i] >= minroot) {
1195 tovisit[lentovisit++] = parents[i];
1196 seen[parents[i] + 1] = 1;
1197 }
1198 }
1199 }
1200 }
1201
1202 /* Find all the nodes in between the roots we found and the heads
1203 * and add them to the reachable set */
1204 if (includepath == 1) {
1205 minidx = minroot;
1206 if (minidx < 0)
1207 minidx = 0;
1208 for (i = minidx; i < len; i++) {
1209 if (seen[i + 1] == 1) {
1210 r = index_get_parents(self, i, parents, (int)len - 1);
1211 /* Corrupted index file, error is set from index_get_parents */
1212 if (r < 0)
1213 goto release_seen_and_tovisit;
1214 for (k = 0; k < 2; k++) {
1215 PyObject *p = PyInt_FromLong(parents[k]);
1216 if (PySet_Contains(reachable, p) == 1)
1217 PySet_Add(reachable, PyInt_FromLong(i));
1218 Py_XDECREF(p);
1219 }
1220 }
1221 }
1222 }
1223
1224 release_seen_and_tovisit:
1225 free(seen);
1226 free(tovisit);
1227 return reachable;
1228 release_reachable:
1229 Py_XDECREF(reachable);
1230 bail:
1231 val = Py_None;
1232 Py_INCREF(Py_None);
1233 return val;
1234 }
1235
1108 static PyObject *compute_phases_map_sets(indexObject *self, PyObject *args)
1236 static PyObject *compute_phases_map_sets(indexObject *self, PyObject *args)
1109 {
1237 {
1110 PyObject *roots = Py_None;
1238 PyObject *roots = Py_None;
@@ -2282,6 +2410,8 b' static PyMethodDef index_methods[] = {'
2282 "get an index entry"},
2410 "get an index entry"},
2283 {"computephasesmapsets", (PyCFunction)compute_phases_map_sets,
2411 {"computephasesmapsets", (PyCFunction)compute_phases_map_sets,
2284 METH_VARARGS, "compute phases"},
2412 METH_VARARGS, "compute phases"},
2413 {"reachableroots", (PyCFunction)reachableroots, METH_VARARGS,
2414 "reachableroots"},
2285 {"headrevs", (PyCFunction)index_headrevs, METH_VARARGS,
2415 {"headrevs", (PyCFunction)index_headrevs, METH_VARARGS,
2286 "get head revisions"}, /* Can do filtering since 3.2 */
2416 "get head revisions"}, /* Can do filtering since 3.2 */
2287 {"headrevsfiltered", (PyCFunction)index_headrevs, METH_VARARGS,
2417 {"headrevsfiltered", (PyCFunction)index_headrevs, METH_VARARGS,
General Comments 0
You need to be logged in to leave comments. Login now