mercurial/parsers.c
changeset 25190 22438cfd11b5
parent 24879 b3142ea2a0d4
child 25280 8c8af4d8aca3
--- a/mercurial/parsers.c	Fri May 08 12:30:51 2015 -0700
+++ b/mercurial/parsers.c	Wed Apr 01 11:17:17 2015 -0700
@@ -1071,14 +1071,17 @@
 		phases[i] = phases[parent_2];
 }
 
-static PyObject *compute_phases(indexObject *self, PyObject *args)
+static PyObject *compute_phases_map_sets(indexObject *self, PyObject *args)
 {
 	PyObject *roots = Py_None;
+	PyObject *ret = NULL;
 	PyObject *phaseslist = NULL;
 	PyObject *phaseroots = NULL;
 	PyObject *rev = NULL;
 	PyObject *p1 = NULL;
 	PyObject *p2 = NULL;
+	PyObject *phaseset = NULL;
+	PyObject *phasessetlist = NULL;
 	Py_ssize_t addlen = self->added ? PyList_GET_SIZE(self->added) : 0;
 	Py_ssize_t len = index_length(self) - 1;
 	Py_ssize_t numphase = 0;
@@ -1088,6 +1091,7 @@
 	int parent_1, parent_2;
 	char *phases = NULL;
 	const char *data;
+	long phase;
 
 	if (!PyArg_ParseTuple(args, "O", &roots))
 		goto release_none;
@@ -1100,13 +1104,24 @@
 	/* Put the phase information of all the roots in phases */
 	numphase = PyList_GET_SIZE(roots)+1;
 	minrevallphases = len + 1;
+	phasessetlist = PyList_New(numphase);
+	if (phasessetlist == NULL)
+		goto release_none;
+
+	PyList_SET_ITEM(phasessetlist, 0, Py_None);
+	Py_INCREF(Py_None);
+
 	for (i = 0; i < numphase-1; i++) {
 		phaseroots = PyList_GET_ITEM(roots, i);
+		phaseset = PySet_New(NULL);
+		if (phaseset == NULL)
+			goto release_phasesetlist;
+		PyList_SET_ITEM(phasessetlist, i+1, phaseset);
 		if (!PyList_Check(phaseroots))
-			goto release_phases;
+			goto release_phasesetlist;
 		minrevphase = add_roots_get_min(self, phaseroots, i+1, phases);
 		if (minrevphase == -2) /* Error from add_roots_get_min */
-			goto release_phases;
+			goto release_phasesetlist;
 		minrevallphases = MIN(minrevallphases, minrevphase);
 	}
 	/* Propagate the phase information from the roots to the revs */
@@ -1121,7 +1136,7 @@
 			p2 = PyTuple_GET_ITEM(rev, 6);
 			if (!PyInt_Check(p1) || !PyInt_Check(p2)) {
 				PyErr_SetString(PyExc_TypeError, "revlog parents are invalid");
-				goto release_phases;
+				goto release_phasesetlist;
 			}
 			parent_1 = (int)PyInt_AS_LONG(p1);
 			parent_2 = (int)PyInt_AS_LONG(p2);
@@ -1131,14 +1146,35 @@
 	/* Transform phase list to a python list */
 	phaseslist = PyList_New(len);
 	if (phaseslist == NULL)
-		goto release_phases;
-	for (i = 0; i < len; i++)
-		PyList_SET_ITEM(phaseslist, i, PyInt_FromLong(phases[i]));
+		goto release_phasesetlist;
+	for (i = 0; i < len; i++) {
+		phase = phases[i];
+		/* We only store the sets of phase for non public phase, the public phase
+		 * is computed as a difference */
+		if (phase != 0) {
+			phaseset = PyList_GET_ITEM(phasessetlist, phase);
+			PySet_Add(phaseset, PyInt_FromLong(i));
+		}
+		PyList_SET_ITEM(phaseslist, i, PyInt_FromLong(phase));
+	}
+	ret = PyList_New(2);
+	if (ret == NULL)
+		goto release_phaseslist;
 
+	PyList_SET_ITEM(ret, 0, phaseslist);
+	PyList_SET_ITEM(ret, 1, phasessetlist);
+	/* We don't release phaseslist and phasessetlist as we return them to
+	 * python */
+	goto release_phases;
+
+release_phaseslist:
+	Py_XDECREF(phaseslist);
+release_phasesetlist:
+	Py_XDECREF(phasessetlist);
 release_phases:
 	free(phases);
 release_none:
-	return phaseslist;
+	return ret;
 }
 
 static PyObject *index_headrevs(indexObject *self, PyObject *args)
@@ -2278,8 +2314,8 @@
 	 "clear the index caches"},
 	{"get", (PyCFunction)index_m_get, METH_VARARGS,
 	 "get an index entry"},
-	{"computephases", (PyCFunction)compute_phases, METH_VARARGS,
-		"compute phases"},
+	{"computephasesmapsets", (PyCFunction)compute_phases_map_sets,
+			METH_VARARGS, "compute phases"},
 	{"headrevs", (PyCFunction)index_headrevs, METH_VARARGS,
 	 "get head revisions"}, /* Can do filtering since 3.2 */
 	{"headrevsfiltered", (PyCFunction)index_headrevs, METH_VARARGS,