diff configmix/_speedups.c @ 543:491413368c7c

Added also a fast C-implementation of configmix.config._split_ns
author Franz Glasner <fzglas.hg@dom66.de>
date Sat, 01 Jan 2022 18:01:32 +0100
parents f71d34dda19f
children db2d108e14e7
line wrap: on
line diff
--- a/configmix/_speedups.c	Fri Dec 31 21:24:16 2021 +0100
+++ b/configmix/_speedups.c	Sat Jan 01 18:01:32 2022 +0100
@@ -21,6 +21,7 @@
 struct speedups_state {
     PyObject *DOT;
     PyObject *QUOTE;
+    PyObject *NS_SEPARATOR;
     PyObject *EMPTY_STR;
 };
 
@@ -81,10 +82,9 @@
 
 static
 PyObject *
-_fast_unquote(PyObject *self, PyObject *s, struct speedups_state *sstate)
+_fast_unquote(PyObject *self, PyObject *s, Py_ssize_t s_len, struct speedups_state *sstate)
 {
     Py_ssize_t find;
-    Py_ssize_t s_len;
     Py_ssize_t parts_len;
     PyObject *res;
     PyObject *res_parts = NULL;
@@ -99,9 +99,11 @@
         PyErr_SetString(PyExc_TypeError, "a (unicode) string type is expected");
         return NULL;
     }
-    s_len = PyUnicode_GetLength(s);
     if (s_len < 0) {
-        return NULL;
+        s_len = PyUnicode_GetLength(s);
+        if (s_len < 0) {
+            return NULL;
+        }
     }
     if (s_len == 0) {
         Py_INCREF(s);
@@ -230,7 +232,7 @@
 PyObject *
 fast_unquote(PyObject *self, PyObject *s)
 {
-    return _fast_unquote(self, s, NULL);
+    return _fast_unquote(self, s, -1, NULL);
 }
 
 
@@ -278,7 +280,7 @@
     }
     for (i=0; i < parts_len; i++) {
         o = PyList_GetItem(parts, i);   /* borrowed */
-        u = _fast_unquote(self, o, sstate);
+        u = _fast_unquote(self, o, -1, sstate);
         if (u == NULL) {
             goto error;
         }
@@ -295,9 +297,67 @@
 }
 
 
+static
+PyObject *
+fast_split_ns(PyObject *self, PyObject *varname)
+{
+    PyObject *res = NULL;
+    Py_ssize_t ns_idx;
+    Py_ssize_t varname_len;
+    PyObject *o1;
+    PyObject *o2;
+
+    varname_len = PyUnicode_GetLength(varname);
+    if (varname_len < 0) {
+        return NULL;
+    }
+    ns_idx = PyUnicode_FindChar(varname, ':', 0, varname_len, 1);
+    if (ns_idx == -2) {
+        return NULL;
+    }
+    if (ns_idx == -1) {
+        res = PyTuple_New(2);
+        if (res == NULL) {
+            return NULL;
+        }
+        Py_INCREF(Py_None);
+        PyTuple_SetItem(res, 0, Py_None);  /* steals */
+        Py_INCREF(varname);
+        PyTuple_SetItem(res, 1, varname);  /* steals */
+        return res;
+    }
+
+    res = PyTuple_New(2);
+    if (res == NULL) {
+        return NULL;
+    }
+    o1 = PyUnicode_Substring(varname, 0, ns_idx);
+    if (o1 == NULL) {
+        Py_DECREF(res);
+        return NULL;
+    }
+    o2 = _fast_unquote(self, o1, ns_idx, NULL);
+    if (o2 == NULL) {
+        Py_DECREF(o1);
+        Py_DECREF(res);
+        return NULL;
+    }
+    Py_DECREF(o1);
+    PyTuple_SetItem(res, 0, o2);    /* steals */
+    o1 = PyUnicode_Substring(varname, ns_idx+1, varname_len);
+    if (o1 == NULL) {
+        Py_DECREF(res);
+        return NULL;
+    }
+    PyTuple_SetItem(res, 1, o1);    /* steals */
+    return res;
+}
+
+
 static struct PyMethodDef speedups_methods[] = {
     {"fast_unquote", fast_unquote, METH_O, PyDoc_STR("C-implementation of configmix.unquote")},
     {"fast_pathstr2path", fast_pathstr2path, METH_O, PyDoc_STR("C-implementation of configmix.pathstr2path")},
+    {"_fast_split_ns", fast_split_ns, METH_O, PyDoc_STR("C-implementation of configmix.config._split_ns")},
     {NULL, NULL, 0, NULL}
 };
 
@@ -329,6 +389,12 @@
     }
     PyUnicode_InternInPlace(&(sstate->QUOTE));
 
+    sstate->NS_SEPARATOR = PyUnicode_FromStringAndSize(":", 1);
+    if (sstate->NS_SEPARATOR == NULL) {
+        return -1;
+    }
+    PyUnicode_InternInPlace(&(sstate->NS_SEPARATOR));
+
     sstate->EMPTY_STR = PyUnicode_FromStringAndSize("", 0);
     if (sstate->EMPTY_STR == NULL) {
         return -1;
@@ -348,6 +414,7 @@
     if (sstate != NULL) {
         Py_VISIT(sstate->DOT);
         Py_VISIT(sstate->QUOTE);
+        Py_VISIT(sstate->NS_SEPARATOR);
         Py_VISIT(sstate->EMPTY_STR);
     }
     return 0;
@@ -363,6 +430,7 @@
     if (sstate != NULL) {
         Py_CLEAR(sstate->DOT);
         Py_CLEAR(sstate->QUOTE);
+        Py_CLEAR(sstate->NS_SEPARATOR);
         Py_CLEAR(sstate->EMPTY_STR);
     }
     return 0;