Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 90c30e8

Browse files
committed
Remove now duplicate code in _json.c; instead, reuse the new private lib
1 parent c61c8d7 commit 90c30e8

1 file changed

Lines changed: 22 additions & 123 deletions

File tree

Modules/_json.c

Lines changed: 22 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -75,17 +75,6 @@ static PyMemberDef encoder_members[] = {
7575
{NULL}
7676
};
7777

78-
/*
79-
* A two-level accumulator of unicode objects that avoids both the overhead
80-
* of keeping a huge number of small separate objects, and the quadratic
81-
* behaviour of using a naive repeated concatenation scheme.
82-
*/
83-
84-
typedef struct {
85-
PyObject *large; /* A list of previously accumulated large strings */
86-
PyObject *small; /* Pending small strings */
87-
} accumulator;
88-
8978
static PyObject *
9079
join_list_unicode(PyObject *lst)
9180
{
@@ -99,96 +88,6 @@ join_list_unicode(PyObject *lst)
9988
return PyUnicode_Join(sep, lst);
10089
}
10190

102-
static int
103-
init_accumulator(accumulator *acc)
104-
{
105-
acc->large = PyList_New(0);
106-
if (acc->large == NULL)
107-
return -1;
108-
acc->small = PyList_New(0);
109-
if (acc->small == NULL) {
110-
Py_CLEAR(acc->large);
111-
return -1;
112-
}
113-
return 0;
114-
}
115-
116-
static int
117-
flush_accumulator(accumulator *acc)
118-
{
119-
Py_ssize_t nsmall = PyList_GET_SIZE(acc->small);
120-
if (nsmall) {
121-
int ret;
122-
PyObject *joined = join_list_unicode(acc->small);
123-
if (joined == NULL)
124-
return -1;
125-
if (PyList_SetSlice(acc->small, 0, nsmall, NULL)) {
126-
Py_DECREF(joined);
127-
return -1;
128-
}
129-
ret = PyList_Append(acc->large, joined);
130-
Py_DECREF(joined);
131-
return ret;
132-
}
133-
return 0;
134-
}
135-
136-
static int
137-
accumulate_unicode(accumulator *acc, PyObject *obj)
138-
{
139-
int ret;
140-
Py_ssize_t nsmall;
141-
PyObject *joined;
142-
assert(PyUnicode_Check(obj));
143-
144-
if (PyList_Append(acc->small, obj))
145-
return -1;
146-
nsmall = PyList_GET_SIZE(acc->small);
147-
/* Each item in a list of unicode objects has an overhead (in 64-bit
148-
* builds) of:
149-
* - 8 bytes for the list slot
150-
* - 56 bytes for the header of the unicode object
151-
* that is, 64 bytes. 100000 such objects waste more than 6MB
152-
* compared to a single concatenated string.
153-
*/
154-
if (nsmall < 100000)
155-
return 0;
156-
joined = join_list_unicode(acc->small);
157-
if (joined == NULL)
158-
return -1;
159-
if (PyList_SetSlice(acc->small, 0, nsmall, NULL)) {
160-
Py_DECREF(joined);
161-
return -1;
162-
}
163-
ret = PyList_Append(acc->large, joined);
164-
Py_DECREF(joined);
165-
return ret;
166-
}
167-
168-
static PyObject *
169-
finish_accumulator(accumulator *acc)
170-
{
171-
int ret;
172-
PyObject *res;
173-
174-
ret = flush_accumulator(acc);
175-
Py_CLEAR(acc->small);
176-
if (ret) {
177-
Py_CLEAR(acc->large);
178-
return NULL;
179-
}
180-
res = acc->large;
181-
acc->large = NULL;
182-
return res;
183-
}
184-
185-
static void
186-
destroy_accumulator(accumulator *acc)
187-
{
188-
Py_CLEAR(acc->small);
189-
Py_CLEAR(acc->large);
190-
}
191-
19291
/* Forward decls */
19392

