comparison mercurial/cext/revlog.c @ 41108:38e88450138c

delta: have a native implementation of _findsnapshot The function might traverse a lot of revision, a native implementation get significantly faster. example affected manifest write before: 0.114989 after: 0.067141 (-42%)
author Boris Feld <boris.feld@octobus.net>
date Thu, 20 Dec 2018 10:15:20 +0100
parents a28833d79aca
children 074c72a38423
comparison
equal deleted inserted replaced
41107:3e2c02836420 41108:38e88450138c
1046 issnap = index_issnapshotrev(self, (Py_ssize_t)rev); 1046 issnap = index_issnapshotrev(self, (Py_ssize_t)rev);
1047 if (issnap < 0) { 1047 if (issnap < 0) {
1048 return NULL; 1048 return NULL;
1049 }; 1049 };
1050 return PyBool_FromLong((long)issnap); 1050 return PyBool_FromLong((long)issnap);
1051 }
1052
1053 static PyObject *index_findsnapshots(indexObject *self, PyObject *args)
1054 {
1055 Py_ssize_t start_rev;
1056 PyObject *cache;
1057 Py_ssize_t base;
1058 Py_ssize_t rev;
1059 PyObject *key = NULL;
1060 PyObject *value = NULL;
1061 const Py_ssize_t length = index_length(self);
1062 if (!PyArg_ParseTuple(args, "O!n", &PyDict_Type, &cache, &start_rev)) {
1063 return NULL;
1064 }
1065 for (rev = start_rev; rev < length; rev++) {
1066 int issnap;
1067 PyObject *allvalues = NULL;
1068 issnap = index_issnapshotrev(self, rev);
1069 if (issnap < 0) {
1070 goto bail;
1071 }
1072 if (issnap == 0) {
1073 continue;
1074 }
1075 base = (Py_ssize_t)index_baserev(self, rev);
1076 if (base == rev) {
1077 base = -1;
1078 }
1079 if (base == -2) {
1080 assert(PyErr_Occurred());
1081 goto bail;
1082 }
1083 key = PyInt_FromSsize_t(base);
1084 allvalues = PyDict_GetItem(cache, key);
1085 if (allvalues == NULL && PyErr_Occurred()) {
1086 goto bail;
1087 }
1088 if (allvalues == NULL) {
1089 int r;
1090 allvalues = PyList_New(0);
1091 if (!allvalues) {
1092 goto bail;
1093 }
1094 r = PyDict_SetItem(cache, key, allvalues);
1095 Py_DECREF(allvalues);
1096 if (r < 0) {
1097 goto bail;
1098 }
1099 }
1100 value = PyInt_FromSsize_t(rev);
1101 if (PyList_Append(allvalues, value)) {
1102 goto bail;
1103 }
1104 Py_CLEAR(key);
1105 Py_CLEAR(value);
1106 }
1107 Py_RETURN_NONE;
1108 bail:
1109 Py_XDECREF(key);
1110 Py_XDECREF(value);
1111 return NULL;
1051 } 1112 }
1052 1113
1053 static PyObject *index_deltachain(indexObject *self, PyObject *args) 1114 static PyObject *index_deltachain(indexObject *self, PyObject *args)
1054 { 1115 {
1055 int rev, generaldelta; 1116 int rev, generaldelta;
2662 "get head revisions"}, /* Can do filtering since 3.2 */ 2723 "get head revisions"}, /* Can do filtering since 3.2 */
2663 {"headrevsfiltered", (PyCFunction)index_headrevs, METH_VARARGS, 2724 {"headrevsfiltered", (PyCFunction)index_headrevs, METH_VARARGS,
2664 "get filtered head revisions"}, /* Can always do filtering */ 2725 "get filtered head revisions"}, /* Can always do filtering */
2665 {"issnapshot", (PyCFunction)index_issnapshot, METH_O, 2726 {"issnapshot", (PyCFunction)index_issnapshot, METH_O,
2666 "True if the object is a snapshot"}, 2727 "True if the object is a snapshot"},
2728 {"findsnapshots", (PyCFunction)index_findsnapshots, METH_VARARGS,
2729 "Gather snapshot data in a cache dict"},
2667 {"deltachain", (PyCFunction)index_deltachain, METH_VARARGS, 2730 {"deltachain", (PyCFunction)index_deltachain, METH_VARARGS,
2668 "determine revisions with deltas to reconstruct fulltext"}, 2731 "determine revisions with deltas to reconstruct fulltext"},
2669 {"slicechunktodensity", (PyCFunction)index_slicechunktodensity, 2732 {"slicechunktodensity", (PyCFunction)index_slicechunktodensity,
2670 METH_VARARGS, "determine revisions with deltas to reconstruct fulltext"}, 2733 METH_VARARGS, "determine revisions with deltas to reconstruct fulltext"},
2671 {"append", (PyCFunction)index_append, METH_O, "append an index entry"}, 2734 {"append", (PyCFunction)index_append, METH_O, "append an index entry"},