##// END OF EJS Templates
spanset: directly use __contains__ instead of a lambda...
spanset: directly use __contains__ instead of a lambda Spanset are massively used in revset. First because the initial subset itself is a repo wide spanset. We speed up the __and__ operation by getting rid of a gratuitous lambda call. A more long terms solution would be to: 1. speed up operation between spansets, 2. have a special smartset for `all` revisions. In the mean time, this is a very simple fix that buyback some of the performance regression. Below is performance benchmark for trival `and` operation between two spansets. (Run on an unspecified fairly large repository.) revset tip:0 2.9.2) wall 0.282543 comb 0.280000 user 0.260000 sys 0.020000 (best of 35) before) wall 0.819181 comb 0.820000 user 0.820000 sys 0.000000 (best of 12) after) wall 0.645358 comb 0.650000 user 0.650000 sys 0.000000 (best of 16) Proof of concept implementation of an `all` smartset brings this to 0.10 but it's too invasive for stable.

File last commit:

r16695:0a0933d3 default
r21207:b9defeeb stable
Show More
diffhelpers.c
197 lines | 4.7 KiB | text/x-c | CLexer
Bryan O'Sullivan
Add Chris Mason's mpatch library....
r4897 /*
* diffhelpers.c - helper routines for mpatch
*
* Copyright 2007 Chris Mason <chris.mason@oracle.com>
*
* This software may be used and distributed according to the terms
* of the GNU General Public License v2, incorporated herein by reference.
*/
#include <Python.h>
#include <stdlib.h>
#include <string.h>
Renato Cunha
diffhelpers.c: Added support for py3k....
r11363 #include "util.h"
Bryan O'Sullivan
Add Chris Mason's mpatch library....
r4897 static char diffhelpers_doc[] = "Efficient diff parsing";
static PyObject *diffhelpers_Error;
/* fixup the last lines of a and b when the patch has no newline at eof */
static void _fix_newline(PyObject *hunk, PyObject *a, PyObject *b)
{
Adrian Buehlmann
diffhelpers: use Py_ssize_t in _fix_newline()...
r16693 Py_ssize_t hunksz = PyList_Size(hunk);
Bryan O'Sullivan
Add Chris Mason's mpatch library....
r4897 PyObject *s = PyList_GET_ITEM(hunk, hunksz-1);
Renato Cunha
diffhelpers.c: Added support for py3k....
r11363 char *l = PyBytes_AsString(s);
Adrian Buehlmann
diffhelpers: use Py_ssize_t in _fix_newline()...
r16693 Py_ssize_t alen = PyList_Size(a);
Py_ssize_t blen = PyList_Size(b);
Bryan O'Sullivan
Add Chris Mason's mpatch library....
r4897 char c = l[0];
Patrick Mezard
diffhelpers: fix variable declaration for MSVC (not C99)
r10146 PyObject *hline;
Adrian Buehlmann
diffhelpers: use Py_ssize_t in _fix_newline()...
r16693 Py_ssize_t sz = PyBytes_GET_SIZE(s);
Bryan O'Sullivan
Add Chris Mason's mpatch library....
r4897
Patrick Mezard
diffhelpers: fix variable declaration for MSVC (not C99)
r10146 if (sz > 1 && l[sz-2] == '\r')
/* tolerate CRLF in last line */
sz -= 1;
Renato Cunha
diffhelpers.c: Added support for py3k....
r11363
hline = PyBytes_FromStringAndSize(l, sz-1);
Patrick Mezard
diffhelpers: fix variable declaration for MSVC (not C99)
r10146
Bryan O'Sullivan
Add Chris Mason's mpatch library....
r4897 if (c == ' ' || c == '+') {
Renato Cunha
diffhelpers.c: Added support for py3k....
r11363 PyObject *rline = PyBytes_FromStringAndSize(l + 1, sz - 2);
Bryan O'Sullivan
Add Chris Mason's mpatch library....
r4897 PyList_SetItem(b, blen-1, rline);
}
if (c == ' ' || c == '-') {
Py_INCREF(hline);
PyList_SetItem(a, alen-1, hline);
}
PyList_SetItem(hunk, hunksz-1, hline);
}
/* python callable form of _fix_newline */
static PyObject *
fix_newline(PyObject *self, PyObject *args)
{
PyObject *hunk, *a, *b;
if (!PyArg_ParseTuple(args, "OOO", &hunk, &a, &b))
return NULL;
_fix_newline(hunk, a, b);
return Py_BuildValue("l", 0);
}
Adrian Buehlmann
diffhelpers: use Py_ssize_t in addlines()...
r16694 #if (PY_VERSION_HEX < 0x02050000)
static const char *addlines_format = "OOiiOO";
#else
static const char *addlines_format = "OOnnOO";
#endif
Bryan O'Sullivan
Add Chris Mason's mpatch library....
r4897 /*
* read lines from fp into the hunk. The hunk is parsed into two arrays
* a and b. a gets the old state of the text, b gets the new state
* The control char from the hunk is saved when inserting into a, but not b
* (for performance while deleting files)
*/
static PyObject *
addlines(PyObject *self, PyObject *args)
{
PyObject *fp, *hunk, *a, *b, *x;
Adrian Buehlmann
diffhelpers: use Py_ssize_t in addlines()...
r16694 Py_ssize_t i;
Py_ssize_t lena, lenb;
Py_ssize_t num;
Py_ssize_t todoa, todob;
Bryan O'Sullivan
Add Chris Mason's mpatch library....
r4897 char *s, c;
PyObject *l;
Adrian Buehlmann
diffhelpers: use Py_ssize_t in addlines()...
r16694 if (!PyArg_ParseTuple(args, addlines_format,
&fp, &hunk, &lena, &lenb, &a, &b))
Bryan O'Sullivan
Add Chris Mason's mpatch library....
r4897 return NULL;
Matt Mackall
many, many trivial check-code fixups
r10282 while (1) {
Bryan O'Sullivan
Add Chris Mason's mpatch library....
r4897 todoa = lena - PyList_Size(a);
todob = lenb - PyList_Size(b);
num = todoa > todob ? todoa : todob;
if (num == 0)
break;
Matt Mackall
many, many trivial check-code fixups
r10282 for (i = 0; i < num; i++) {
Bryan O'Sullivan
Add Chris Mason's mpatch library....
r4897 x = PyFile_GetLine(fp, 0);
Renato Cunha
diffhelpers.c: Added support for py3k....
r11363 s = PyBytes_AsString(x);
Bryan O'Sullivan
Add Chris Mason's mpatch library....
r4897 c = *s;
if (strcmp(s, "\\ No newline at end of file\n") == 0) {
_fix_newline(hunk, a, b);
continue;
}
Hollis Blanchard
Handle patches with misformatted empty lines...
r5483 if (c == '\n') {
/* Some patches may be missing the control char
* on empty lines. Supply a leading space. */
Py_DECREF(x);
Renato Cunha
diffhelpers.c: Added support for py3k....
r11363 x = PyBytes_FromString(" \n");
Hollis Blanchard
Handle patches with misformatted empty lines...
r5483 }
Bryan O'Sullivan
Add Chris Mason's mpatch library....
r4897 PyList_Append(hunk, x);
if (c == '+') {
Renato Cunha
diffhelpers.c: Added support for py3k....
r11363 l = PyBytes_FromString(s + 1);
Bryan O'Sullivan
Add Chris Mason's mpatch library....
r4897 PyList_Append(b, l);
Py_DECREF(l);
} else if (c == '-') {
PyList_Append(a, x);
} else {
Renato Cunha
diffhelpers.c: Added support for py3k....
r11363 l = PyBytes_FromString(s + 1);
Bryan O'Sullivan
Add Chris Mason's mpatch library....
r4897 PyList_Append(b, l);
Py_DECREF(l);
PyList_Append(a, x);
}
Py_DECREF(x);
}
}
return Py_BuildValue("l", 0);
}
/*
* compare the lines in a with the lines in b. a is assumed to have
* a control char at the start of each line, this char is ignored in the
* compare
*/
static PyObject *
testhunk(PyObject *self, PyObject *args)
{
PyObject *a, *b;
long bstart;
Adrian Buehlmann
diffhelpers: use Py_ssize_t in testhunk()...
r16695 Py_ssize_t alen, blen;
Py_ssize_t i;
Bryan O'Sullivan
Add Chris Mason's mpatch library....
r4897 char *sa, *sb;
if (!PyArg_ParseTuple(args, "OOl", &a, &b, &bstart))
return NULL;
alen = PyList_Size(a);
blen = PyList_Size(b);
Matt Mackall
diffhelpers: harden testhunk
r16651 if (alen > blen - bstart || bstart < 0) {
Bryan O'Sullivan
Add Chris Mason's mpatch library....
r4897 return Py_BuildValue("l", -1);
}
Matt Mackall
many, many trivial check-code fixups
r10282 for (i = 0; i < alen; i++) {
Renato Cunha
diffhelpers.c: Added support for py3k....
r11363 sa = PyBytes_AsString(PyList_GET_ITEM(a, i));
sb = PyBytes_AsString(PyList_GET_ITEM(b, i + bstart));
Matt Mackall
many, many trivial check-code fixups
r10282 if (strcmp(sa + 1, sb) != 0)
Bryan O'Sullivan
Add Chris Mason's mpatch library....
r4897 return Py_BuildValue("l", -1);
}
return Py_BuildValue("l", 0);
}
static PyMethodDef methods[] = {
{"addlines", addlines, METH_VARARGS, "add lines to a hunk\n"},
{"fix_newline", fix_newline, METH_VARARGS, "fixup newline counters\n"},
{"testhunk", testhunk, METH_VARARGS, "test lines in a hunk\n"},
{NULL, NULL}
};
Renato Cunha
diffhelpers.c: Added support for py3k....
r11363 #ifdef IS_PY3K
static struct PyModuleDef diffhelpers_module = {
PyModuleDef_HEAD_INIT,
"diffhelpers",
diffhelpers_doc,
-1,
methods
};
PyMODINIT_FUNC PyInit_diffhelpers(void)
{
PyObject *m;
m = PyModule_Create(&diffhelpers_module);
if (m == NULL)
return NULL;
diffhelpers_Error = PyErr_NewException("diffhelpers.diffhelpersError",
NULL, NULL);
Py_INCREF(diffhelpers_Error);
PyModule_AddObject(m, "diffhelpersError", diffhelpers_Error);
return m;
}
#else
Bryan O'Sullivan
Add Chris Mason's mpatch library....
r4897 PyMODINIT_FUNC
initdiffhelpers(void)
{
Py_InitModule3("diffhelpers", methods, diffhelpers_doc);
diffhelpers_Error = PyErr_NewException("diffhelpers.diffhelpersError",
NULL, NULL);
}
Renato Cunha
diffhelpers.c: Added support for py3k....
r11363 #endif
Bryan O'Sullivan
Add Chris Mason's mpatch library....
r4897