Mercurial > hg
changeset 27592:7c9eb2927879
dirstate: add a C implementation for nonnormalentries
Before this patch, there was only a python version of nonnormalentries.
On mozilla-central we have a 10x win by putting this function in C:
% python -m timeit -s \
'from mercurial import hg, ui, parsers; \
repo = hg.repository(ui.ui(), "mozilla-central"); \
m = repo.dirstate._map' \
'parsers.nonnormalentries(m)'
100 loops, best of 3: 3.15 msec per loop
The python implementation runs in 31ms, a similar test gives:
10 loops, best of 3: 31.7 msec per loop
On our big repos, the win is still of 10x with the python implementation running
in 350ms and the C implementation running in 30ms.
author | Laurent Charignon <lcharignon@fb.com> |
---|---|
date | Mon, 21 Dec 2015 16:27:16 -0800 |
parents | 127cc7f78475 |
children | bc97b9af4e62 |
files | mercurial/parsers.c |
diffstat | 1 files changed, 40 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/parsers.c Mon Dec 21 16:26:44 2015 -0800 +++ b/mercurial/parsers.c Mon Dec 21 16:27:16 2015 -0800 @@ -547,6 +547,44 @@ } /* + * Build a set of non-normal entries from the dirstate dmap +*/ +static PyObject *nonnormalentries(PyObject *self, PyObject *args) +{ + PyObject *dmap, *nonnset = NULL, *fname, *v; + Py_ssize_t pos; + + if (!PyArg_ParseTuple(args, "O!:nonnormalentries", + &PyDict_Type, &dmap)) + goto bail; + + nonnset = PySet_New(NULL); + if (nonnset == NULL) + goto bail; + + pos = 0; + while (PyDict_Next(dmap, &pos, &fname, &v)) { + dirstateTupleObject *t; + if (!dirstate_tuple_check(v)) { + PyErr_SetString(PyExc_TypeError, + "expected a dirstate tuple"); + goto bail; + } + t = (dirstateTupleObject *)v; + + if (t->state == 'n' && t->mtime != -1) + continue; + if (PySet_Add(nonnset, fname) == -1) + goto bail; + } + + return nonnset; +bail: + Py_XDECREF(nonnset); + return NULL; +} + +/* * Efficiently pack a dirstate object into its on-disk format. */ static PyObject *pack_dirstate(PyObject *self, PyObject *args) @@ -2740,6 +2778,8 @@ static PyMethodDef methods[] = { {"pack_dirstate", pack_dirstate, METH_VARARGS, "pack a dirstate\n"}, + {"nonnormalentries", nonnormalentries, METH_VARARGS, + "create a set containing non-normal entries of given dirstate\n"}, {"parse_manifest", parse_manifest, METH_VARARGS, "parse a manifest\n"}, {"parse_dirstate", parse_dirstate, METH_VARARGS, "parse a dirstate\n"}, {"parse_index2", parse_index2, METH_VARARGS, "parse a revlog index\n"},