##// END OF EJS Templates
revlog: C implementation of delta chain resolution...
Gregory Szorc -
r33168:6d678ab1 default
parent child Browse files
Show More
@@ -816,6 +816,139 b' bail:'
816 return NULL;
816 return NULL;
817 }
817 }
818
818
819 static inline int index_baserev(indexObject *self, int rev)
820 {
821 const char *data;
822
823 if (rev >= self->length - 1) {
824 PyObject *tuple = PyList_GET_ITEM(self->added,
825 rev - self->length + 1);
826 return (int)PyInt_AS_LONG(PyTuple_GET_ITEM(tuple, 3));
827 }
828 else {
829 data = index_deref(self, rev);
830 if (data == NULL) {
831 return -2;
832 }
833
834 return getbe32(data + 16);
835 }
836 }
837
838 static PyObject *index_deltachain(indexObject *self, PyObject *args)
839 {
840 int rev, generaldelta;
841 PyObject *stoparg;
842 int stoprev, iterrev, baserev = -1;
843 int stopped;
844 PyObject *chain = NULL, *value = NULL, *result = NULL;
845 const Py_ssize_t length = index_length(self);
846
847 if (!PyArg_ParseTuple(args, "iOi", &rev, &stoparg, &generaldelta)) {
848 return NULL;
849 }
850
851 if (PyInt_Check(stoparg)) {
852 stoprev = (int)PyInt_AsLong(stoparg);
853 if (stoprev == -1 && PyErr_Occurred()) {
854 return NULL;
855 }
856 }
857 else if (stoparg == Py_None) {
858 stoprev = -2;
859 }
860 else {
861 PyErr_SetString(PyExc_ValueError,
862 "stoprev must be integer or None");
863 return NULL;
864 }
865
866 if (rev < 0 || rev >= length - 1) {
867 PyErr_SetString(PyExc_ValueError, "revlog index out of range");
868 return NULL;
869 }
870
871 chain = PyList_New(0);
872 if (chain == NULL) {
873 return NULL;
874 }
875
876 baserev = index_baserev(self, rev);
877
878 /* This should never happen. */
879 if (baserev == -2) {
880 PyErr_SetString(PyExc_IndexError, "unable to resolve data");
881 goto bail;
882 }
883
884 iterrev = rev;
885
886 while (iterrev != baserev && iterrev != stoprev) {
887 value = PyInt_FromLong(iterrev);
888 if (value == NULL) {
889 goto bail;
890 }
891 if (PyList_Append(chain, value)) {
892 Py_DECREF(value);
893 goto bail;
894 }
895 Py_DECREF(value);
896
897 if (generaldelta) {
898 iterrev = baserev;
899 }
900 else {
901 iterrev--;
902 }
903
904 if (iterrev < 0) {
905 break;
906 }
907
908 if (iterrev >= length - 1) {
909 PyErr_SetString(PyExc_IndexError, "revision outside index");
910 return NULL;
911 }
912
913 baserev = index_baserev(self, iterrev);
914
915 /* This should never happen. */
916 if (baserev == -2) {
917 PyErr_SetString(PyExc_IndexError, "unable to resolve data");
918 goto bail;
919 }
920 }
921
922 if (iterrev == stoprev) {
923 stopped = 1;
924 }
925 else {
926 value = PyInt_FromLong(iterrev);
927 if (value == NULL) {
928 goto bail;
929 }
930 if (PyList_Append(chain, value)) {
931 Py_DECREF(value);
932 goto bail;
933 }
934 Py_DECREF(value);
935
936 stopped = 0;
937 }
938
939 if (PyList_Reverse(chain)) {
940 goto bail;
941 }
942
943 result = Py_BuildValue("OO", chain, stopped ? Py_True : Py_False);
944 Py_DECREF(chain);
945 return result;
946
947 bail:
948 Py_DECREF(chain);
949 return NULL;
950 }
951
819 static inline int nt_level(const char *node, Py_ssize_t level)
952 static inline int nt_level(const char *node, Py_ssize_t level)
820 {
953 {
821 int v = node[level>>1];
954 int v = node[level>>1];
@@ -1828,6 +1961,8 b' static PyMethodDef index_methods[] = {'
1828 "get head revisions"}, /* Can do filtering since 3.2 */
1961 "get head revisions"}, /* Can do filtering since 3.2 */
1829 {"headrevsfiltered", (PyCFunction)index_headrevs, METH_VARARGS,
1962 {"headrevsfiltered", (PyCFunction)index_headrevs, METH_VARARGS,
1830 "get filtered head revisions"}, /* Can always do filtering */
1963 "get filtered head revisions"}, /* Can always do filtering */
1964 {"deltachain", (PyCFunction)index_deltachain, METH_VARARGS,
1965 "determine revisions with deltas to reconstruct fulltext"},
1831 {"insert", (PyCFunction)index_insert, METH_VARARGS,
1966 {"insert", (PyCFunction)index_insert, METH_VARARGS,
1832 "insert an index entry"},
1967 "insert an index entry"},
1833 {"partialmatch", (PyCFunction)index_partialmatch, METH_VARARGS,
1968 {"partialmatch", (PyCFunction)index_partialmatch, METH_VARARGS,
@@ -570,6 +570,12 b' class revlog(object):'
570 revs in ascending order and ``stopped`` is a bool indicating whether
570 revs in ascending order and ``stopped`` is a bool indicating whether
571 ``stoprev`` was hit.
571 ``stoprev`` was hit.
572 """
572 """
573 # Try C implementation.
574 try:
575 return self.index.deltachain(rev, stoprev, self._generaldelta)
576 except AttributeError:
577 pass
578
573 chain = []
579 chain = []
574
580
575 # Alias to prevent attribute lookup in tight loop.
581 # Alias to prevent attribute lookup in tight loop.
General Comments 0
You need to be logged in to leave comments. Login now