Show More
@@ -171,8 +171,13 b' class changelog(revlog.revlog):' | |||||
171 |
|
171 | |||
172 | def headrevs(self): |
|
172 | def headrevs(self): | |
173 | if self.filteredrevs: |
|
173 | if self.filteredrevs: | |
174 | # XXX we should fix and use the C version |
|
174 | try: | |
175 |
return self. |
|
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 | return super(changelog, self).headrevs() |
|
181 | return super(changelog, self).headrevs() | |
177 |
|
182 | |||
178 | def strip(self, *args, **kwargs): |
|
183 | def strip(self, *args, **kwargs): |
@@ -508,6 +508,7 b' typedef struct {' | |||||
508 | Py_ssize_t length; /* current number of elements */ |
|
508 | Py_ssize_t length; /* current number of elements */ | |
509 | PyObject *added; /* populated on demand */ |
|
509 | PyObject *added; /* populated on demand */ | |
510 | PyObject *headrevs; /* cache, invalidated on changes */ |
|
510 | PyObject *headrevs; /* cache, invalidated on changes */ | |
|
511 | PyObject *filteredrevs;/* filtered revs set */ | |||
511 | nodetree *nt; /* base-16 trie */ |
|
512 | nodetree *nt; /* base-16 trie */ | |
512 | int ntlength; /* # nodes in use */ |
|
513 | int ntlength; /* # nodes in use */ | |
513 | int ntcapacity; /* # nodes allocated */ |
|
514 | int ntcapacity; /* # nodes allocated */ | |
@@ -823,15 +824,60 b' static PyObject *list_copy(PyObject *lis' | |||||
823 | return newlist; |
|
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 | Py_ssize_t i, len, addlen; |
|
855 | Py_ssize_t i, len, addlen; | |
829 | char *nothead = NULL; |
|
856 | char *nothead = NULL; | |
830 | PyObject *heads; |
|
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 | return list_copy(self->headrevs); |
|
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 | len = index_length(self) - 1; |
|
881 | len = index_length(self) - 1; | |
836 | heads = PyList_New(0); |
|
882 | heads = PyList_New(0); | |
837 | if (heads == NULL) |
|
883 | if (heads == NULL) | |
@@ -850,9 +896,25 b' static PyObject *index_headrevs(indexObj' | |||||
850 | goto bail; |
|
896 | goto bail; | |
851 |
|
897 | |||
852 | for (i = 0; i < self->raw_length; i++) { |
|
898 | for (i = 0; i < self->raw_length; i++) { | |
853 |
const char *data |
|
899 | const char *data; | |
854 | int parent_1 = getbe32(data + 24); |
|
900 | int parent_1, parent_2, isfiltered; | |
855 | int parent_2 = getbe32(data + 28); |
|
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 | if (parent_1 >= 0) |
|
918 | if (parent_1 >= 0) | |
857 | nothead[parent_1] = 1; |
|
919 | nothead[parent_1] = 1; | |
858 | if (parent_2 >= 0) |
|
920 | if (parent_2 >= 0) | |
@@ -866,12 +928,26 b' static PyObject *index_headrevs(indexObj' | |||||
866 | PyObject *p1 = PyTuple_GET_ITEM(rev, 5); |
|
928 | PyObject *p1 = PyTuple_GET_ITEM(rev, 5); | |
867 | PyObject *p2 = PyTuple_GET_ITEM(rev, 6); |
|
929 | PyObject *p2 = PyTuple_GET_ITEM(rev, 6); | |
868 | long parent_1, parent_2; |
|
930 | long parent_1, parent_2; | |
|
931 | int isfiltered; | |||
869 |
|
932 | |||
870 | if (!PyInt_Check(p1) || !PyInt_Check(p2)) { |
|
933 | if (!PyInt_Check(p1) || !PyInt_Check(p2)) { | |
871 | PyErr_SetString(PyExc_TypeError, |
|
934 | PyErr_SetString(PyExc_TypeError, | |
872 | "revlog parents are invalid"); |
|
935 | "revlog parents are invalid"); | |
873 | goto bail; |
|
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 | parent_1 = PyInt_AS_LONG(p1); |
|
951 | parent_1 = PyInt_AS_LONG(p1); | |
876 | parent_2 = PyInt_AS_LONG(p2); |
|
952 | parent_2 = PyInt_AS_LONG(p2); | |
877 | if (parent_1 >= 0) |
|
953 | if (parent_1 >= 0) | |
@@ -894,9 +970,11 b' static PyObject *index_headrevs(indexObj' | |||||
894 |
|
970 | |||
895 | done: |
|
971 | done: | |
896 | self->headrevs = heads; |
|
972 | self->headrevs = heads; | |
|
973 | Py_XDECREF(filter); | |||
897 | free(nothead); |
|
974 | free(nothead); | |
898 | return list_copy(self->headrevs); |
|
975 | return list_copy(self->headrevs); | |
899 | bail: |
|
976 | bail: | |
|
977 | Py_XDECREF(filter); | |||
900 | Py_XDECREF(heads); |
|
978 | Py_XDECREF(heads); | |
901 | free(nothead); |
|
979 | free(nothead); | |
902 | return NULL; |
|
980 | return NULL; | |
@@ -1896,6 +1974,8 b' static int index_init(indexObject *self,' | |||||
1896 | self->cache = NULL; |
|
1974 | self->cache = NULL; | |
1897 | self->data = NULL; |
|
1975 | self->data = NULL; | |
1898 | self->headrevs = NULL; |
|
1976 | self->headrevs = NULL; | |
|
1977 | self->filteredrevs = Py_None; | |||
|
1978 | Py_INCREF(Py_None); | |||
1899 | self->nt = NULL; |
|
1979 | self->nt = NULL; | |
1900 | self->offsets = NULL; |
|
1980 | self->offsets = NULL; | |
1901 |
|
1981 | |||
@@ -1945,6 +2025,7 b' static PyObject *index_nodemap(indexObje' | |||||
1945 | static void index_dealloc(indexObject *self) |
|
2025 | static void index_dealloc(indexObject *self) | |
1946 | { |
|
2026 | { | |
1947 | _index_clearcaches(self); |
|
2027 | _index_clearcaches(self); | |
|
2028 | Py_XDECREF(self->filteredrevs); | |||
1948 | Py_XDECREF(self->data); |
|
2029 | Py_XDECREF(self->data); | |
1949 | Py_XDECREF(self->added); |
|
2030 | Py_XDECREF(self->added); | |
1950 | PyObject_Del(self); |
|
2031 | PyObject_Del(self); | |
@@ -1977,7 +2058,7 b' static PyMethodDef index_methods[] = {' | |||||
1977 | "clear the index caches"}, |
|
2058 | "clear the index caches"}, | |
1978 | {"get", (PyCFunction)index_m_get, METH_VARARGS, |
|
2059 | {"get", (PyCFunction)index_m_get, METH_VARARGS, | |
1979 | "get an index entry"}, |
|
2060 | "get an index entry"}, | |
1980 |
{"headrevs", (PyCFunction)index_headrevs, METH_ |
|
2061 | {"headrevs", (PyCFunction)index_headrevs, METH_VARARGS, | |
1981 | "get head revisions"}, |
|
2062 | "get head revisions"}, | |
1982 | {"insert", (PyCFunction)index_insert, METH_VARARGS, |
|
2063 | {"insert", (PyCFunction)index_insert, METH_VARARGS, | |
1983 | "insert an index entry"}, |
|
2064 | "insert an index entry"}, |
General Comments 0
You need to be logged in to leave comments.
Login now