Mercurial > hgrepos > Python > libs > ConfigMix
diff configmix/_speedups.c @ 552:39e5d07d8dbc
Provide a C implementation of configmix.config._split_filters.
This is needed as precondition for implementation interpolate_variables in
C also.
Currently the speedup is not measurable but it does not hurt also.
Also provide some unit-tests for _split_filters().
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Sun, 02 Jan 2022 20:40:09 +0100 |
| parents | 79db28e879f8 |
| children | 9d2bd411f5c5 |
line wrap: on
line diff
--- a/configmix/_speedups.c Sun Jan 02 16:05:35 2022 +0100 +++ b/configmix/_speedups.c Sun Jan 02 20:40:09 2022 +0100 @@ -22,6 +22,7 @@ PyObject *DOT; PyObject *QUOTE; PyObject *NS_SEPARATOR; + PyObject *FILTER_SEPARATOR; PyObject *EMPTY_STR; PyObject *QUOTE_MAP; }; @@ -251,7 +252,7 @@ static PyObject * -_fast_unquote(PyObject *self, PyObject *s, Py_ssize_t s_len, struct speedups_state *sstate) +_fast_unquote(PyObject *s, Py_ssize_t s_len, PyObject *self, struct speedups_state *sstate) { Py_ssize_t find; Py_ssize_t parts_len; @@ -397,7 +398,7 @@ PyObject * fast_unquote(PyObject *self, PyObject *s) { - return _fast_unquote(self, s, -1, NULL); + return _fast_unquote(s, -1, self, NULL); } @@ -499,7 +500,7 @@ } for (i=0; i < parts_len; i++) { o = PyList_GetItem(parts, i); /* borrowed */ - u = _fast_unquote(self, o, -1, sstate); + u = _fast_unquote(o, -1, NULL, sstate); if (u == NULL) { goto error; } @@ -518,6 +519,122 @@ static PyObject * +_fast_split_filters(PyObject *varname, PyObject *self, struct speedups_state *sstate) +{ + Py_ssize_t varname_len; + Py_ssize_t sep; + PyObject *res = NULL; + PyObject *filters = NULL; + PyObject *name = NULL; + PyObject *tmp; + + varname_len = PyUnicode_GetLength(varname); + if (varname_len < 0) { + return NULL; + } + if (varname_len == 0) { + sep = -1; + } + else { + sep = PyUnicode_FindChar(varname, '|', 0, varname_len, 1); + if (sep == -2) { + return NULL; + } + } + if (sep == -1) { + res = PyTuple_New(2); + if (res == NULL) { + goto error; + } + Py_INCREF(varname); /* because PyTuple_SetItem steals */ + PyTuple_SetItem(res, 0, varname); /* steals */ + filters = PyList_New(0); + if (filters == NULL) { + goto error; + } + PyTuple_SetItem(res, 1, filters); /* steals */ + return res; + } + name = PyUnicode_Substring(varname, 0, sep); + if (name == NULL) { + goto error; + } + tmp = PyObject_CallMethod(name, "rstrip", NULL); + if (tmp == NULL) { + goto error; + } + Py_DECREF(name); + name = tmp; + + filters = PyUnicode_Substring(varname, sep+1, varname_len); + if (filters == NULL) { + goto error; + } + tmp = PyObject_CallMethod(filters, "strip", NULL); + if (tmp == NULL) { + goto error; + } + Py_DECREF(filters); + filters = tmp; + + if (PyObject_Not(filters)) { + Py_DECREF(filters); filters = NULL; + + res = PyTuple_New(2); + if (res == NULL) { + goto error; + } + PyTuple_SetItem(res, 0, name); /* steals */ + name = NULL; /* no ownership any more */ + filters = PyList_New(0); + if (filters == NULL) { + goto error; + } + PyTuple_SetItem(res, 1, filters); /* steals */ + return res; + } + + if (sstate == NULL) { + sstate = PyModule_GetState(self); + if (sstate == NULL) { + PyErr_SetString(PyExc_RuntimeError, "no module state available"); + goto error; + } + } + + tmp = PyUnicode_Split(filters, sstate->FILTER_SEPARATOR, -1); + if (tmp == NULL) { + goto error; + } + Py_DECREF(filters); + filters = tmp; + + res = PyTuple_New(2); + if (res == NULL) { + goto error; + } + PyTuple_SetItem(res, 0, name); /* steals -- ownership changed */ + PyTuple_SetItem(res, 1, filters); /* steals -- ownership changed */ + return res; + +error: + Py_XDECREF(res); + Py_XDECREF(filters); + Py_XDECREF(name); + return NULL; +} + + +static +PyObject * +fast_split_filters(PyObject *self, PyObject *varname) +{ + return _fast_split_filters(varname, self, NULL); +} + + +static +PyObject * fast_split_ns(PyObject *self, PyObject *varname) { PyObject *res = NULL; @@ -555,7 +672,7 @@ Py_DECREF(res); return NULL; } - o2 = _fast_unquote(self, o1, ns_idx, NULL); + o2 = _fast_unquote(o1, ns_idx, self, NULL); if (o2 == NULL) { Py_DECREF(o1); Py_DECREF(res); @@ -577,6 +694,7 @@ {"fast_unquote", fast_unquote, METH_O, PyDoc_STR("C-implementation of configmix.unquote")}, {"fast_quote", fast_quote, METH_O, PyDoc_STR("C-implementation of configmix.quote")}, {"fast_pathstr2path", fast_pathstr2path, METH_O, PyDoc_STR("C-implementation of configmix.pathstr2path")}, + {"_fast_split_filters", fast_split_filters, METH_O, PyDoc_STR("C-implementation of configmix.config._split_filters")}, {"_fast_split_ns", fast_split_ns, METH_O, PyDoc_STR("C-implementation of configmix.config._split_ns")}, {NULL, NULL, 0, NULL} }; @@ -621,6 +739,12 @@ } PyUnicode_InternInPlace(&(sstate->NS_SEPARATOR)); + sstate->FILTER_SEPARATOR = PyUnicode_FromStringAndSize("|", 1); + if (sstate->FILTER_SEPARATOR == NULL) { + return -1; + } + PyUnicode_InternInPlace(&(sstate->FILTER_SEPARATOR)); + sstate->EMPTY_STR = PyUnicode_FromStringAndSize("", 0); if (sstate->EMPTY_STR == NULL) { return -1; @@ -658,6 +782,7 @@ Py_VISIT(sstate->DOT); Py_VISIT(sstate->QUOTE); Py_VISIT(sstate->NS_SEPARATOR); + Py_VISIT(sstate->FILTER_SEPARATOR); Py_VISIT(sstate->EMPTY_STR); Py_VISIT(sstate->QUOTE_MAP); } @@ -675,6 +800,7 @@ Py_CLEAR(sstate->DOT); Py_CLEAR(sstate->QUOTE); Py_CLEAR(sstate->NS_SEPARATOR); + Py_CLEAR(sstate->FILTER_SEPARATOR); Py_CLEAR(sstate->EMPTY_STR); Py_CLEAR(sstate->QUOTE_MAP); }