19493
static PyObject *
@@ -217,11 +116,11 @@ encoder_dealloc(PyObject *self);
217116
static int
218117
encoder_clear(PyObject *self);
219118
static int
220-
encoder_listencode_list(PyEncoderObject *s, accumulator *acc, PyObject *seq, Py_ssize_t indent_level);
119+
encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc, PyObject *seq, Py_ssize_t indent_level);
221120
static int
222-
encoder_listencode_obj(PyEncoderObject *s, accumulator *acc, PyObject *obj, Py_ssize_t indent_level);
121+
encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc, PyObject *obj, Py_ssize_t indent_level);
223122
static int
224-
encoder_listencode_dict(PyEncoderObject *s, accumulator *acc, PyObject *dct, Py_ssize_t indent_level);
123+
encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, PyObject *dct, Py_ssize_t indent_level);
225124
static PyObject *
226125
_encoded_const(PyObject *obj);
227126
static void
@@ -1383,20 +1282,20 @@ encoder_call(PyObject *self, PyObject *args, PyObject *kwds)
13831282
PyObject *obj;
13841283
Py_ssize_t indent_level;
13851284
PyEncoderObject *s;
1386-
accumulator acc;
1285+
_PyAccu acc;
13871286

13881287
assert(PyEncoder_Check(self));
13891288
s = (PyEncoderObject *)self;
13901289
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&:_iterencode", kwlist,
13911290
&obj, _convertPyInt_AsSsize_t, &indent_level))
13921291
return NULL;
1393-
if (init_accumulator(&acc))
1292+
if (_PyAccu_Init(&acc))
13941293
return NULL;
13951294
if (encoder_listencode_obj(s, &acc, obj, indent_level)) {
1396-
destroy_accumulator(&acc);
1295+
_PyAccu_Destroy(&acc);
13971296
return NULL;
13981297
}
1399-
return finish_accumulator(&acc);
1298+
return _PyAccu_FinishAsList(&acc);
14001299
}
14011300

14021301
static PyObject *
@@ -1468,16 +1367,16 @@ encoder_encode_string(PyEncoderObject *s, PyObject *obj)
14681367
}
14691368

14701369
static int
1471-
_steal_accumulate(accumulator *acc, PyObject *stolen)
1370+
_steal_accumulate(_PyAccu *acc, PyObject *stolen)
14721371
{
14731372
/* Append stolen and then decrement its reference count */
1474-
int rval = accumulate_unicode(acc, stolen);
1373+
int rval = _PyAccu_Accumulate(acc, stolen);
14751374
Py_DECREF(stolen);
14761375
return rval;
14771376
}
14781377

