Mercurial > hgrepos > Python > libs > ConfigMix
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 |
