comparison 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
comparison
equal deleted inserted replaced
542:f71d34dda19f 543:491413368c7c
19 * Module state holds pre-created some objects 19 * Module state holds pre-created some objects
20 */ 20 */
21 struct speedups_state { 21 struct speedups_state {
22 PyObject *DOT; 22 PyObject *DOT;
23 PyObject *QUOTE; 23 PyObject *QUOTE;
24 PyObject *NS_SEPARATOR;
24 PyObject *EMPTY_STR; 25 PyObject *EMPTY_STR;
25 }; 26 };
26 27
27 28
28 static 29 static
79 } 80 }
80 81
81 82
82 static 83 static
83 PyObject * 84 PyObject *
84 _fast_unquote(PyObject *self, PyObject *s, struct speedups_state *sstate) 85 _fast_unquote(PyObject *self, PyObject *s, Py_ssize_t s_len, struct speedups_state *sstate)
85 { 86 {
86 Py_ssize_t find; 87 Py_ssize_t find;
87 Py_ssize_t s_len;
88 Py_ssize_t parts_len; 88 Py_ssize_t parts_len;
89 PyObject *res; 89 PyObject *res;
90 PyObject *res_parts = NULL; 90 PyObject *res_parts = NULL;
91 PyObject *parts = NULL; 91 PyObject *parts = NULL;
92 PyObject *o; 92 PyObject *o;
97 97
98 if (!PyUnicode_Check(s)) { 98 if (!PyUnicode_Check(s)) {
99 PyErr_SetString(PyExc_TypeError, "a (unicode) string type is expected"); 99 PyErr_SetString(PyExc_TypeError, "a (unicode) string type is expected");
100 return NULL; 100 return NULL;
101 } 101 }
102 s_len = PyUnicode_GetLength(s);
103 if (s_len < 0) { 102 if (s_len < 0) {
104 return NULL; 103 s_len = PyUnicode_GetLength(s);
104 if (s_len < 0) {
105 return NULL;
106 }
105 } 107 }
106 if (s_len == 0) { 108 if (s_len == 0) {
107 Py_INCREF(s); 109 Py_INCREF(s);
108 return s; 110 return s;
109 } 111 }
228 230
229 static 231 static
230 PyObject * 232 PyObject *
231 fast_unquote(PyObject *self, PyObject *s) 233 fast_unquote(PyObject *self, PyObject *s)
232 { 234 {
233 return _fast_unquote(self, s, NULL); 235 return _fast_unquote(self, s, -1, NULL);
234 } 236 }
235 237
236 238
237 static 239 static
238 PyObject * 240 PyObject *
276 if (res == NULL) { 278 if (res == NULL) {
277 goto error; 279 goto error;
278 } 280 }
279 for (i=0; i < parts_len; i++) { 281 for (i=0; i < parts_len; i++) {
280 o = PyList_GetItem(parts, i); /* borrowed */ 282 o = PyList_GetItem(parts, i); /* borrowed */
281 u = _fast_unquote(self, o, sstate); 283 u = _fast_unquote(self, o, -1, sstate);
282 if (u == NULL) { 284 if (u == NULL) {
283 goto error; 285 goto error;
284 } 286 }
285 PyTuple_SetItem(res, i, u); /* steals */ 287 PyTuple_SetItem(res, i, u); /* steals */
286 } 288 }
293 Py_XDECREF(res); 295 Py_XDECREF(res);
294 return NULL; 296 return NULL;
295 } 297 }
296 298
297 299
300 static
301 PyObject *
302 fast_split_ns(PyObject *self, PyObject *varname)
303 {
304 PyObject *res = NULL;
305 Py_ssize_t ns_idx;
306 Py_ssize_t varname_len;
307 PyObject *o1;
308 PyObject *o2;
309
310 varname_len = PyUnicode_GetLength(varname);
311 if (varname_len < 0) {
312 return NULL;
313 }
314 ns_idx = PyUnicode_FindChar(varname, ':', 0, varname_len, 1);
315 if (ns_idx == -2) {
316 return NULL;
317 }
318 if (ns_idx == -1) {
319 res = PyTuple_New(2);
320 if (res == NULL) {
321 return NULL;
322 }
323 Py_INCREF(Py_None);
324 PyTuple_SetItem(res, 0, Py_None); /* steals */
325 Py_INCREF(varname);
326 PyTuple_SetItem(res, 1, varname); /* steals */
327 return res;
328 }
329
330 res = PyTuple_New(2);
331 if (res == NULL) {
332 return NULL;
333 }
334 o1 = PyUnicode_Substring(varname, 0, ns_idx);
335 if (o1 == NULL) {
336 Py_DECREF(res);
337 return NULL;
338 }
339 o2 = _fast_unquote(self, o1, ns_idx, NULL);
340 if (o2 == NULL) {
341 Py_DECREF(o1);
342 Py_DECREF(res);
343 return NULL;
344 }
345 Py_DECREF(o1);
346 PyTuple_SetItem(res, 0, o2); /* steals */
347 o1 = PyUnicode_Substring(varname, ns_idx+1, varname_len);
348 if (o1 == NULL) {
349 Py_DECREF(res);
350 return NULL;
351 }
352 PyTuple_SetItem(res, 1, o1); /* steals */
353 return res;
354 }
355
356
298 static struct PyMethodDef speedups_methods[] = { 357 static struct PyMethodDef speedups_methods[] = {
299 {"fast_unquote", fast_unquote, METH_O, PyDoc_STR("C-implementation of configmix.unquote")}, 358 {"fast_unquote", fast_unquote, METH_O, PyDoc_STR("C-implementation of configmix.unquote")},
300 {"fast_pathstr2path", fast_pathstr2path, METH_O, PyDoc_STR("C-implementation of configmix.pathstr2path")}, 359 {"fast_pathstr2path", fast_pathstr2path, METH_O, PyDoc_STR("C-implementation of configmix.pathstr2path")},
360 {"_fast_split_ns", fast_split_ns, METH_O, PyDoc_STR("C-implementation of configmix.config._split_ns")},
301 {NULL, NULL, 0, NULL} 361 {NULL, NULL, 0, NULL}
302 }; 362 };
303 363
304 364
305 static 365 static
327 if (sstate->QUOTE == NULL) { 387 if (sstate->QUOTE == NULL) {
328 return -1; 388 return -1;
329 } 389 }
330 PyUnicode_InternInPlace(&(sstate->QUOTE)); 390 PyUnicode_InternInPlace(&(sstate->QUOTE));
331 391
392 sstate->NS_SEPARATOR = PyUnicode_FromStringAndSize(":", 1);
393 if (sstate->NS_SEPARATOR == NULL) {
394 return -1;
395 }
396 PyUnicode_InternInPlace(&(sstate->NS_SEPARATOR));
397
332 sstate->EMPTY_STR = PyUnicode_FromStringAndSize("", 0); 398 sstate->EMPTY_STR = PyUnicode_FromStringAndSize("", 0);
333 if (sstate->EMPTY_STR == NULL) { 399 if (sstate->EMPTY_STR == NULL) {
334 return -1; 400 return -1;
335 } 401 }
336 PyUnicode_InternInPlace(&(sstate->EMPTY_STR)); 402 PyUnicode_InternInPlace(&(sstate->EMPTY_STR));
346 struct speedups_state *sstate = PyModule_GetState(module); 412 struct speedups_state *sstate = PyModule_GetState(module);
347 413
348 if (sstate != NULL) { 414 if (sstate != NULL) {
349 Py_VISIT(sstate->DOT); 415 Py_VISIT(sstate->DOT);
350 Py_VISIT(sstate->QUOTE); 416 Py_VISIT(sstate->QUOTE);
417 Py_VISIT(sstate->NS_SEPARATOR);
351 Py_VISIT(sstate->EMPTY_STR); 418 Py_VISIT(sstate->EMPTY_STR);
352 } 419 }
353 return 0; 420 return 0;
354 } 421 }
355 422
361 struct speedups_state *sstate = PyModule_GetState(module); 428 struct speedups_state *sstate = PyModule_GetState(module);
362 429
363 if (sstate != NULL) { 430 if (sstate != NULL) {
364 Py_CLEAR(sstate->DOT); 431 Py_CLEAR(sstate->DOT);
365 Py_CLEAR(sstate->QUOTE); 432 Py_CLEAR(sstate->QUOTE);
433 Py_CLEAR(sstate->NS_SEPARATOR);
366 Py_CLEAR(sstate->EMPTY_STR); 434 Py_CLEAR(sstate->EMPTY_STR);
367 } 435 }
368 return 0; 436 return 0;
369 } 437 }
370 438