mercurial/parsers.c
changeset 24443 539b3c7eea44
parent 24214 a5f1bccd2996
child 24499 90db70de6f9c
equal deleted inserted replaced
24442:98042b0e19f9 24443:539b3c7eea44
   909 	} else {
   909 	} else {
   910 		return 0;
   910 		return 0;
   911 	}
   911 	}
   912 }
   912 }
   913 
   913 
       
   914 static Py_ssize_t add_roots_get_min(indexObject *self, PyObject *list,
       
   915                                     int marker, char *phases)
       
   916 {
       
   917 	PyObject *iter = NULL;
       
   918 	PyObject *iter_item = NULL;
       
   919 	Py_ssize_t min_idx = index_length(self) + 1;
       
   920 	long iter_item_long;
       
   921 
       
   922 	if (PyList_GET_SIZE(list) != 0) {
       
   923 		iter = PyObject_GetIter(list);
       
   924 		if (iter == NULL)
       
   925 			return -2;
       
   926 		while ((iter_item = PyIter_Next(iter)))
       
   927 		{
       
   928 			iter_item_long = PyInt_AS_LONG(iter_item);
       
   929 			Py_DECREF(iter_item);
       
   930 			if (iter_item_long < min_idx)
       
   931 				min_idx = iter_item_long;
       
   932 			phases[iter_item_long] = marker;
       
   933 		}
       
   934 		Py_DECREF(iter);
       
   935 	}
       
   936 
       
   937 	return min_idx;
       
   938 }
       
   939 
       
   940 static inline void set_phase_from_parents(char *phases, int parent_1,
       
   941                                           int parent_2, int i)
       
   942 {
       
   943 	if (parent_1 >= 0 && phases[parent_1] > phases[i])
       
   944 		phases[i] = phases[parent_1];
       
   945 	if (parent_2 >= 0 && phases[parent_2] > phases[i])
       
   946 		phases[i] = phases[parent_2];
       
   947 }
       
   948 
       
   949 static PyObject *compute_phases(indexObject *self, PyObject *args)
       
   950 {
       
   951 	PyObject *roots = Py_None;
       
   952 	PyObject *phaseslist = NULL;
       
   953 	PyObject *phaseroots = NULL;
       
   954 	PyObject *rev = NULL;
       
   955 	PyObject *p1 = NULL;
       
   956 	PyObject *p2 = NULL;
       
   957 	Py_ssize_t addlen = self->added ? PyList_GET_SIZE(self->added) : 0;
       
   958 	Py_ssize_t len = index_length(self) - 1;
       
   959 	Py_ssize_t numphase = 0;
       
   960 	Py_ssize_t minrevallphases = 0;
       
   961 	Py_ssize_t minrevphase = 0;
       
   962 	Py_ssize_t i = 0;
       
   963 	long parent_1, parent_2;
       
   964 	char *phases = NULL;
       
   965 	const char *data;
       
   966 
       
   967 	if (!PyArg_ParseTuple(args, "O", &roots))
       
   968 		goto release_none;
       
   969 	if (roots == NULL || !PyList_Check(roots))
       
   970 		goto release_none;
       
   971 
       
   972 	phases = calloc(len, 1); /* phase per rev: {0: public, 1: draft, 2: secret} */
       
   973 	if (phases == NULL)
       
   974 		goto release_none;
       
   975 	/* Put the phase information of all the roots in phases */
       
   976 	numphase = PyList_GET_SIZE(roots)+1;
       
   977 	minrevallphases = len + 1;
       
   978 	for (i = 0; i < numphase-1; i++) {
       
   979 		phaseroots = PyList_GET_ITEM(roots, i);
       
   980 		if (!PyList_Check(phaseroots))
       
   981 			goto release_phases;
       
   982 		minrevphase = add_roots_get_min(self, phaseroots, i+1, phases);
       
   983 		if (minrevphase == -2) /* Error from add_roots_get_min */
       
   984 			goto release_phases;
       
   985 		minrevallphases = MIN(minrevallphases, minrevphase);
       
   986 	}
       
   987 	/* Propagate the phase information from the roots to the revs */
       
   988 	if (minrevallphases != -1) {
       
   989 		for (i = minrevallphases; i < self->raw_length; i++) {
       
   990 			data = index_deref(self, i);
       
   991 			set_phase_from_parents(phases, getbe32(data+24), getbe32(data+28), i);
       
   992 		}
       
   993 		for (i = 0; i < addlen; i++) {
       
   994 			rev = PyList_GET_ITEM(self->added, i);
       
   995 			p1 = PyTuple_GET_ITEM(rev, 5);
       
   996 			p2 = PyTuple_GET_ITEM(rev, 6);
       
   997 			if (!PyInt_Check(p1) || !PyInt_Check(p2)) {
       
   998 				PyErr_SetString(PyExc_TypeError, "revlog parents are invalid");
       
   999 				goto release_phases;
       
  1000 			}
       
  1001 			parent_1 = PyInt_AS_LONG(p1);
       
  1002 			parent_2 = PyInt_AS_LONG(p2);
       
  1003 			set_phase_from_parents(phases, parent_1, parent_2, i+self->raw_length);
       
  1004 		}
       
  1005 	}
       
  1006 	/* Transform phase list to a python list */
       
  1007 	phaseslist = PyList_New(len);
       
  1008 	if (phaseslist == NULL)
       
  1009 		goto release_phases;
       
  1010 	for (i = 0; i < len; i++)
       
  1011 		PyList_SET_ITEM(phaseslist, i, PyInt_FromLong(phases[i]));
       
  1012 
       
  1013 release_phases:
       
  1014 	free(phases);
       
  1015 release_none:
       
  1016 	return phaseslist;
       
  1017 }
       
  1018 
   914 static PyObject *index_headrevs(indexObject *self, PyObject *args)
  1019 static PyObject *index_headrevs(indexObject *self, PyObject *args)
   915 {
  1020 {
   916 	Py_ssize_t i, len, addlen;
  1021 	Py_ssize_t i, len, addlen;
   917 	char *nothead = NULL;
  1022 	char *nothead = NULL;
   918 	PyObject *heads = NULL;
  1023 	PyObject *heads = NULL;
  2041 	  "return the heads of the common ancestors of the given revs"},
  2146 	  "return the heads of the common ancestors of the given revs"},
  2042 	{"clearcaches", (PyCFunction)index_clearcaches, METH_NOARGS,
  2147 	{"clearcaches", (PyCFunction)index_clearcaches, METH_NOARGS,
  2043 	 "clear the index caches"},
  2148 	 "clear the index caches"},
  2044 	{"get", (PyCFunction)index_m_get, METH_VARARGS,
  2149 	{"get", (PyCFunction)index_m_get, METH_VARARGS,
  2045 	 "get an index entry"},
  2150 	 "get an index entry"},
       
  2151 	{"computephases", (PyCFunction)compute_phases, METH_VARARGS,
       
  2152 		"compute phases"},
  2046 	{"headrevs", (PyCFunction)index_headrevs, METH_VARARGS,
  2153 	{"headrevs", (PyCFunction)index_headrevs, METH_VARARGS,
  2047 	 "get head revisions"}, /* Can do filtering since 3.2 */
  2154 	 "get head revisions"}, /* Can do filtering since 3.2 */
  2048 	{"headrevsfiltered", (PyCFunction)index_headrevs, METH_VARARGS,
  2155 	{"headrevsfiltered", (PyCFunction)index_headrevs, METH_VARARGS,
  2049 	 "get filtered head revisions"}, /* Can always do filtering */
  2156 	 "get filtered head revisions"}, /* Can always do filtering */
  2050 	{"insert", (PyCFunction)index_insert, METH_VARARGS,
  2157 	{"insert", (PyCFunction)index_insert, METH_VARARGS,