Show More
@@ -171,8 +171,13 b' class changelog(revlog.revlog):' | |||
|
171 | 171 | |
|
172 | 172 | def headrevs(self): |
|
173 | 173 | if self.filteredrevs: |
|
174 | # XXX we should fix and use the C version | |
|
175 |
return self. |
|
|
174 | try: | |
|
175 | return self.index.headrevs(self.filteredrevs) | |
|
176 | # AttributeError covers non-c-extension environments. | |
|
177 | # TypeError allows us work with old c extensions. | |
|
178 | except (AttributeError, TypeError): | |
|
179 | return self._headrevs() | |
|
180 | ||
|
176 | 181 | return super(changelog, self).headrevs() |
|
177 | 182 | |
|
178 | 183 | def strip(self, *args, **kwargs): |
@@ -508,6 +508,7 b' typedef struct {' | |||
|
508 | 508 | Py_ssize_t length; /* current number of elements */ |
|
509 | 509 | PyObject *added; /* populated on demand */ |
|
510 | 510 | PyObject *headrevs; /* cache, invalidated on changes */ |
|
511 | PyObject *filteredrevs;/* filtered revs set */ | |
|
511 | 512 | nodetree *nt; /* base-16 trie */ |
|
512 | 513 | int ntlength; /* # nodes in use */ |
|
513 | 514 | int ntcapacity; /* # nodes allocated */ |
@@ -823,15 +824,60 b' static PyObject *list_copy(PyObject *lis' | |||
|
823 | 824 | return newlist; |
|
824 | 825 | } |
|
825 | 826 | |
|
826 | static PyObject *index_headrevs(indexObject *self) | |
|
827 | static int check_filter(PyObject *filter, Py_ssize_t arg) { | |
|
828 | if (filter) { | |
|
829 | PyObject *arglist, *result; | |
|
830 | int isfiltered; | |
|
831 | ||
|
832 | arglist = Py_BuildValue("(n)", arg); | |
|
833 | if (!arglist) { | |
|
834 | return -1; | |
|
835 | } | |
|
836 | ||
|
837 | result = PyEval_CallObject(filter, arglist); | |
|
838 | Py_DECREF(arglist); | |
|
839 | if (!result) { | |
|
840 | return -1; | |
|
841 | } | |
|
842 | ||
|
843 | /* PyObject_IsTrue returns 1 if true, 0 if false, -1 if error, | |
|
844 | * same as this function, so we can just return it directly.*/ | |
|
845 | isfiltered = PyObject_IsTrue(result); | |
|
846 | Py_DECREF(result); | |
|
847 | return isfiltered; | |
|
848 | } else { | |
|
849 | return 0; | |
|
850 | } | |
|
851 | } | |
|
852 | ||
|
853 | static PyObject *index_headrevs(indexObject *self, PyObject *args) | |
|
827 | 854 | { |
|
828 | 855 | Py_ssize_t i, len, addlen; |
|
829 | 856 | char *nothead = NULL; |
|
830 | 857 | PyObject *heads; |
|
858 | PyObject *filter = NULL; | |
|
859 | PyObject *filteredrevs = Py_None; | |
|
831 | 860 | |
|
832 | if (self->headrevs) | |
|
861 | if (!PyArg_ParseTuple(args, "|O", &filteredrevs)) { | |
|
862 | return NULL; | |
|
863 | } | |
|
864 | ||
|
865 | if (self->headrevs && filteredrevs == self->filteredrevs) | |
|
833 | 866 | return list_copy(self->headrevs); |
|
834 | 867 | |
|
868 | Py_DECREF(self->filteredrevs); | |
|
869 | self->filteredrevs = filteredrevs; | |
|
870 | Py_INCREF(filteredrevs); | |
|
871 | ||
|
872 | if (filteredrevs != Py_None) { | |
|
873 | filter = PyObject_GetAttrString(filteredrevs, "__contains__"); | |
|
874 | if (!filter) { | |
|
875 | PyErr_SetString(PyExc_TypeError, | |
|
876 | "filteredrevs has no attribute __contains__"); | |
|
877 | goto bail; | |
|
878 | } | |
|
879 | } | |
|
880 | ||
|
835 | 881 | len = index_length(self) - 1; |
|
836 | 882 | heads = PyList_New(0); |
|
837 | 883 | if (heads == NULL) |
@@ -850,9 +896,25 b' static PyObject *index_headrevs(indexObj' | |||
|
850 | 896 | goto bail; |
|
851 | 897 | |
|
852 | 898 | for (i = 0; i < self->raw_length; i++) { |
|
853 |
const char *data |
|
|
854 | int parent_1 = getbe32(data + 24); | |
|
855 | int parent_2 = getbe32(data + 28); | |
|
899 | const char *data; | |
|
900 | int parent_1, parent_2, isfiltered; | |
|
901 | ||
|
902 | isfiltered = check_filter(filter, i); | |
|
903 | if (isfiltered == -1) { | |
|
904 | PyErr_SetString(PyExc_TypeError, | |
|
905 | "unable to check filter"); | |
|
906 | goto bail; | |
|
907 | } | |
|
908 | ||
|
909 | if (isfiltered) { | |
|
910 | nothead[i] = 1; | |
|
911 | continue; | |
|
912 | } | |
|
913 | ||
|
914 | data = index_deref(self, i); | |
|
915 | parent_1 = getbe32(data + 24); | |
|
916 | parent_2 = getbe32(data + 28); | |
|
917 | ||
|
856 | 918 | if (parent_1 >= 0) |
|
857 | 919 | nothead[parent_1] = 1; |
|
858 | 920 | if (parent_2 >= 0) |
@@ -866,12 +928,26 b' static PyObject *index_headrevs(indexObj' | |||
|
866 | 928 | PyObject *p1 = PyTuple_GET_ITEM(rev, 5); |
|
867 | 929 | PyObject *p2 = PyTuple_GET_ITEM(rev, 6); |
|
868 | 930 | long parent_1, parent_2; |
|
931 | int isfiltered; | |
|
869 | 932 | |
|
870 | 933 | if (!PyInt_Check(p1) || !PyInt_Check(p2)) { |
|
871 | 934 | PyErr_SetString(PyExc_TypeError, |
|
872 | 935 | "revlog parents are invalid"); |
|
873 | 936 | goto bail; |
|
874 | 937 | } |
|
938 | ||
|
939 | isfiltered = check_filter(filter, i); | |
|
940 | if (isfiltered == -1) { | |
|
941 | PyErr_SetString(PyExc_TypeError, | |
|
942 | "unable to check filter"); | |
|
943 | goto bail; | |
|
944 | } | |
|
945 | ||
|
946 | if (isfiltered) { | |
|
947 | nothead[i] = 1; | |
|
948 | continue; | |
|
949 | } | |
|
950 | ||
|
875 | 951 | parent_1 = PyInt_AS_LONG(p1); |
|
876 | 952 | parent_2 = PyInt_AS_LONG(p2); |
|
877 | 953 | if (parent_1 >= 0) |
@@ -894,9 +970,11 b' static PyObject *index_headrevs(indexObj' | |||
|
894 | 970 | |
|
895 | 971 | done: |
|
896 | 972 | self->headrevs = heads; |
|
973 | Py_XDECREF(filter); | |
|
897 | 974 | free(nothead); |
|
898 | 975 | return list_copy(self->headrevs); |
|
899 | 976 | bail: |
|
977 | Py_XDECREF(filter); | |
|
900 | 978 | Py_XDECREF(heads); |
|
901 | 979 | free(nothead); |
|
902 | 980 | return NULL; |
@@ -1896,6 +1974,8 b' static int index_init(indexObject *self,' | |||
|
1896 | 1974 | self->cache = NULL; |
|
1897 | 1975 | self->data = NULL; |
|
1898 | 1976 | self->headrevs = NULL; |
|
1977 | self->filteredrevs = Py_None; | |
|
1978 | Py_INCREF(Py_None); | |
|
1899 | 1979 | self->nt = NULL; |
|
1900 | 1980 | self->offsets = NULL; |
|
1901 | 1981 | |
@@ -1945,6 +2025,7 b' static PyObject *index_nodemap(indexObje' | |||
|
1945 | 2025 | static void index_dealloc(indexObject *self) |
|
1946 | 2026 | { |
|
1947 | 2027 | _index_clearcaches(self); |
|
2028 | Py_XDECREF(self->filteredrevs); | |
|
1948 | 2029 | Py_XDECREF(self->data); |
|
1949 | 2030 | Py_XDECREF(self->added); |
|
1950 | 2031 | PyObject_Del(self); |
@@ -1977,7 +2058,7 b' static PyMethodDef index_methods[] = {' | |||
|
1977 | 2058 | "clear the index caches"}, |
|
1978 | 2059 | {"get", (PyCFunction)index_m_get, METH_VARARGS, |
|
1979 | 2060 | "get an index entry"}, |
|
1980 |
{"headrevs", (PyCFunction)index_headrevs, METH_ |
|
|
2061 | {"headrevs", (PyCFunction)index_headrevs, METH_VARARGS, | |
|
1981 | 2062 | "get head revisions"}, |
|
1982 | 2063 | {"insert", (PyCFunction)index_insert, METH_VARARGS, |
|
1983 | 2064 | "insert an index entry"}, |
General Comments 0
You need to be logged in to leave comments.
Login now