Mercurial > public > mercurial-scm > hg-stable
diff mercurial/cext/revlog.c @ 41111: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 |
line wrap: on
line diff
--- a/mercurial/cext/revlog.c Sun Dec 23 12:39:20 2018 +0900 +++ b/mercurial/cext/revlog.c Thu Dec 20 10:15:20 2018 +0100 @@ -1050,6 +1050,67 @@ return PyBool_FromLong((long)issnap); } +static PyObject *index_findsnapshots(indexObject *self, PyObject *args) +{ + Py_ssize_t start_rev; + PyObject *cache; + Py_ssize_t base; + Py_ssize_t rev; + PyObject *key = NULL; + PyObject *value = NULL; + const Py_ssize_t length = index_length(self); + if (!PyArg_ParseTuple(args, "O!n", &PyDict_Type, &cache, &start_rev)) { + return NULL; + } + for (rev = start_rev; rev < length; rev++) { + int issnap; + PyObject *allvalues = NULL; + issnap = index_issnapshotrev(self, rev); + if (issnap < 0) { + goto bail; + } + if (issnap == 0) { + continue; + } + base = (Py_ssize_t)index_baserev(self, rev); + if (base == rev) { + base = -1; + } + if (base == -2) { + assert(PyErr_Occurred()); + goto bail; + } + key = PyInt_FromSsize_t(base); + allvalues = PyDict_GetItem(cache, key); + if (allvalues == NULL && PyErr_Occurred()) { + goto bail; + } + if (allvalues == NULL) { + int r; + allvalues = PyList_New(0); + if (!allvalues) { + goto bail; + } + r = PyDict_SetItem(cache, key, allvalues); + Py_DECREF(allvalues); + if (r < 0) { + goto bail; + } + } + value = PyInt_FromSsize_t(rev); + if (PyList_Append(allvalues, value)) { + goto bail; + } + Py_CLEAR(key); + Py_CLEAR(value); + } + Py_RETURN_NONE; +bail: + Py_XDECREF(key); + Py_XDECREF(value); + return NULL; +} + static PyObject *index_deltachain(indexObject *self, PyObject *args) { int rev, generaldelta; @@ -2664,6 +2725,8 @@ "get filtered head revisions"}, /* Can always do filtering */ {"issnapshot", (PyCFunction)index_issnapshot, METH_O, "True if the object is a snapshot"}, + {"findsnapshots", (PyCFunction)index_findsnapshots, METH_VARARGS, + "Gather snapshot data in a cache dict"}, {"deltachain", (PyCFunction)index_deltachain, METH_VARARGS, "determine revisions with deltas to reconstruct fulltext"}, {"slicechunktodensity", (PyCFunction)index_slicechunktodensity,