ยปCore Development>Code coverage>Objects/accu.c

Python code coverage for Objects/accu.c

#countcontent
1n/a/* Accumulator struct implementation */
2n/a
3n/a#include "Python.h"
4n/a#include "accu.h"
5n/a
6n/astatic PyObject *
7n/ajoin_list_unicode(PyObject *lst)
8n/a{
9n/a /* return ''.join(lst) */
10n/a PyObject *sep, *ret;
11n/a sep = PyUnicode_FromStringAndSize("", 0);
12n/a ret = PyUnicode_Join(sep, lst);
13n/a Py_DECREF(sep);
14n/a return ret;
15n/a}
16n/a
17n/aint
18n/a_PyAccu_Init(_PyAccu *acc)
19n/a{
20n/a /* Lazily allocated */
21n/a acc->large = NULL;
22n/a acc->small = PyList_New(0);
23n/a if (acc->small == NULL)
24n/a return -1;
25n/a return 0;
26n/a}
27n/a
28n/astatic int
29n/aflush_accumulator(_PyAccu *acc)
30n/a{
31n/a Py_ssize_t nsmall = PyList_GET_SIZE(acc->small);
32n/a if (nsmall) {
33n/a int ret;
34n/a PyObject *joined;
35n/a if (acc->large == NULL) {
36n/a acc->large = PyList_New(0);
37n/a if (acc->large == NULL)
38n/a return -1;
39n/a }
40n/a joined = join_list_unicode(acc->small);
41n/a if (joined == NULL)
42n/a return -1;
43n/a if (PyList_SetSlice(acc->small, 0, nsmall, NULL)) {
44n/a Py_DECREF(joined);
45n/a return -1;
46n/a }
47n/a ret = PyList_Append(acc->large, joined);
48n/a Py_DECREF(joined);
49n/a return ret;
50n/a }
51n/a return 0;
52n/a}
53n/a
54n/aint
55n/a_PyAccu_Accumulate(_PyAccu *acc, PyObject *unicode)
56n/a{
57n/a Py_ssize_t nsmall;
58n/a assert(PyUnicode_Check(unicode));
59n/a
60n/a if (PyList_Append(acc->small, unicode))
61n/a return -1;
62n/a nsmall = PyList_GET_SIZE(acc->small);
63n/a /* Each item in a list of unicode objects has an overhead (in 64-bit
64n/a * builds) of:
65n/a * - 8 bytes for the list slot
66n/a * - 56 bytes for the header of the unicode object
67n/a * that is, 64 bytes. 100000 such objects waste more than 6MB
68n/a * compared to a single concatenated string.
69n/a */
70n/a if (nsmall < 100000)
71n/a return 0;
72n/a return flush_accumulator(acc);
73n/a}
74n/a
75n/aPyObject *
76n/a_PyAccu_FinishAsList(_PyAccu *acc)
77n/a{
78n/a int ret;
79n/a PyObject *res;
80n/a
81n/a ret = flush_accumulator(acc);
82n/a Py_CLEAR(acc->small);
83n/a if (ret) {
84n/a Py_CLEAR(acc->large);
85n/a return NULL;
86n/a }
87n/a res = acc->large;
88n/a acc->large = NULL;
89n/a return res;
90n/a}
91n/a
92n/aPyObject *
93n/a_PyAccu_Finish(_PyAccu *acc)
94n/a{
95n/a PyObject *list, *res;
96n/a if (acc->large == NULL) {
97n/a list = acc->small;
98n/a acc->small = NULL;
99n/a }
100n/a else {
101n/a list = _PyAccu_FinishAsList(acc);
102n/a if (!list)
103n/a return NULL;
104n/a }
105n/a res = join_list_unicode(list);
106n/a Py_DECREF(list);
107n/a return res;
108n/a}
109n/a
110n/avoid
111n/a_PyAccu_Destroy(_PyAccu *acc)
112n/a{
113n/a Py_CLEAR(acc->small);
114n/a Py_CLEAR(acc->large);
115n/a}