~ubuntu-branches/ubuntu/precise/python3.2/precise-proposed

« back to all changes in this revision

Viewing changes to Objects/accu.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2012-03-09 18:40:39 UTC
  • mfrom: (30.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20120309184039-j3yk2emxr1plyo21
Tags: 3.2.3~rc1-1
* Python 3.2.3 release candidate 1.
* Update to 20120309 from the 3.2 branch.
* Fix libpython.a symlink. Closes: #660146.
* Build-depend on xauth.
* Run the gdb tests for the debug build only.

Show diffs side-by-side

added added

removed removed

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