14791378
static int
1480-
encoder_listencode_obj(PyEncoderObject *s, accumulator *acc,
1379+
encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc,
14811380
PyObject *obj, Py_ssize_t indent_level)
14821381
{
14831382
/* Encode Python object obj to a JSON term */
@@ -1570,7 +1469,7 @@ encoder_listencode_obj(PyEncoderObject *s, accumulator *acc,
15701469
}
15711470

15721471
static int
1573-
encoder_listencode_dict(PyEncoderObject *s, accumulator *acc,
1472+
encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc,
15741473
PyObject *dct, Py_ssize_t indent_level)
15751474
{
15761475
/* Encode Python dict dct a JSON term */
@@ -1593,7 +1492,7 @@ encoder_listencode_dict(PyEncoderObject *s, accumulator *acc,
15931492
return -1;
15941493
}
15951494
if (Py_SIZE(dct) == 0)
1596-
return accumulate_unicode(acc, empty_dict);
1495+
return _PyAccu_Accumulate(acc, empty_dict);
15971496

15981497
if (s->markers != Py_None) {
15991498
int has_key;
@@ -1611,7 +1510,7 @@ encoder_listencode_dict(PyEncoderObject *s, accumulator *acc,
16111510
}
16121511
}
16131512

1614-
if (accumulate_unicode(acc, open_dict))
1513+
if (_PyAccu_Accumulate(acc, open_dict))
16151514
goto bail;
16161515

16171516
if (s->indent != Py_None) {
@@ -1698,20 +1597,20 @@ encoder_listencode_dict(PyEncoderObject *s, accumulator *acc,
16981597
}
16991598

17001599
if (idx) {
1701-
if (accumulate_unicode(acc, s->item_separator))
1600+
if (_PyAccu_Accumulate(acc, s->item_separator))
17021601
goto bail;
17031602
}
17041603

17051604
encoded = encoder_encode_string(s, kstr);
17061605
Py_CLEAR(kstr);
17071606
if (encoded == NULL)
17081607
goto bail;
1709-
if (accumulate_unicode(acc, encoded)) {
1608+
if (_PyAccu_Accumulate(acc, encoded)) {
17101609
Py_DECREF(encoded);
17111610
goto bail;
17121611
}
17131612
Py_DECREF(encoded);
1714-
if (accumulate_unicode(acc, s->key_separator))
1613+
if (_PyAccu_Accumulate(acc, s->key_separator))
17151614
goto bail;
17161615

17171616
value = PyTuple_GET_ITEM(item, 1);
@@ -1735,7 +1634,7 @@ encoder_listencode_dict(PyEncoderObject *s, accumulator *acc,
17351634
17361635
yield '\n' + (' ' * (_indent * _current_indent_level))
17371636
}*/
1738-
if (accumulate_unicode(acc, close_dict))
1637+
if (_PyAccu_Accumulate(acc, close_dict))
17391638
goto bail;
17401639
return 0;
17411640

@@ -1749,7 +1648,7 @@ encoder_listencode_dict(PyEncoderObject *s, accumulator *acc,
17491648

17501649

17511650
static int
1752-
encoder_listencode_list(PyEncoderObject *s, accumulator *acc,
1651+
encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc,
17531652
PyObject *seq, Py_ssize_t indent_level)
17541653
{
17551654
/* Encode Python list seq to a JSON term */
@@ -1776,7 +1675,7 @@ encoder_listencode_list(PyEncoderObject *s, accumulator *acc,
17761675
num_items = PySequence_Fast_GET_SIZE(s_fast);
17771676
if (num_items == 0) {
17781677
Py_DECREF(s_fast);
1779-
return accumulate_unicode(acc, empty_array);
1678+
return _PyAccu_Accumulate(acc, empty_array);
17801679
}
17811680

17821681
if (s->markers != Py_None) {
@@ -1796,7 +1695,7 @@ encoder_listencode_list(PyEncoderObject *s, accumulator *acc,
17961695
}
17971696

17981697
seq_items = PySequence_Fast_ITEMS(s_fast);
1799-
if (accumulate_unicode(acc, open_array))
1698+
if (_PyAccu_Accumulate(acc, open_array))
18001699
goto bail;
18011700
if (s->indent != Py_None) {
18021701
/* TODO: DOES NOT RUN */
@@ -1810,7 +1709,7 @@ encoder_listencode_list(PyEncoderObject *s, accumulator *acc,
18101709
for (i = 0; i < num_items; i++) {
18111710
PyObject *obj = seq_items[i];
18121711
if (i) {
1813-
if (accumulate_unicode(acc, s->item_separator))
1712+
if (_PyAccu_Accumulate(acc, s->item_separator))
18141713
goto bail;
18151714
}
18161715
if (encoder_listencode_obj(s, acc, obj, indent_level))
@@ -1828,7 +1727,7 @@ encoder_listencode_list(PyEncoderObject *s, accumulator *acc,
18281727
18291728
yield '\n' + (' ' * (_indent * _current_indent_level))
18301729
}*/
1831-
if (accumulate_unicode(acc, close_array))
1730+
if (_PyAccu_Accumulate(acc, close_array))
18321731
goto bail;
18331732
Py_DECREF(s_fast);
18341733
return 0;

0 commit comments

Comments
 (0)