Branch data Line data Source code
1 : : #include "Python.h"
2 : : #include "pycore_call.h" // _PyObject_CallNoArgs()
3 : : #include "pycore_long.h" // _PyLong_GetZero()
4 : : #include "structmember.h" // PyMemberDef
5 : : #include <stddef.h>
6 : :
7 : : /*[clinic input]
8 : : module _collections
9 : : class _tuplegetter "_tuplegetterobject *" "&tuplegetter_type"
10 : : [clinic start generated code]*/
11 : : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=a8ece4ccad7e30ac]*/
12 : :
13 : : static PyTypeObject tuplegetter_type;
14 : : #include "clinic/_collectionsmodule.c.h"
15 : :
16 : : /* collections module implementation of a deque() datatype
17 : : Written and maintained by Raymond D. Hettinger <python@rcn.com>
18 : : */
19 : :
20 : : /* The block length may be set to any number over 1. Larger numbers
21 : : * reduce the number of calls to the memory allocator, give faster
22 : : * indexing and rotation, and reduce the link to data overhead ratio.
23 : : * Making the block length a power of two speeds-up the modulo
24 : : * and division calculations in deque_item() and deque_ass_item().
25 : : */
26 : :
27 : : #define BLOCKLEN 64
28 : : #define CENTER ((BLOCKLEN - 1) / 2)
29 : : #define MAXFREEBLOCKS 16
30 : :
31 : : /* Data for deque objects is stored in a doubly-linked list of fixed
32 : : * length blocks. This assures that appends or pops never move any
33 : : * other data elements besides the one being appended or popped.
34 : : *
35 : : * Another advantage is that it completely avoids use of realloc(),
36 : : * resulting in more predictable performance.
37 : : *
38 : : * Textbook implementations of doubly-linked lists store one datum
39 : : * per link, but that gives them a 200% memory overhead (a prev and
40 : : * next link for each datum) and it costs one malloc() call per data
41 : : * element. By using fixed-length blocks, the link to data ratio is
42 : : * significantly improved and there are proportionally fewer calls
43 : : * to malloc() and free(). The data blocks of consecutive pointers
44 : : * also improve cache locality.
45 : : *
46 : : * The list of blocks is never empty, so d.leftblock and d.rightblock
47 : : * are never equal to NULL. The list is not circular.
48 : : *
49 : : * A deque d's first element is at d.leftblock[leftindex]
50 : : * and its last element is at d.rightblock[rightindex].
51 : : *
52 : : * Unlike Python slice indices, these indices are inclusive on both
53 : : * ends. This makes the algorithms for left and right operations
54 : : * more symmetrical and it simplifies the design.
55 : : *
56 : : * The indices, d.leftindex and d.rightindex are always in the range:
57 : : * 0 <= index < BLOCKLEN
58 : : *
59 : : * And their exact relationship is:
60 : : * (d.leftindex + d.len - 1) % BLOCKLEN == d.rightindex
61 : : *
62 : : * Whenever d.leftblock == d.rightblock, then:
63 : : * d.leftindex + d.len - 1 == d.rightindex
64 : : *
65 : : * However, when d.leftblock != d.rightblock, the d.leftindex and
66 : : * d.rightindex become indices into distinct blocks and either may
67 : : * be larger than the other.
68 : : *
69 : : * Empty deques have:
70 : : * d.len == 0
71 : : * d.leftblock == d.rightblock
72 : : * d.leftindex == CENTER + 1
73 : : * d.rightindex == CENTER
74 : : *
75 : : * Checking for d.len == 0 is the intended way to see whether d is empty.
76 : : */
77 : :
78 : : typedef struct BLOCK {
79 : : struct BLOCK *leftlink;
80 : : PyObject *data[BLOCKLEN];
81 : : struct BLOCK *rightlink;
82 : : } block;
83 : :
84 : : typedef struct {
85 : : PyObject_VAR_HEAD
86 : : block *leftblock;
87 : : block *rightblock;
88 : : Py_ssize_t leftindex; /* 0 <= leftindex < BLOCKLEN */
89 : : Py_ssize_t rightindex; /* 0 <= rightindex < BLOCKLEN */
90 : : size_t state; /* incremented whenever the indices move */
91 : : Py_ssize_t maxlen; /* maxlen is -1 for unbounded deques */
92 : : Py_ssize_t numfreeblocks;
93 : : block *freeblocks[MAXFREEBLOCKS];
94 : : PyObject *weakreflist;
95 : : } dequeobject;
96 : :
97 : : static PyTypeObject deque_type;
98 : :
99 : : /* For debug builds, add error checking to track the endpoints
100 : : * in the chain of links. The goal is to make sure that link
101 : : * assignments only take place at endpoints so that links already
102 : : * in use do not get overwritten.
103 : : *
104 : : * CHECK_END should happen before each assignment to a block's link field.
105 : : * MARK_END should happen whenever a link field becomes a new endpoint.
106 : : * This happens when new blocks are added or whenever an existing
107 : : * block is freed leaving another existing block as the new endpoint.
108 : : */
109 : :
110 : : #ifndef NDEBUG
111 : : #define MARK_END(link) link = NULL;
112 : : #define CHECK_END(link) assert(link == NULL);
113 : : #define CHECK_NOT_END(link) assert(link != NULL);
114 : : #else
115 : : #define MARK_END(link)
116 : : #define CHECK_END(link)
117 : : #define CHECK_NOT_END(link)
118 : : #endif
119 : :
120 : : /* A simple freelisting scheme is used to minimize calls to the memory
121 : : allocator. It accommodates common use cases where new blocks are being
122 : : added at about the same rate as old blocks are being freed.
123 : : */
124 : :
125 : : static inline block *
126 : 78693 : newblock(dequeobject *deque) {
127 : : block *b;
128 [ + + ]: 78693 : if (deque->numfreeblocks) {
129 : 15076 : deque->numfreeblocks--;
130 : 15076 : return deque->freeblocks[deque->numfreeblocks];
131 : : }
132 : 63617 : b = PyMem_Malloc(sizeof(block));
133 [ + - ]: 63617 : if (b != NULL) {
134 : 63617 : return b;
135 : : }
136 : : PyErr_NoMemory();
137 : 0 : return NULL;
138 : : }
139 : :
140 : : static inline void
141 : 78503 : freeblock(dequeobject *deque, block *b)
142 : : {
143 [ + + ]: 78503 : if (deque->numfreeblocks < MAXFREEBLOCKS) {
144 : 69861 : deque->freeblocks[deque->numfreeblocks] = b;
145 : 69861 : deque->numfreeblocks++;
146 : : } else {
147 : 8642 : PyMem_Free(b);
148 : : }
149 : 78503 : }
150 : :
151 : : static PyObject *
152 : 50449 : deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
153 : : {
154 : : dequeobject *deque;
155 : : block *b;
156 : :
157 : : /* create dequeobject structure */
158 : 50449 : deque = (dequeobject *)type->tp_alloc(type, 0);
159 [ - + ]: 50449 : if (deque == NULL)
160 : 0 : return NULL;
161 : :
162 : 50449 : b = newblock(deque);
163 [ - + ]: 50449 : if (b == NULL) {
164 : 0 : Py_DECREF(deque);
165 : 0 : return NULL;
166 : : }
167 : : MARK_END(b->leftlink);
168 : : MARK_END(b->rightlink);
169 : :
170 : : assert(BLOCKLEN >= 2);
171 : 50449 : Py_SET_SIZE(deque, 0);
172 : 50449 : deque->leftblock = b;
173 : 50449 : deque->rightblock = b;
174 : 50449 : deque->leftindex = CENTER + 1;
175 : 50449 : deque->rightindex = CENTER;
176 : 50449 : deque->state = 0;
177 : 50449 : deque->maxlen = -1;
178 : 50449 : deque->numfreeblocks = 0;
179 : 50449 : deque->weakreflist = NULL;
180 : :
181 : 50449 : return (PyObject *)deque;
182 : : }
183 : :
184 : : static PyObject *
185 : 734753 : deque_pop(dequeobject *deque, PyObject *unused)
186 : : {
187 : : PyObject *item;
188 : : block *prevblock;
189 : :
190 [ + + ]: 734753 : if (Py_SIZE(deque) == 0) {
191 : 3 : PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
192 : 3 : return NULL;
193 : : }
194 : 734750 : item = deque->rightblock->data[deque->rightindex];
195 : 734750 : deque->rightindex--;
196 : 734750 : Py_SET_SIZE(deque, Py_SIZE(deque) - 1);
197 : 734750 : deque->state++;
198 : :
199 [ + + ]: 734750 : if (deque->rightindex < 0) {
200 [ + + ]: 12875 : if (Py_SIZE(deque)) {
201 : 9733 : prevblock = deque->rightblock->leftlink;
202 : : assert(deque->leftblock != deque->rightblock);
203 : 9733 : freeblock(deque, deque->rightblock);
204 : : CHECK_NOT_END(prevblock);
205 : : MARK_END(prevblock->rightlink);
206 : 9733 : deque->rightblock = prevblock;
207 : 9733 : deque->rightindex = BLOCKLEN - 1;
208 : : } else {
209 : : assert(deque->leftblock == deque->rightblock);
210 : : assert(deque->leftindex == deque->rightindex+1);
211 : : /* re-center instead of freeing a block */
212 : 3142 : deque->leftindex = CENTER + 1;
213 : 3142 : deque->rightindex = CENTER;
214 : : }
215 : : }
216 : 734750 : return item;
217 : : }
218 : :
219 : : PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element.");
220 : :
221 : : static PyObject *
222 : 1005079 : deque_popleft(dequeobject *deque, PyObject *unused)
223 : : {
224 : : PyObject *item;
225 : : block *prevblock;
226 : :
227 [ + + ]: 1005079 : if (Py_SIZE(deque) == 0) {
228 : 810 : PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
229 : 810 : return NULL;
230 : : }
231 : : assert(deque->leftblock != NULL);
232 : 1004269 : item = deque->leftblock->data[deque->leftindex];
233 : 1004269 : deque->leftindex++;
234 : 1004269 : Py_SET_SIZE(deque, Py_SIZE(deque) - 1);
235 : 1004269 : deque->state++;
236 : :
237 [ + + ]: 1004269 : if (deque->leftindex == BLOCKLEN) {
238 [ + + ]: 16394 : if (Py_SIZE(deque)) {
239 : : assert(deque->leftblock != deque->rightblock);
240 : 12305 : prevblock = deque->leftblock->rightlink;
241 : 12305 : freeblock(deque, deque->leftblock);
242 : : CHECK_NOT_END(prevblock);
243 : : MARK_END(prevblock->leftlink);
244 : 12305 : deque->leftblock = prevblock;
245 : 12305 : deque->leftindex = 0;
246 : : } else {
247 : : assert(deque->leftblock == deque->rightblock);
248 : : assert(deque->leftindex == deque->rightindex+1);
249 : : /* re-center instead of freeing a block */
250 : 4089 : deque->leftindex = CENTER + 1;
251 : 4089 : deque->rightindex = CENTER;
252 : : }
253 : : }
254 : 1004269 : return item;
255 : : }
256 : :
257 : : PyDoc_STRVAR(popleft_doc, "Remove and return the leftmost element.");
258 : :
259 : : /* The deque's size limit is d.maxlen. The limit can be zero or positive.
260 : : * If there is no limit, then d.maxlen == -1.
261 : : *
262 : : * After an item is added to a deque, we check to see if the size has
263 : : * grown past the limit. If it has, we get the size back down to the limit
264 : : * by popping an item off of the opposite end. The methods that can
265 : : * trigger this are append(), appendleft(), extend(), and extendleft().
266 : : *
267 : : * The macro to check whether a deque needs to be trimmed uses a single
268 : : * unsigned test that returns true whenever 0 <= maxlen < Py_SIZE(deque).
269 : : */
270 : :
271 : : #define NEEDS_TRIM(deque, maxlen) ((size_t)(maxlen) < (size_t)(Py_SIZE(deque)))
272 : :
273 : : static inline int
274 : 1224411 : deque_append_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen)
275 : : {
276 [ + + ]: 1224411 : if (deque->rightindex == BLOCKLEN - 1) {
277 : 15259 : block *b = newblock(deque);
278 [ - + ]: 15259 : if (b == NULL)
279 : 0 : return -1;
280 : 15259 : b->leftlink = deque->rightblock;
281 : : CHECK_END(deque->rightblock->rightlink);
282 : 15259 : deque->rightblock->rightlink = b;
283 : 15259 : deque->rightblock = b;
284 : : MARK_END(b->rightlink);
285 : 15259 : deque->rightindex = -1;
286 : : }
287 : 1224411 : Py_SET_SIZE(deque, Py_SIZE(deque) + 1);
288 : 1224411 : deque->rightindex++;
289 : 1224411 : deque->rightblock->data[deque->rightindex] = item;
290 [ + + ]: 1224411 : if (NEEDS_TRIM(deque, maxlen)) {
291 : 23327 : PyObject *olditem = deque_popleft(deque, NULL);
292 : 23327 : Py_DECREF(olditem);
293 : : } else {
294 : 1201084 : deque->state++;
295 : : }
296 : 1224411 : return 0;
297 : : }
298 : :
299 : : static PyObject *
300 : 970849 : deque_append(dequeobject *deque, PyObject *item)
301 : : {
302 : 970849 : Py_INCREF(item);
303 [ - + ]: 970849 : if (deque_append_internal(deque, item, deque->maxlen) < 0)
304 : 0 : return NULL;
305 : 970849 : Py_RETURN_NONE;
306 : : }
307 : :
308 : : PyDoc_STRVAR(append_doc, "Add an element to the right side of the deque.");
309 : :
310 : : static inline int
311 : 703832 : deque_appendleft_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen)
312 : : {
313 [ + + ]: 703832 : if (deque->leftindex == 0) {
314 : 9392 : block *b = newblock(deque);
315 [ - + ]: 9392 : if (b == NULL)
316 : 0 : return -1;
317 : 9392 : b->rightlink = deque->leftblock;
318 : : CHECK_END(deque->leftblock->leftlink);
319 : 9392 : deque->leftblock->leftlink = b;
320 : 9392 : deque->leftblock = b;
321 : : MARK_END(b->leftlink);
322 : 9392 : deque->leftindex = BLOCKLEN;
323 : : }
324 : 703832 : Py_SET_SIZE(deque, Py_SIZE(deque) + 1);
325 : 703832 : deque->leftindex--;
326 : 703832 : deque->leftblock->data[deque->leftindex] = item;
327 [ + + ]: 703832 : if (NEEDS_TRIM(deque, deque->maxlen)) {
328 : 3 : PyObject *olditem = deque_pop(deque, NULL);
329 : 3 : Py_DECREF(olditem);
330 : : } else {
331 : 703829 : deque->state++;
332 : : }
333 : 703832 : return 0;
334 : : }
335 : :
336 : : static PyObject *
337 : 702820 : deque_appendleft(dequeobject *deque, PyObject *item)
338 : : {
339 : 702820 : Py_INCREF(item);
340 [ - + ]: 702820 : if (deque_appendleft_internal(deque, item, deque->maxlen) < 0)
341 : 0 : return NULL;
342 : 702820 : Py_RETURN_NONE;
343 : : }
344 : :
345 : : PyDoc_STRVAR(appendleft_doc, "Add an element to the left side of the deque.");
346 : :
347 : : static PyObject*
348 : 12016 : finalize_iterator(PyObject *it)
349 : : {
350 [ + + ]: 12016 : if (PyErr_Occurred()) {
351 [ + + ]: 31 : if (PyErr_ExceptionMatches(PyExc_StopIteration))
352 : 20 : PyErr_Clear();
353 : : else {
354 : 11 : Py_DECREF(it);
355 : 11 : return NULL;
356 : : }
357 : : }
358 : 12005 : Py_DECREF(it);
359 : 12005 : Py_RETURN_NONE;
360 : : }
361 : :
362 : : /* Run an iterator to exhaustion. Shortcut for
363 : : the extend/extendleft methods when maxlen == 0. */
364 : : static PyObject*
365 : 14 : consume_iterator(PyObject *it)
366 : : {
367 : : PyObject *(*iternext)(PyObject *);
368 : : PyObject *item;
369 : :
370 : 14 : iternext = *Py_TYPE(it)->tp_iternext;
371 [ + + ]: 327 : while ((item = iternext(it)) != NULL) {
372 : 313 : Py_DECREF(item);
373 : : }
374 : 14 : return finalize_iterator(it);
375 : : }
376 : :
377 : : static PyObject *
378 : 12033 : deque_extend(dequeobject *deque, PyObject *iterable)
379 : : {
380 : : PyObject *it, *item;
381 : : PyObject *(*iternext)(PyObject *);
382 : 12033 : Py_ssize_t maxlen = deque->maxlen;
383 : :
384 : : /* Handle case where id(deque) == id(iterable) */
385 [ + + ]: 12033 : if ((PyObject *)deque == iterable) {
386 : : PyObject *result;
387 : 2 : PyObject *s = PySequence_List(iterable);
388 [ - + ]: 2 : if (s == NULL)
389 : 0 : return NULL;
390 : 2 : result = deque_extend(deque, s);
391 : 2 : Py_DECREF(s);
392 : 2 : return result;
393 : : }
394 : :
395 : 12031 : it = PyObject_GetIter(iterable);
396 [ + + ]: 12031 : if (it == NULL)
397 : 22 : return NULL;
398 : :
399 [ + + ]: 12009 : if (maxlen == 0)
400 : 13 : return consume_iterator(it);
401 : :
402 : : /* Space saving heuristic. Start filling from the left */
403 [ + + ]: 11996 : if (Py_SIZE(deque) == 0) {
404 : : assert(deque->leftblock == deque->rightblock);
405 : : assert(deque->leftindex == deque->rightindex+1);
406 : 9410 : deque->leftindex = 1;
407 : 9410 : deque->rightindex = 0;
408 : : }
409 : :
410 : 11996 : iternext = *Py_TYPE(it)->tp_iternext;
411 [ + + ]: 265558 : while ((item = iternext(it)) != NULL) {
412 [ - + ]: 253562 : if (deque_append_internal(deque, item, maxlen) == -1) {
413 : 0 : Py_DECREF(item);
414 : 0 : Py_DECREF(it);
415 : 0 : return NULL;
416 : : }
417 : : }
418 : 11996 : return finalize_iterator(it);
419 : : }
420 : :
421 : : PyDoc_STRVAR(extend_doc,
422 : : "Extend the right side of the deque with elements from the iterable");
423 : :
424 : : static PyObject *
425 : 9 : deque_extendleft(dequeobject *deque, PyObject *iterable)
426 : : {
427 : : PyObject *it, *item;
428 : : PyObject *(*iternext)(PyObject *);
429 : 9 : Py_ssize_t maxlen = deque->maxlen;
430 : :
431 : : /* Handle case where id(deque) == id(iterable) */
432 [ + + ]: 9 : if ((PyObject *)deque == iterable) {
433 : : PyObject *result;
434 : 1 : PyObject *s = PySequence_List(iterable);
435 [ - + ]: 1 : if (s == NULL)
436 : 0 : return NULL;
437 : 1 : result = deque_extendleft(deque, s);
438 : 1 : Py_DECREF(s);
439 : 1 : return result;
440 : : }
441 : :
442 : 8 : it = PyObject_GetIter(iterable);
443 [ + + ]: 8 : if (it == NULL)
444 : 1 : return NULL;
445 : :
446 [ + + ]: 7 : if (maxlen == 0)
447 : 1 : return consume_iterator(it);
448 : :
449 : : /* Space saving heuristic. Start filling from the right */
450 [ + + ]: 6 : if (Py_SIZE(deque) == 0) {
451 : : assert(deque->leftblock == deque->rightblock);
452 : : assert(deque->leftindex == deque->rightindex+1);
453 : 2 : deque->leftindex = BLOCKLEN - 1;
454 : 2 : deque->rightindex = BLOCKLEN - 2;
455 : : }
456 : :
457 : 6 : iternext = *Py_TYPE(it)->tp_iternext;
458 [ + + ]: 1018 : while ((item = iternext(it)) != NULL) {
459 [ - + ]: 1012 : if (deque_appendleft_internal(deque, item, maxlen) == -1) {
460 : 0 : Py_DECREF(item);
461 : 0 : Py_DECREF(it);
462 : 0 : return NULL;
463 : : }
464 : : }
465 : 6 : return finalize_iterator(it);
466 : : }
467 : :
468 : : PyDoc_STRVAR(extendleft_doc,
469 : : "Extend the left side of the deque with elements from the iterable");
470 : :
471 : : static PyObject *
472 : 6 : deque_inplace_concat(dequeobject *deque, PyObject *other)
473 : : {
474 : : PyObject *result;
475 : :
476 : 6 : result = deque_extend(deque, other);
477 [ - + ]: 6 : if (result == NULL)
478 : 0 : return result;
479 : 6 : Py_INCREF(deque);
480 : 6 : Py_DECREF(result);
481 : 6 : return (PyObject *)deque;
482 : : }
483 : :
484 : : static PyObject *
485 : 136 : deque_copy(PyObject *deque, PyObject *Py_UNUSED(ignored))
486 : : {
487 : : PyObject *result;
488 : 136 : dequeobject *old_deque = (dequeobject *)deque;
489 [ + + ]: 136 : if (Py_IS_TYPE(deque, &deque_type)) {
490 : : dequeobject *new_deque;
491 : : PyObject *rv;
492 : :
493 : 128 : new_deque = (dequeobject *)deque_new(&deque_type, (PyObject *)NULL, (PyObject *)NULL);
494 [ - + ]: 128 : if (new_deque == NULL)
495 : 0 : return NULL;
496 : 128 : new_deque->maxlen = old_deque->maxlen;
497 : : /* Fast path for the deque_repeat() common case where len(deque) == 1 */
498 [ + + ]: 128 : if (Py_SIZE(deque) == 1) {
499 : 23 : PyObject *item = old_deque->leftblock->data[old_deque->leftindex];
500 : 23 : rv = deque_append(new_deque, item);
501 : : } else {
502 : 105 : rv = deque_extend(new_deque, deque);
503 : : }
504 [ + - ]: 128 : if (rv != NULL) {
505 : 128 : Py_DECREF(rv);
506 : 128 : return (PyObject *)new_deque;
507 : : }
508 : 0 : Py_DECREF(new_deque);
509 : 0 : return NULL;
510 : : }
511 [ + + ]: 8 : if (old_deque->maxlen < 0)
512 : 6 : result = PyObject_CallOneArg((PyObject *)(Py_TYPE(deque)), deque);
513 : : else
514 : 2 : result = PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "Oi",
515 : : deque, old_deque->maxlen, NULL);
516 [ + - + + ]: 8 : if (result != NULL && !PyObject_TypeCheck(result, &deque_type)) {
517 : 2 : PyErr_Format(PyExc_TypeError,
518 : : "%.200s() must return a deque, not %.200s",
519 : 2 : Py_TYPE(deque)->tp_name, Py_TYPE(result)->tp_name);
520 : 2 : Py_DECREF(result);
521 : 2 : return NULL;
522 : : }
523 : 6 : return result;
524 : : }
525 : :
526 : : PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque.");
527 : :
528 : : static PyObject *
529 : 23 : deque_concat(dequeobject *deque, PyObject *other)
530 : : {
531 : : PyObject *new_deque, *result;
532 : : int rv;
533 : :
534 : 23 : rv = PyObject_IsInstance(other, (PyObject *)&deque_type);
535 [ + + ]: 23 : if (rv <= 0) {
536 [ + - ]: 1 : if (rv == 0) {
537 : 1 : PyErr_Format(PyExc_TypeError,
538 : : "can only concatenate deque (not \"%.200s\") to deque",
539 : 1 : Py_TYPE(other)->tp_name);
540 : : }
541 : 1 : return NULL;
542 : : }
543 : :
544 : 22 : new_deque = deque_copy((PyObject *)deque, NULL);
545 [ + + ]: 22 : if (new_deque == NULL)
546 : 1 : return NULL;
547 : 21 : result = deque_extend((dequeobject *)new_deque, other);
548 [ - + ]: 21 : if (result == NULL) {
549 : 0 : Py_DECREF(new_deque);
550 : 0 : return NULL;
551 : : }
552 : 21 : Py_DECREF(result);
553 : 21 : return new_deque;
554 : : }
555 : :
556 : : static int
557 : 53947 : deque_clear(dequeobject *deque)
558 : : {
559 : : block *b;
560 : : block *prevblock;
561 : : block *leftblock;
562 : : Py_ssize_t leftindex;
563 : : Py_ssize_t n, m;
564 : : PyObject *item;
565 : : PyObject **itemptr, **limit;
566 : :
567 [ + + ]: 53947 : if (Py_SIZE(deque) == 0)
568 : 52351 : return 0;
569 : :
570 : : /* During the process of clearing a deque, decrefs can cause the
571 : : deque to mutate. To avoid fatal confusion, we have to make the
572 : : deque empty before clearing the blocks and never refer to
573 : : anything via deque->ref while clearing. (This is the same
574 : : technique used for clearing lists, sets, and dicts.)
575 : :
576 : : Making the deque empty requires allocating a new empty block. In
577 : : the unlikely event that memory is full, we fall back to an
578 : : alternate method that doesn't require a new block. Repeating
579 : : pops in a while-loop is slower, possibly re-entrant (and a clever
580 : : adversary could cause it to never terminate).
581 : : */
582 : :
583 : 1596 : b = newblock(deque);
584 [ - + ]: 1596 : if (b == NULL) {
585 : 0 : PyErr_Clear();
586 : 0 : goto alternate_method;
587 : : }
588 : :
589 : : /* Remember the old size, leftblock, and leftindex */
590 : 1596 : n = Py_SIZE(deque);
591 : 1596 : leftblock = deque->leftblock;
592 : 1596 : leftindex = deque->leftindex;
593 : :
594 : : /* Set the deque to be empty using the newly allocated block */
595 : : MARK_END(b->leftlink);
596 : : MARK_END(b->rightlink);
597 : 1596 : Py_SET_SIZE(deque, 0);
598 : 1596 : deque->leftblock = b;
599 : 1596 : deque->rightblock = b;
600 : 1596 : deque->leftindex = CENTER + 1;
601 : 1596 : deque->rightindex = CENTER;
602 : 1596 : deque->state++;
603 : :
604 : : /* Now the old size, leftblock, and leftindex are disconnected from
605 : : the empty deque and we can use them to decref the pointers.
606 : : */
607 : 1596 : m = (BLOCKLEN - leftindex > n) ? n : BLOCKLEN - leftindex;
608 : 1596 : itemptr = &leftblock->data[leftindex];
609 : 1596 : limit = itemptr + m;
610 : 1596 : n -= m;
611 : : while (1) {
612 [ + + ]: 193840 : if (itemptr == limit) {
613 [ + + ]: 4260 : if (n == 0)
614 : 1596 : break;
615 : : CHECK_NOT_END(leftblock->rightlink);
616 : 2664 : prevblock = leftblock;
617 : 2664 : leftblock = leftblock->rightlink;
618 : 2664 : m = (n > BLOCKLEN) ? BLOCKLEN : n;
619 : 2664 : itemptr = leftblock->data;
620 : 2664 : limit = itemptr + m;
621 : 2664 : n -= m;
622 : 2664 : freeblock(deque, prevblock);
623 : : }
624 : 192244 : item = *(itemptr++);
625 : 192244 : Py_DECREF(item);
626 : : }
627 : : CHECK_END(leftblock->rightlink);
628 : 1596 : freeblock(deque, leftblock);
629 : 1596 : return 0;
630 : :
631 : 0 : alternate_method:
632 [ # # ]: 0 : while (Py_SIZE(deque)) {
633 : 0 : item = deque_pop(deque, NULL);
634 : : assert (item != NULL);
635 : 0 : Py_DECREF(item);
636 : : }
637 : 0 : return 0;
638 : : }
639 : :
640 : : static PyObject *
641 : 3592 : deque_clearmethod(dequeobject *deque, PyObject *Py_UNUSED(ignored))
642 : : {
643 : 3592 : deque_clear(deque);
644 : 3592 : Py_RETURN_NONE;
645 : : }
646 : :
647 : : PyDoc_STRVAR(clear_doc, "Remove all elements from the deque.");
648 : :
649 : : static PyObject *
650 : 115 : deque_inplace_repeat(dequeobject *deque, Py_ssize_t n)
651 : : {
652 : : Py_ssize_t i, m, size;
653 : : PyObject *seq;
654 : : PyObject *rv;
655 : :
656 : 115 : size = Py_SIZE(deque);
657 [ + + + + ]: 115 : if (size == 0 || n == 1) {
658 : 36 : Py_INCREF(deque);
659 : 36 : return (PyObject *)deque;
660 : : }
661 : :
662 [ + + ]: 79 : if (n <= 0) {
663 : 38 : deque_clear(deque);
664 : 38 : Py_INCREF(deque);
665 : 38 : return (PyObject *)deque;
666 : : }
667 : :
668 [ + + ]: 41 : if (size == 1) {
669 : : /* common case, repeating a single element */
670 : 12 : PyObject *item = deque->leftblock->data[deque->leftindex];
671 : :
672 [ + + + + ]: 12 : if (deque->maxlen >= 0 && n > deque->maxlen)
673 : 2 : n = deque->maxlen;
674 : :
675 : 12 : deque->state++;
676 [ + + ]: 67 : for (i = 0 ; i < n-1 ; ) {
677 [ + + ]: 55 : if (deque->rightindex == BLOCKLEN - 1) {
678 : 43 : block *b = newblock(deque);
679 [ - + ]: 43 : if (b == NULL) {
680 : 0 : Py_SET_SIZE(deque, Py_SIZE(deque) + i);
681 : 0 : return NULL;
682 : : }
683 : 43 : b->leftlink = deque->rightblock;
684 : : CHECK_END(deque->rightblock->rightlink);
685 : 43 : deque->rightblock->rightlink = b;
686 : 43 : deque->rightblock = b;
687 : : MARK_END(b->rightlink);
688 : 43 : deque->rightindex = -1;
689 : : }
690 : 55 : m = n - 1 - i;
691 [ + + ]: 55 : if (m > BLOCKLEN - 1 - deque->rightindex)
692 : 43 : m = BLOCKLEN - 1 - deque->rightindex;
693 : 55 : i += m;
694 [ + + ]: 3075 : while (m--) {
695 : 3020 : deque->rightindex++;
696 : 3020 : Py_INCREF(item);
697 : 3020 : deque->rightblock->data[deque->rightindex] = item;
698 : : }
699 : : }
700 : 12 : Py_SET_SIZE(deque, Py_SIZE(deque) + i);
701 : 12 : Py_INCREF(deque);
702 : 12 : return (PyObject *)deque;
703 : : }
704 : :
705 [ - + ]: 29 : if ((size_t)size > PY_SSIZE_T_MAX / (size_t)n) {
706 : : return PyErr_NoMemory();
707 : : }
708 : :
709 : 29 : seq = PySequence_List((PyObject *)deque);
710 [ - + ]: 29 : if (seq == NULL)
711 : 0 : return seq;
712 : :
713 : : /* Reduce the number of repetitions when maxlen would be exceeded */
714 [ + + + + ]: 29 : if (deque->maxlen >= 0 && n * size > deque->maxlen)
715 : 6 : n = (deque->maxlen + size - 1) / size;
716 : :
717 [ + + ]: 1412 : for (i = 0 ; i < n-1 ; i++) {
718 : 1383 : rv = deque_extend(deque, seq);
719 [ - + ]: 1383 : if (rv == NULL) {
720 : 0 : Py_DECREF(seq);
721 : 0 : return NULL;
722 : : }
723 : 1383 : Py_DECREF(rv);
724 : : }
725 : 29 : Py_INCREF(deque);
726 : 29 : Py_DECREF(seq);
727 : 29 : return (PyObject *)deque;
728 : : }
729 : :
730 : : static PyObject *
731 : 73 : deque_repeat(dequeobject *deque, Py_ssize_t n)
732 : : {
733 : : dequeobject *new_deque;
734 : : PyObject *rv;
735 : :
736 : 73 : new_deque = (dequeobject *)deque_copy((PyObject *) deque, NULL);
737 [ + + ]: 73 : if (new_deque == NULL)
738 : 1 : return NULL;
739 : 72 : rv = deque_inplace_repeat(new_deque, n);
740 : 72 : Py_DECREF(new_deque);
741 : 72 : return rv;
742 : : }
743 : :
744 : : /* The rotate() method is part of the public API and is used internally
745 : : as a primitive for other methods.
746 : :
747 : : Rotation by 1 or -1 is a common case, so any optimizations for high
748 : : volume rotations should take care not to penalize the common case.
749 : :
750 : : Conceptually, a rotate by one is equivalent to a pop on one side and an
751 : : append on the other. However, a pop/append pair is unnecessarily slow
752 : : because it requires an incref/decref pair for an object located randomly
753 : : in memory. It is better to just move the object pointer from one block
754 : : to the next without changing the reference count.
755 : :
756 : : When moving batches of pointers, it is tempting to use memcpy() but that
757 : : proved to be slower than a simple loop for a variety of reasons.
758 : : Memcpy() cannot know in advance that we're copying pointers instead of
759 : : bytes, that the source and destination are pointer aligned and
760 : : non-overlapping, that moving just one pointer is a common case, that we
761 : : never need to move more than BLOCKLEN pointers, and that at least one
762 : : pointer is always moved.
763 : :
764 : : For high volume rotations, newblock() and freeblock() are never called
765 : : more than once. Previously emptied blocks are immediately reused as a
766 : : destination block. If a block is left-over at the end, it is freed.
767 : : */
768 : :
769 : : static int
770 : 188181 : _deque_rotate(dequeobject *deque, Py_ssize_t n)
771 : : {
772 : 188181 : block *b = NULL;
773 : 188181 : block *leftblock = deque->leftblock;
774 : 188181 : block *rightblock = deque->rightblock;
775 : 188181 : Py_ssize_t leftindex = deque->leftindex;
776 : 188181 : Py_ssize_t rightindex = deque->rightindex;
777 : 188181 : Py_ssize_t len=Py_SIZE(deque), halflen=len>>1;
778 : 188181 : int rv = -1;
779 : :
780 [ + + ]: 188181 : if (len <= 1)
781 : 53812 : return 0;
782 [ + + + + ]: 134369 : if (n > halflen || n < -halflen) {
783 : 584 : n %= len;
784 [ + + ]: 584 : if (n > halflen)
785 : 267 : n -= len;
786 [ + + ]: 317 : else if (n < -halflen)
787 : 275 : n += len;
788 : : }
789 : : assert(len > 1);
790 : : assert(-halflen <= n && n <= halflen);
791 : :
792 : 134369 : deque->state++;
793 [ + + ]: 236136 : while (n > 0) {
794 [ + + ]: 101767 : if (leftindex == 0) {
795 [ + + ]: 2075 : if (b == NULL) {
796 : 1763 : b = newblock(deque);
797 [ - + ]: 1763 : if (b == NULL)
798 : 0 : goto done;
799 : : }
800 : 2075 : b->rightlink = leftblock;
801 : : CHECK_END(leftblock->leftlink);
802 : 2075 : leftblock->leftlink = b;
803 : 2075 : leftblock = b;
804 : : MARK_END(b->leftlink);
805 : 2075 : leftindex = BLOCKLEN;
806 : 2075 : b = NULL;
807 : : }
808 : : assert(leftindex > 0);
809 : : {
810 : : PyObject **src, **dest;
811 : 101767 : Py_ssize_t m = n;
812 : :
813 [ + + ]: 101767 : if (m > rightindex + 1)
814 : 780 : m = rightindex + 1;
815 [ + + ]: 101767 : if (m > leftindex)
816 : 488 : m = leftindex;
817 : : assert (m > 0 && m <= len);
818 : 101767 : rightindex -= m;
819 : 101767 : leftindex -= m;
820 : 101767 : src = &rightblock->data[rightindex + 1];
821 : 101767 : dest = &leftblock->data[leftindex];
822 : 101767 : n -= m;
823 : : do {
824 : 131841 : *(dest++) = *(src++);
825 [ + + ]: 131841 : } while (--m);
826 : : }
827 [ + + ]: 101767 : if (rightindex < 0) {
828 : : assert(leftblock != rightblock);
829 : : assert(b == NULL);
830 : 2071 : b = rightblock;
831 : : CHECK_NOT_END(rightblock->leftlink);
832 : 2071 : rightblock = rightblock->leftlink;
833 : : MARK_END(rightblock->rightlink);
834 : 2071 : rightindex = BLOCKLEN - 1;
835 : : }
836 : : }
837 [ + + ]: 136029 : while (n < 0) {
838 [ + + ]: 1660 : if (rightindex == BLOCKLEN - 1) {
839 [ + + ]: 499 : if (b == NULL) {
840 : 191 : b = newblock(deque);
841 [ - + ]: 191 : if (b == NULL)
842 : 0 : goto done;
843 : : }
844 : 499 : b->leftlink = rightblock;
845 : : CHECK_END(rightblock->rightlink);
846 : 499 : rightblock->rightlink = b;
847 : 499 : rightblock = b;
848 : : MARK_END(b->rightlink);
849 : 499 : rightindex = -1;
850 : 499 : b = NULL;
851 : : }
852 : : assert (rightindex < BLOCKLEN - 1);
853 : : {
854 : : PyObject **src, **dest;
855 : 1660 : Py_ssize_t m = -n;
856 : :
857 [ + + ]: 1660 : if (m > BLOCKLEN - leftindex)
858 : 791 : m = BLOCKLEN - leftindex;
859 [ + + ]: 1660 : if (m > BLOCKLEN - 1 - rightindex)
860 : 483 : m = BLOCKLEN - 1 - rightindex;
861 : : assert (m > 0 && m <= len);
862 : 1660 : src = &leftblock->data[leftindex];
863 : 1660 : dest = &rightblock->data[rightindex + 1];
864 : 1660 : leftindex += m;
865 : 1660 : rightindex += m;
866 : 1660 : n += m;
867 : : do {
868 : 31669 : *(dest++) = *(src++);
869 [ + + ]: 31669 : } while (--m);
870 : : }
871 [ + + ]: 1660 : if (leftindex == BLOCKLEN) {
872 : : assert(leftblock != rightblock);
873 : : assert(b == NULL);
874 : 495 : b = leftblock;
875 : : CHECK_NOT_END(leftblock->rightlink);
876 : 495 : leftblock = leftblock->rightlink;
877 : : MARK_END(leftblock->leftlink);
878 : 495 : leftindex = 0;
879 : : }
880 : : }
881 : 134369 : rv = 0;
882 : 134369 : done:
883 [ + + ]: 134369 : if (b != NULL)
884 : 1946 : freeblock(deque, b);
885 : 134369 : deque->leftblock = leftblock;
886 : 134369 : deque->rightblock = rightblock;
887 : 134369 : deque->leftindex = leftindex;
888 : 134369 : deque->rightindex = rightindex;
889 : :
890 : 134369 : return rv;
891 : : }
892 : :
893 : : static PyObject *
894 : 100445 : deque_rotate(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs)
895 : : {
896 : 100445 : Py_ssize_t n=1;
897 : :
898 [ + - + + : 100445 : if (!_PyArg_CheckPositional("deque.rotate", nargs, 0, 1)) {
+ - ]
899 : 1 : return NULL;
900 : : }
901 [ + + ]: 100444 : if (nargs) {
902 : 325 : PyObject *index = _PyNumber_Index(args[0]);
903 [ + + ]: 325 : if (index == NULL) {
904 : 1 : return NULL;
905 : : }
906 : 324 : n = PyLong_AsSsize_t(index);
907 : 324 : Py_DECREF(index);
908 [ + + - + ]: 324 : if (n == -1 && PyErr_Occurred()) {
909 : 0 : return NULL;
910 : : }
911 : : }
912 : :
913 [ + - ]: 100443 : if (!_deque_rotate(deque, n))
914 : 100443 : Py_RETURN_NONE;
915 : 0 : return NULL;
916 : : }
917 : :
918 : : PyDoc_STRVAR(rotate_doc,
919 : : "Rotate the deque n steps to the right (default n=1). If n is negative, rotates left.");
920 : :
921 : : static PyObject *
922 : 1000 : deque_reverse(dequeobject *deque, PyObject *unused)
923 : : {
924 : 1000 : block *leftblock = deque->leftblock;
925 : 1000 : block *rightblock = deque->rightblock;
926 : 1000 : Py_ssize_t leftindex = deque->leftindex;
927 : 1000 : Py_ssize_t rightindex = deque->rightindex;
928 : 1000 : Py_ssize_t n = Py_SIZE(deque) >> 1;
929 : : PyObject *tmp;
930 : :
931 [ + + ]: 125500 : while (--n >= 0) {
932 : : /* Validate that pointers haven't met in the middle */
933 : : assert(leftblock != rightblock || leftindex < rightindex);
934 : : CHECK_NOT_END(leftblock);
935 : : CHECK_NOT_END(rightblock);
936 : :
937 : : /* Swap */
938 : 124500 : tmp = leftblock->data[leftindex];
939 : 124500 : leftblock->data[leftindex] = rightblock->data[rightindex];
940 : 124500 : rightblock->data[rightindex] = tmp;
941 : :
942 : : /* Advance left block/index pair */
943 : 124500 : leftindex++;
944 [ + + ]: 124500 : if (leftindex == BLOCKLEN) {
945 : 1476 : leftblock = leftblock->rightlink;
946 : 1476 : leftindex = 0;
947 : : }
948 : :
949 : : /* Step backwards with the right block/index pair */
950 : 124500 : rightindex--;
951 [ + + ]: 124500 : if (rightindex < 0) {
952 : 1946 : rightblock = rightblock->leftlink;
953 : 1946 : rightindex = BLOCKLEN - 1;
954 : : }
955 : : }
956 : 1000 : Py_RETURN_NONE;
957 : : }
958 : :
959 : : PyDoc_STRVAR(reverse_doc,
960 : : "D.reverse() -- reverse *IN PLACE*");
961 : :
962 : : static PyObject *
963 : 93 : deque_count(dequeobject *deque, PyObject *v)
964 : : {
965 : 93 : block *b = deque->leftblock;
966 : 93 : Py_ssize_t index = deque->leftindex;
967 : 93 : Py_ssize_t n = Py_SIZE(deque);
968 : 93 : Py_ssize_t count = 0;
969 : 93 : size_t start_state = deque->state;
970 : : PyObject *item;
971 : : int cmp;
972 : :
973 [ + + ]: 130544 : while (--n >= 0) {
974 : : CHECK_NOT_END(b);
975 : 130456 : item = b->data[index];
976 : 130456 : Py_INCREF(item);
977 : 130456 : cmp = PyObject_RichCompareBool(item, v, Py_EQ);
978 : 130456 : Py_DECREF(item);
979 [ + + ]: 130456 : if (cmp < 0)
980 : 3 : return NULL;
981 : 130453 : count += cmp;
982 : :
983 [ + + ]: 130453 : if (start_state != deque->state) {
984 : 2 : PyErr_SetString(PyExc_RuntimeError,
985 : : "deque mutated during iteration");
986 : 2 : return NULL;
987 : : }
988 : :
989 : : /* Advance left block/index pair */
990 : 130451 : index++;
991 [ + + ]: 130451 : if (index == BLOCKLEN) {
992 : 2028 : b = b->rightlink;
993 : 2028 : index = 0;
994 : : }
995 : : }
996 : 88 : return PyLong_FromSsize_t(count);
997 : : }
998 : :
999 : : PyDoc_STRVAR(count_doc,
1000 : : "D.count(value) -> integer -- return number of occurrences of value");
1001 : :
1002 : : static int
1003 : 1226 : deque_contains(dequeobject *deque, PyObject *v)
1004 : : {
1005 : 1226 : block *b = deque->leftblock;
1006 : 1226 : Py_ssize_t index = deque->leftindex;
1007 : 1226 : Py_ssize_t n = Py_SIZE(deque);
1008 : 1226 : size_t start_state = deque->state;
1009 : : PyObject *item;
1010 : : int cmp;
1011 : :
1012 [ + + ]: 206609 : while (--n >= 0) {
1013 : : CHECK_NOT_END(b);
1014 : 206102 : item = b->data[index];
1015 : 206102 : Py_INCREF(item);
1016 : 206102 : cmp = PyObject_RichCompareBool(item, v, Py_EQ);
1017 : 206102 : Py_DECREF(item);
1018 [ + + ]: 206102 : if (cmp) {
1019 : 717 : return cmp;
1020 : : }
1021 [ + + ]: 205385 : if (start_state != deque->state) {
1022 : 2 : PyErr_SetString(PyExc_RuntimeError,
1023 : : "deque mutated during iteration");
1024 : 2 : return -1;
1025 : : }
1026 : 205383 : index++;
1027 [ + + ]: 205383 : if (index == BLOCKLEN) {
1028 : 3108 : b = b->rightlink;
1029 : 3108 : index = 0;
1030 : : }
1031 : : }
1032 : 507 : return 0;
1033 : : }
1034 : :
1035 : : static Py_ssize_t
1036 : 473925 : deque_len(dequeobject *deque)
1037 : : {
1038 : 473925 : return Py_SIZE(deque);
1039 : : }
1040 : :
1041 : : static PyObject *
1042 : 67655 : deque_index(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs)
1043 : : {
1044 : 67655 : Py_ssize_t i, n, start=0, stop=Py_SIZE(deque);
1045 : : PyObject *v, *item;
1046 : 67655 : block *b = deque->leftblock;
1047 : 67655 : Py_ssize_t index = deque->leftindex;
1048 : 67655 : size_t start_state = deque->state;
1049 : : int cmp;
1050 : :
1051 [ + + ]: 67655 : if (!_PyArg_ParseStack(args, nargs, "O|O&O&:index", &v,
1052 : : _PyEval_SliceIndexNotNone, &start,
1053 : : _PyEval_SliceIndexNotNone, &stop)) {
1054 : 1 : return NULL;
1055 : : }
1056 : :
1057 [ + + ]: 67654 : if (start < 0) {
1058 : 33626 : start += Py_SIZE(deque);
1059 [ + + ]: 33626 : if (start < 0)
1060 : 18863 : start = 0;
1061 : : }
1062 [ + + ]: 67654 : if (stop < 0) {
1063 : 33624 : stop += Py_SIZE(deque);
1064 [ + + ]: 33624 : if (stop < 0)
1065 : 18863 : stop = 0;
1066 : : }
1067 [ + + ]: 67654 : if (stop > Py_SIZE(deque))
1068 : 18042 : stop = Py_SIZE(deque);
1069 [ + + ]: 67654 : if (start > stop)
1070 : 32571 : start = stop;
1071 : : assert(0 <= start && start <= stop && stop <= Py_SIZE(deque));
1072 : :
1073 [ + + ]: 68654 : for (i=0 ; i < start - BLOCKLEN ; i += BLOCKLEN) {
1074 : 1000 : b = b->rightlink;
1075 : : }
1076 [ + + ]: 381058 : for ( ; i < start ; i++) {
1077 : 313404 : index++;
1078 [ + + ]: 313404 : if (index == BLOCKLEN) {
1079 : 94 : b = b->rightlink;
1080 : 94 : index = 0;
1081 : : }
1082 : : }
1083 : :
1084 : 67654 : n = stop - i;
1085 [ + + ]: 223683 : while (--n >= 0) {
1086 : : CHECK_NOT_END(b);
1087 : 175767 : item = b->data[index];
1088 : 175767 : cmp = PyObject_RichCompareBool(item, v, Py_EQ);
1089 [ + + ]: 175767 : if (cmp > 0)
1090 : 19727 : return PyLong_FromSsize_t(stop - n - 1);
1091 [ + + ]: 156040 : if (cmp < 0)
1092 : 6 : return NULL;
1093 [ + + ]: 156034 : if (start_state != deque->state) {
1094 : 5 : PyErr_SetString(PyExc_RuntimeError,
1095 : : "deque mutated during iteration");
1096 : 5 : return NULL;
1097 : : }
1098 : 156029 : index++;
1099 [ + + ]: 156029 : if (index == BLOCKLEN) {
1100 : 562 : b = b->rightlink;
1101 : 562 : index = 0;
1102 : : }
1103 : : }
1104 : 47916 : PyErr_Format(PyExc_ValueError, "%R is not in deque", v);
1105 : 47916 : return NULL;
1106 : : }
1107 : :
1108 : : PyDoc_STRVAR(index_doc,
1109 : : "D.index(value, [start, [stop]]) -> integer -- return first index of value.\n"
1110 : : "Raises ValueError if the value is not present.");
1111 : :
1112 : : /* insert(), remove(), and delitem() are implemented in terms of
1113 : : rotate() for simplicity and reasonable performance near the end
1114 : : points. If for some reason these methods become popular, it is not
1115 : : hard to re-implement this using direct data movement (similar to
1116 : : the code used in list slice assignments) and achieve a performance
1117 : : boost (by moving each pointer only once instead of twice).
1118 : : */
1119 : :
1120 : : static PyObject *
1121 : 65 : deque_insert(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs)
1122 : : {
1123 : : Py_ssize_t index;
1124 : 65 : Py_ssize_t n = Py_SIZE(deque);
1125 : : PyObject *value;
1126 : : PyObject *rv;
1127 : :
1128 [ - + ]: 65 : if (!_PyArg_ParseStack(args, nargs, "nO:insert", &index, &value)) {
1129 : 0 : return NULL;
1130 : : }
1131 : :
1132 [ + + ]: 65 : if (deque->maxlen == Py_SIZE(deque)) {
1133 : 1 : PyErr_SetString(PyExc_IndexError, "deque already at its maximum size");
1134 : 1 : return NULL;
1135 : : }
1136 [ + + ]: 64 : if (index >= n)
1137 : 14 : return deque_append(deque, value);
1138 [ + + + + ]: 50 : if (index <= -n || index == 0)
1139 : 18 : return deque_appendleft(deque, value);
1140 [ - + ]: 32 : if (_deque_rotate(deque, -index))
1141 : 0 : return NULL;
1142 [ + + ]: 32 : if (index < 0)
1143 : 16 : rv = deque_append(deque, value);
1144 : : else
1145 : 16 : rv = deque_appendleft(deque, value);
1146 [ - + ]: 32 : if (rv == NULL)
1147 : 0 : return NULL;
1148 : 32 : Py_DECREF(rv);
1149 [ - + ]: 32 : if (_deque_rotate(deque, index))
1150 : 0 : return NULL;
1151 : 32 : Py_RETURN_NONE;
1152 : : }
1153 : :
1154 : : PyDoc_STRVAR(insert_doc,
1155 : : "D.insert(index, object) -- insert object before index");
1156 : :
1157 : : PyDoc_STRVAR(remove_doc,
1158 : : "D.remove(value) -- remove first occurrence of value.");
1159 : :
1160 : : static int
1161 : 1356858 : valid_index(Py_ssize_t i, Py_ssize_t limit)
1162 : : {
1163 : : /* The cast to size_t lets us use just a single comparison
1164 : : to check whether i is in the range: 0 <= i < limit */
1165 : 1356858 : return (size_t) i < (size_t) limit;
1166 : : }
1167 : :
1168 : : static PyObject *
1169 : 106588 : deque_item(dequeobject *deque, Py_ssize_t i)
1170 : : {
1171 : : block *b;
1172 : : PyObject *item;
1173 : 106588 : Py_ssize_t n, index=i;
1174 : :
1175 [ + + ]: 106588 : if (!valid_index(i, Py_SIZE(deque))) {
1176 : 3 : PyErr_SetString(PyExc_IndexError, "deque index out of range");
1177 : 3 : return NULL;
1178 : : }
1179 : :
1180 [ + + ]: 106585 : if (i == 0) {
1181 : 42306 : i = deque->leftindex;
1182 : 42306 : b = deque->leftblock;
1183 [ + + ]: 64279 : } else if (i == Py_SIZE(deque) - 1) {
1184 : 443 : i = deque->rightindex;
1185 : 443 : b = deque->rightblock;
1186 : : } else {
1187 : 63836 : i += deque->leftindex;
1188 : 63836 : n = (Py_ssize_t)((size_t) i / BLOCKLEN);
1189 : 63836 : i = (Py_ssize_t)((size_t) i % BLOCKLEN);
1190 [ + + ]: 63836 : if (index < (Py_SIZE(deque) >> 1)) {
1191 : 31770 : b = deque->leftblock;
1192 [ + + ]: 51400 : while (--n >= 0)
1193 : 19630 : b = b->rightlink;
1194 : : } else {
1195 : 32066 : n = (Py_ssize_t)(
1196 : 32066 : ((size_t)(deque->leftindex + Py_SIZE(deque) - 1))
1197 : 32066 : / BLOCKLEN - n);
1198 : 32066 : b = deque->rightblock;
1199 [ + + ]: 51725 : while (--n >= 0)
1200 : 19659 : b = b->leftlink;
1201 : : }
1202 : : }
1203 : 106585 : item = b->data[i];
1204 : 106585 : Py_INCREF(item);
1205 : 106585 : return item;
1206 : : }
1207 : :
1208 : : static int
1209 : 43837 : deque_del_item(dequeobject *deque, Py_ssize_t i)
1210 : : {
1211 : : PyObject *item;
1212 : : int rv;
1213 : :
1214 : : assert (i >= 0 && i < Py_SIZE(deque));
1215 [ - + ]: 43837 : if (_deque_rotate(deque, -i))
1216 : 0 : return -1;
1217 : 43837 : item = deque_popleft(deque, NULL);
1218 : 43837 : rv = _deque_rotate(deque, i);
1219 : : assert (item != NULL);
1220 : 43837 : Py_DECREF(item);
1221 : 43837 : return rv;
1222 : : }
1223 : :
1224 : : static PyObject *
1225 : 40315 : deque_remove(dequeobject *deque, PyObject *value)
1226 : : {
1227 : : PyObject *item;
1228 : 40315 : block *b = deque->leftblock;
1229 : 40315 : Py_ssize_t i, n = Py_SIZE(deque), index = deque->leftindex;
1230 : 40315 : size_t start_state = deque->state;
1231 : : int cmp, rv;
1232 : :
1233 [ + + ]: 40351 : for (i = 0 ; i < n; i++) {
1234 : 40342 : item = b->data[index];
1235 : 40342 : Py_INCREF(item);
1236 : 40342 : cmp = PyObject_RichCompareBool(item, value, Py_EQ);
1237 : 40342 : Py_DECREF(item);
1238 [ + + ]: 40342 : if (cmp < 0) {
1239 : 1 : return NULL;
1240 : : }
1241 [ + + ]: 40341 : if (start_state != deque->state) {
1242 : 2 : PyErr_SetString(PyExc_IndexError,
1243 : : "deque mutated during iteration");
1244 : 2 : return NULL;
1245 : : }
1246 [ + + ]: 40339 : if (cmp > 0) {
1247 : 40303 : break;
1248 : : }
1249 : 36 : index++;
1250 [ - + ]: 36 : if (index == BLOCKLEN) {
1251 : 0 : b = b->rightlink;
1252 : 0 : index = 0;
1253 : : }
1254 : : }
1255 [ + + ]: 40312 : if (i == n) {
1256 : 9 : PyErr_Format(PyExc_ValueError, "%R is not in deque", value);
1257 : 9 : return NULL;
1258 : : }
1259 : 40303 : rv = deque_del_item(deque, i);
1260 [ - + ]: 40303 : if (rv == -1) {
1261 : 0 : return NULL;
1262 : : }
1263 : 40303 : Py_RETURN_NONE;
1264 : : }
1265 : :
1266 : : static int
1267 : 8548 : deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v)
1268 : : {
1269 : : PyObject *old_value;
1270 : : block *b;
1271 : 8548 : Py_ssize_t n, len=Py_SIZE(deque), halflen=(len+1)>>1, index=i;
1272 : :
1273 [ + + ]: 8548 : if (!valid_index(i, len)) {
1274 : 2 : PyErr_SetString(PyExc_IndexError, "deque index out of range");
1275 : 2 : return -1;
1276 : : }
1277 [ + + ]: 8546 : if (v == NULL)
1278 : 3534 : return deque_del_item(deque, i);
1279 : :
1280 : 5012 : i += deque->leftindex;
1281 : 5012 : n = (Py_ssize_t)((size_t) i / BLOCKLEN);
1282 : 5012 : i = (Py_ssize_t)((size_t) i % BLOCKLEN);
1283 [ + + ]: 5012 : if (index <= halflen) {
1284 : 2537 : b = deque->leftblock;
1285 [ + + ]: 3491 : while (--n >= 0)
1286 : 954 : b = b->rightlink;
1287 : : } else {
1288 : 2475 : n = (Py_ssize_t)(
1289 : 2475 : ((size_t)(deque->leftindex + Py_SIZE(deque) - 1))
1290 : 2475 : / BLOCKLEN - n);
1291 : 2475 : b = deque->rightblock;
1292 [ + + ]: 5375 : while (--n >= 0)
1293 : 2900 : b = b->leftlink;
1294 : : }
1295 : 5012 : Py_INCREF(v);
1296 : 5012 : old_value = b->data[i];
1297 : 5012 : b->data[i] = v;
1298 : 5012 : Py_DECREF(old_value);
1299 : 5012 : return 0;
1300 : : }
1301 : :
1302 : : static void
1303 : 50259 : deque_dealloc(dequeobject *deque)
1304 : : {
1305 : : Py_ssize_t i;
1306 : :
1307 : 50259 : PyObject_GC_UnTrack(deque);
1308 [ + + ]: 50259 : if (deque->weakreflist != NULL)
1309 : 1 : PyObject_ClearWeakRefs((PyObject *) deque);
1310 [ + - ]: 50259 : if (deque->leftblock != NULL) {
1311 : 50259 : deque_clear(deque);
1312 : : assert(deque->leftblock != NULL);
1313 : 50259 : freeblock(deque, deque->leftblock);
1314 : : }
1315 : 50259 : deque->leftblock = NULL;
1316 : 50259 : deque->rightblock = NULL;
1317 [ + + ]: 105044 : for (i=0 ; i < deque->numfreeblocks ; i++) {
1318 : 54785 : PyMem_Free(deque->freeblocks[i]);
1319 : : }
1320 : 50259 : Py_TYPE(deque)->tp_free(deque);
1321 : 50259 : }
1322 : :
1323 : : static int
1324 : 202095 : deque_traverse(dequeobject *deque, visitproc visit, void *arg)
1325 : : {
1326 : : block *b;
1327 : : PyObject *item;
1328 : : Py_ssize_t index;
1329 : 202095 : Py_ssize_t indexlo = deque->leftindex;
1330 : : Py_ssize_t indexhigh;
1331 : :
1332 [ + + ]: 202445 : for (b = deque->leftblock; b != deque->rightblock; b = b->rightlink) {
1333 [ + + ]: 17162 : for (index = indexlo; index < BLOCKLEN ; index++) {
1334 : 16812 : item = b->data[index];
1335 [ + - - + ]: 16812 : Py_VISIT(item);
1336 : : }
1337 : 350 : indexlo = 0;
1338 : : }
1339 : 202095 : indexhigh = deque->rightindex;
1340 [ + + ]: 212012 : for (index = indexlo; index <= indexhigh; index++) {
1341 : 9917 : item = b->data[index];
1342 [ + - - + ]: 9917 : Py_VISIT(item);
1343 : : }
1344 : 202095 : return 0;
1345 : : }
1346 : :
1347 : : static PyObject *
1348 : 115 : deque_reduce(dequeobject *deque, PyObject *Py_UNUSED(ignored))
1349 : : {
1350 : : PyObject *state, *it;
1351 : :
1352 : 115 : state = _PyObject_GetState((PyObject *)deque);
1353 [ - + ]: 115 : if (state == NULL) {
1354 : 0 : return NULL;
1355 : : }
1356 : :
1357 : 115 : it = PyObject_GetIter((PyObject *)deque);
1358 [ + + ]: 115 : if (it == NULL) {
1359 : 12 : Py_DECREF(state);
1360 : 12 : return NULL;
1361 : : }
1362 : :
1363 [ + + ]: 103 : if (deque->maxlen < 0) {
1364 : 67 : return Py_BuildValue("O()NN", Py_TYPE(deque), state, it);
1365 : : }
1366 : : else {
1367 : 36 : return Py_BuildValue("O(()n)NN", Py_TYPE(deque), deque->maxlen, state, it);
1368 : : }
1369 : : }
1370 : :
1371 : : PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
1372 : :
1373 : : static PyObject *
1374 : 34 : deque_repr(PyObject *deque)
1375 : : {
1376 : : PyObject *aslist, *result;
1377 : : int i;
1378 : :
1379 : 34 : i = Py_ReprEnter(deque);
1380 [ + + ]: 34 : if (i != 0) {
1381 [ - + ]: 2 : if (i < 0)
1382 : 0 : return NULL;
1383 : 2 : return PyUnicode_FromString("[...]");
1384 : : }
1385 : :
1386 : 32 : aslist = PySequence_List(deque);
1387 [ - + ]: 32 : if (aslist == NULL) {
1388 : 0 : Py_ReprLeave(deque);
1389 : 0 : return NULL;
1390 : : }
1391 [ + + ]: 32 : if (((dequeobject *)deque)->maxlen >= 0)
1392 : 11 : result = PyUnicode_FromFormat("%s(%R, maxlen=%zd)",
1393 : : _PyType_Name(Py_TYPE(deque)), aslist,
1394 : : ((dequeobject *)deque)->maxlen);
1395 : : else
1396 : 21 : result = PyUnicode_FromFormat("%s(%R)",
1397 : : _PyType_Name(Py_TYPE(deque)), aslist);
1398 : 32 : Py_ReprLeave(deque);
1399 : 32 : Py_DECREF(aslist);
1400 : 32 : return result;
1401 : : }
1402 : :
1403 : : static PyObject *
1404 : 286 : deque_richcompare(PyObject *v, PyObject *w, int op)
1405 : : {
1406 : 286 : PyObject *it1=NULL, *it2=NULL, *x, *y;
1407 : : Py_ssize_t vs, ws;
1408 : 286 : int b, cmp=-1;
1409 : :
1410 [ + - + + ]: 572 : if (!PyObject_TypeCheck(v, &deque_type) ||
1411 : 286 : !PyObject_TypeCheck(w, &deque_type)) {
1412 : 2 : Py_RETURN_NOTIMPLEMENTED;
1413 : : }
1414 : :
1415 : : /* Shortcuts */
1416 : 284 : vs = Py_SIZE((dequeobject *)v);
1417 : 284 : ws = Py_SIZE((dequeobject *)w);
1418 [ + + ]: 284 : if (op == Py_EQ) {
1419 [ + + ]: 240 : if (v == w)
1420 : 2 : Py_RETURN_TRUE;
1421 [ + + ]: 238 : if (vs != ws)
1422 : 10 : Py_RETURN_FALSE;
1423 : : }
1424 [ + + ]: 272 : if (op == Py_NE) {
1425 [ + + ]: 12 : if (v == w)
1426 : 1 : Py_RETURN_FALSE;
1427 [ + + ]: 11 : if (vs != ws)
1428 : 10 : Py_RETURN_TRUE;
1429 : : }
1430 : :
1431 : : /* Search for the first index where items are different */
1432 : 261 : it1 = PyObject_GetIter(v);
1433 [ - + ]: 261 : if (it1 == NULL)
1434 : 0 : goto done;
1435 : 261 : it2 = PyObject_GetIter(w);
1436 [ + - ]: 261 : if (it2 == NULL)
1437 : 0 : goto done;
1438 : : for (;;) {
1439 : 17034 : x = PyIter_Next(it1);
1440 [ + + - + ]: 17034 : if (x == NULL && PyErr_Occurred())
1441 : 0 : goto done;
1442 : 17034 : y = PyIter_Next(it2);
1443 [ + + + - ]: 17034 : if (x == NULL || y == NULL)
1444 : : break;
1445 : 16773 : b = PyObject_RichCompareBool(x, y, Py_EQ);
1446 [ - + ]: 16773 : if (b == 0) {
1447 : 0 : cmp = PyObject_RichCompareBool(x, y, op);
1448 : 0 : Py_DECREF(x);
1449 : 0 : Py_DECREF(y);
1450 : 0 : goto done;
1451 : : }
1452 : 16773 : Py_DECREF(x);
1453 : 16773 : Py_DECREF(y);
1454 [ - + ]: 16773 : if (b < 0)
1455 : 0 : goto done;
1456 : : }
1457 : : /* We reached the end of one deque or both */
1458 : 261 : Py_XDECREF(x);
1459 : 261 : Py_XDECREF(y);
1460 [ - + ]: 261 : if (PyErr_Occurred())
1461 : 0 : goto done;
1462 [ + + + + : 261 : switch (op) {
+ + - ]
1463 : 8 : case Py_LT: cmp = y != NULL; break; /* if w was longer */
1464 : 8 : case Py_LE: cmp = x == NULL; break; /* if v was not longer */
1465 : 228 : case Py_EQ: cmp = x == y; break; /* if we reached the end of both */
1466 : 1 : case Py_NE: cmp = x != y; break; /* if one deque continues */
1467 : 8 : case Py_GT: cmp = x != NULL; break; /* if v was longer */
1468 : 8 : case Py_GE: cmp = y == NULL; break; /* if w was not longer */
1469 : : }
1470 : :
1471 : 261 : done:
1472 : 261 : Py_XDECREF(it1);
1473 : 261 : Py_XDECREF(it2);
1474 [ + + ]: 261 : if (cmp == 1)
1475 : 244 : Py_RETURN_TRUE;
1476 [ + - ]: 17 : if (cmp == 0)
1477 : 17 : Py_RETURN_FALSE;
1478 : 0 : return NULL;
1479 : : }
1480 : :
1481 : : static int
1482 : 50323 : deque_init(dequeobject *deque, PyObject *args, PyObject *kwdargs)
1483 : : {
1484 : 50323 : PyObject *iterable = NULL;
1485 : 50323 : PyObject *maxlenobj = NULL;
1486 : 50323 : Py_ssize_t maxlen = -1;
1487 : 50323 : char *kwlist[] = {"iterable", "maxlen", 0};
1488 : :
1489 [ + + + - ]: 50323 : if (kwdargs == NULL && PyTuple_GET_SIZE(args) <= 2) {
1490 [ + + ]: 48929 : if (PyTuple_GET_SIZE(args) > 0) {
1491 : 1277 : iterable = PyTuple_GET_ITEM(args, 0);
1492 : : }
1493 [ + + ]: 48929 : if (PyTuple_GET_SIZE(args) > 1) {
1494 : 103 : maxlenobj = PyTuple_GET_ITEM(args, 1);
1495 : : }
1496 : : } else {
1497 [ + + ]: 1394 : if (!PyArg_ParseTupleAndKeywords(args, kwdargs, "|OO:deque", kwlist,
1498 : : &iterable, &maxlenobj))
1499 : 2 : return -1;
1500 : : }
1501 [ + + + + ]: 50321 : if (maxlenobj != NULL && maxlenobj != Py_None) {
1502 : 1460 : maxlen = PyLong_AsSsize_t(maxlenobj);
1503 [ + + - + ]: 1460 : if (maxlen == -1 && PyErr_Occurred())
1504 : 0 : return -1;
1505 [ + + ]: 1460 : if (maxlen < 0) {
1506 : 2 : PyErr_SetString(PyExc_ValueError, "maxlen must be non-negative");
1507 : 2 : return -1;
1508 : : }
1509 : : }
1510 : 50319 : deque->maxlen = maxlen;
1511 [ + + ]: 50319 : if (Py_SIZE(deque) > 0)
1512 : 2 : deque_clear(deque);
1513 [ + + ]: 50319 : if (iterable != NULL) {
1514 : 2659 : PyObject *rv = deque_extend(deque, iterable);
1515 [ + + ]: 2659 : if (rv == NULL)
1516 : 31 : return -1;
1517 : 2628 : Py_DECREF(rv);
1518 : : }
1519 : 50288 : return 0;
1520 : : }
1521 : :
1522 : : static PyObject *
1523 : 5 : deque_sizeof(dequeobject *deque, void *unused)
1524 : : {
1525 : : Py_ssize_t res;
1526 : : Py_ssize_t blocks;
1527 : :
1528 : 5 : res = _PyObject_SIZE(Py_TYPE(deque));
1529 : 5 : blocks = (size_t)(deque->leftindex + Py_SIZE(deque) + BLOCKLEN - 1) / BLOCKLEN;
1530 : : assert(deque->leftindex + Py_SIZE(deque) - 1 ==
1531 : : (blocks - 1) * BLOCKLEN + deque->rightindex);
1532 : 5 : res += blocks * sizeof(block);
1533 : 5 : return PyLong_FromSsize_t(res);
1534 : : }
1535 : :
1536 : : PyDoc_STRVAR(sizeof_doc,
1537 : : "D.__sizeof__() -- size of D in memory, in bytes");
1538 : :
1539 : : static PyObject *
1540 : 197 : deque_get_maxlen(dequeobject *deque, void *Py_UNUSED(ignored))
1541 : : {
1542 [ + + ]: 197 : if (deque->maxlen < 0)
1543 : 72 : Py_RETURN_NONE;
1544 : 125 : return PyLong_FromSsize_t(deque->maxlen);
1545 : : }
1546 : :
1547 : :
1548 : : /* deque object ********************************************************/
1549 : :
1550 : : static PyGetSetDef deque_getset[] = {
1551 : : {"maxlen", (getter)deque_get_maxlen, (setter)NULL,
1552 : : "maximum size of a deque or None if unbounded"},
1553 : : {0}
1554 : : };
1555 : :
1556 : : static PySequenceMethods deque_as_sequence = {
1557 : : (lenfunc)deque_len, /* sq_length */
1558 : : (binaryfunc)deque_concat, /* sq_concat */
1559 : : (ssizeargfunc)deque_repeat, /* sq_repeat */
1560 : : (ssizeargfunc)deque_item, /* sq_item */
1561 : : 0, /* sq_slice */
1562 : : (ssizeobjargproc)deque_ass_item, /* sq_ass_item */
1563 : : 0, /* sq_ass_slice */
1564 : : (objobjproc)deque_contains, /* sq_contains */
1565 : : (binaryfunc)deque_inplace_concat, /* sq_inplace_concat */
1566 : : (ssizeargfunc)deque_inplace_repeat, /* sq_inplace_repeat */
1567 : : };
1568 : :
1569 : : static PyObject *deque_iter(dequeobject *deque);
1570 : : static PyObject *deque_reviter(dequeobject *deque, PyObject *Py_UNUSED(ignored));
1571 : : PyDoc_STRVAR(reversed_doc,
1572 : : "D.__reversed__() -- return a reverse iterator over the deque");
1573 : :
1574 : : static PyMethodDef deque_methods[] = {
1575 : : {"append", (PyCFunction)deque_append,
1576 : : METH_O, append_doc},
1577 : : {"appendleft", (PyCFunction)deque_appendleft,
1578 : : METH_O, appendleft_doc},
1579 : : {"clear", (PyCFunction)deque_clearmethod,
1580 : : METH_NOARGS, clear_doc},
1581 : : {"__copy__", deque_copy,
1582 : : METH_NOARGS, copy_doc},
1583 : : {"copy", deque_copy,
1584 : : METH_NOARGS, copy_doc},
1585 : : {"count", (PyCFunction)deque_count,
1586 : : METH_O, count_doc},
1587 : : {"extend", (PyCFunction)deque_extend,
1588 : : METH_O, extend_doc},
1589 : : {"extendleft", (PyCFunction)deque_extendleft,
1590 : : METH_O, extendleft_doc},
1591 : : {"index", _PyCFunction_CAST(deque_index),
1592 : : METH_FASTCALL, index_doc},
1593 : : {"insert", _PyCFunction_CAST(deque_insert),
1594 : : METH_FASTCALL, insert_doc},
1595 : : {"pop", (PyCFunction)deque_pop,
1596 : : METH_NOARGS, pop_doc},
1597 : : {"popleft", (PyCFunction)deque_popleft,
1598 : : METH_NOARGS, popleft_doc},
1599 : : {"__reduce__", (PyCFunction)deque_reduce,
1600 : : METH_NOARGS, reduce_doc},
1601 : : {"remove", (PyCFunction)deque_remove,
1602 : : METH_O, remove_doc},
1603 : : {"__reversed__", (PyCFunction)deque_reviter,
1604 : : METH_NOARGS, reversed_doc},
1605 : : {"reverse", (PyCFunction)deque_reverse,
1606 : : METH_NOARGS, reverse_doc},
1607 : : {"rotate", _PyCFunction_CAST(deque_rotate),
1608 : : METH_FASTCALL, rotate_doc},
1609 : : {"__sizeof__", (PyCFunction)deque_sizeof,
1610 : : METH_NOARGS, sizeof_doc},
1611 : : {"__class_getitem__", Py_GenericAlias,
1612 : : METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
1613 : : {NULL, NULL} /* sentinel */
1614 : : };
1615 : :
1616 : : PyDoc_STRVAR(deque_doc,
1617 : : "deque([iterable[, maxlen]]) --> deque object\n\
1618 : : \n\
1619 : : A list-like sequence optimized for data accesses near its endpoints.");
1620 : :
1621 : : static PyTypeObject deque_type = {
1622 : : PyVarObject_HEAD_INIT(NULL, 0)
1623 : : "collections.deque", /* tp_name */
1624 : : sizeof(dequeobject), /* tp_basicsize */
1625 : : 0, /* tp_itemsize */
1626 : : /* methods */
1627 : : (destructor)deque_dealloc, /* tp_dealloc */
1628 : : 0, /* tp_vectorcall_offset */
1629 : : 0, /* tp_getattr */
1630 : : 0, /* tp_setattr */
1631 : : 0, /* tp_as_async */
1632 : : deque_repr, /* tp_repr */
1633 : : 0, /* tp_as_number */
1634 : : &deque_as_sequence, /* tp_as_sequence */
1635 : : 0, /* tp_as_mapping */
1636 : : PyObject_HashNotImplemented, /* tp_hash */
1637 : : 0, /* tp_call */
1638 : : 0, /* tp_str */
1639 : : PyObject_GenericGetAttr, /* tp_getattro */
1640 : : 0, /* tp_setattro */
1641 : : 0, /* tp_as_buffer */
1642 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1643 : : Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_SEQUENCE,
1644 : : /* tp_flags */
1645 : : deque_doc, /* tp_doc */
1646 : : (traverseproc)deque_traverse, /* tp_traverse */
1647 : : (inquiry)deque_clear, /* tp_clear */
1648 : : (richcmpfunc)deque_richcompare, /* tp_richcompare */
1649 : : offsetof(dequeobject, weakreflist), /* tp_weaklistoffset*/
1650 : : (getiterfunc)deque_iter, /* tp_iter */
1651 : : 0, /* tp_iternext */
1652 : : deque_methods, /* tp_methods */
1653 : : 0, /* tp_members */
1654 : : deque_getset, /* tp_getset */
1655 : : 0, /* tp_base */
1656 : : 0, /* tp_dict */
1657 : : 0, /* tp_descr_get */
1658 : : 0, /* tp_descr_set */
1659 : : 0, /* tp_dictoffset */
1660 : : (initproc)deque_init, /* tp_init */
1661 : : PyType_GenericAlloc, /* tp_alloc */
1662 : : deque_new, /* tp_new */
1663 : : PyObject_GC_Del, /* tp_free */
1664 : : };
1665 : :
1666 : : /*********************** Deque Iterator **************************/
1667 : :
1668 : : typedef struct {
1669 : : PyObject_HEAD
1670 : : block *b;
1671 : : Py_ssize_t index;
1672 : : dequeobject *deque;
1673 : : size_t state; /* state when the iterator is created */
1674 : : Py_ssize_t counter; /* number of items remaining for iteration */
1675 : : } dequeiterobject;
1676 : :
1677 : : static PyTypeObject dequeiter_type;
1678 : :
1679 : : static PyObject *
1680 : 2885 : deque_iter(dequeobject *deque)
1681 : : {
1682 : : dequeiterobject *it;
1683 : :
1684 : 2885 : it = PyObject_GC_New(dequeiterobject, &dequeiter_type);
1685 [ - + ]: 2885 : if (it == NULL)
1686 : 0 : return NULL;
1687 : 2885 : it->b = deque->leftblock;
1688 : 2885 : it->index = deque->leftindex;
1689 : 2885 : Py_INCREF(deque);
1690 : 2885 : it->deque = deque;
1691 : 2885 : it->state = deque->state;
1692 : 2885 : it->counter = Py_SIZE(deque);
1693 : 2885 : PyObject_GC_Track(it);
1694 : 2885 : return (PyObject *)it;
1695 : : }
1696 : :
1697 : : static int
1698 : 6 : dequeiter_traverse(dequeiterobject *dio, visitproc visit, void *arg)
1699 : : {
1700 [ + - - + ]: 6 : Py_VISIT(dio->deque);
1701 : 6 : return 0;
1702 : : }
1703 : :
1704 : : static void
1705 : 2895 : dequeiter_dealloc(dequeiterobject *dio)
1706 : : {
1707 : : /* bpo-31095: UnTrack is needed before calling any callbacks */
1708 : 2895 : PyObject_GC_UnTrack(dio);
1709 : 2895 : Py_XDECREF(dio->deque);
1710 : 2895 : PyObject_GC_Del(dio);
1711 : 2895 : }
1712 : :
1713 : : static PyObject *
1714 : 317861 : dequeiter_next(dequeiterobject *it)
1715 : : {
1716 : : PyObject *item;
1717 : :
1718 [ + + ]: 317861 : if (it->deque->state != it->state) {
1719 : 3 : it->counter = 0;
1720 : 3 : PyErr_SetString(PyExc_RuntimeError,
1721 : : "deque mutated during iteration");
1722 : 3 : return NULL;
1723 : : }
1724 [ + + ]: 317858 : if (it->counter == 0)
1725 : 2794 : return NULL;
1726 : : assert (!(it->b == it->deque->rightblock &&
1727 : : it->index > it->deque->rightindex));
1728 : :
1729 : 315064 : item = it->b->data[it->index];
1730 : 315064 : it->index++;
1731 : 315064 : it->counter--;
1732 [ + + + + ]: 315064 : if (it->index == BLOCKLEN && it->counter > 0) {
1733 : : CHECK_NOT_END(it->b->rightlink);
1734 : 4353 : it->b = it->b->rightlink;
1735 : 4353 : it->index = 0;
1736 : : }
1737 : 315064 : Py_INCREF(item);
1738 : 315064 : return item;
1739 : : }
1740 : :
1741 : : static PyObject *
1742 : 24 : dequeiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1743 : : {
1744 : 24 : Py_ssize_t i, index=0;
1745 : : PyObject *deque;
1746 : : dequeiterobject *it;
1747 [ - + ]: 24 : if (!PyArg_ParseTuple(args, "O!|n", &deque_type, &deque, &index))
1748 : 0 : return NULL;
1749 : : assert(type == &dequeiter_type);
1750 : :
1751 : 24 : it = (dequeiterobject*)deque_iter((dequeobject *)deque);
1752 [ - + ]: 24 : if (!it)
1753 : 0 : return NULL;
1754 : : /* consume items from the queue */
1755 [ + + ]: 2430 : for(i=0; i<index; i++) {
1756 : 2406 : PyObject *item = dequeiter_next(it);
1757 [ + - ]: 2406 : if (item) {
1758 : 2406 : Py_DECREF(item);
1759 : : } else {
1760 [ # # ]: 0 : if (it->counter) {
1761 : 0 : Py_DECREF(it);
1762 : 0 : return NULL;
1763 : : } else
1764 : 0 : break;
1765 : : }
1766 : : }
1767 : 24 : return (PyObject*)it;
1768 : : }
1769 : :
1770 : : static PyObject *
1771 : 61 : dequeiter_len(dequeiterobject *it, PyObject *Py_UNUSED(ignored))
1772 : : {
1773 : 61 : return PyLong_FromSsize_t(it->counter);
1774 : : }
1775 : :
1776 : : PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
1777 : :
1778 : : static PyObject *
1779 : 24 : dequeiter_reduce(dequeiterobject *it, PyObject *Py_UNUSED(ignored))
1780 : : {
1781 : 24 : return Py_BuildValue("O(On)", Py_TYPE(it), it->deque, Py_SIZE(it->deque) - it->counter);
1782 : : }
1783 : :
1784 : : static PyMethodDef dequeiter_methods[] = {
1785 : : {"__length_hint__", (PyCFunction)dequeiter_len, METH_NOARGS, length_hint_doc},
1786 : : {"__reduce__", (PyCFunction)dequeiter_reduce, METH_NOARGS, reduce_doc},
1787 : : {NULL, NULL} /* sentinel */
1788 : : };
1789 : :
1790 : : static PyTypeObject dequeiter_type = {
1791 : : PyVarObject_HEAD_INIT(NULL, 0)
1792 : : "_collections._deque_iterator", /* tp_name */
1793 : : sizeof(dequeiterobject), /* tp_basicsize */
1794 : : 0, /* tp_itemsize */
1795 : : /* methods */
1796 : : (destructor)dequeiter_dealloc, /* tp_dealloc */
1797 : : 0, /* tp_vectorcall_offset */
1798 : : 0, /* tp_getattr */
1799 : : 0, /* tp_setattr */
1800 : : 0, /* tp_as_async */
1801 : : 0, /* tp_repr */
1802 : : 0, /* tp_as_number */
1803 : : 0, /* tp_as_sequence */
1804 : : 0, /* tp_as_mapping */
1805 : : 0, /* tp_hash */
1806 : : 0, /* tp_call */
1807 : : 0, /* tp_str */
1808 : : PyObject_GenericGetAttr, /* tp_getattro */
1809 : : 0, /* tp_setattro */
1810 : : 0, /* tp_as_buffer */
1811 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1812 : : 0, /* tp_doc */
1813 : : (traverseproc)dequeiter_traverse, /* tp_traverse */
1814 : : 0, /* tp_clear */
1815 : : 0, /* tp_richcompare */
1816 : : 0, /* tp_weaklistoffset */
1817 : : PyObject_SelfIter, /* tp_iter */
1818 : : (iternextfunc)dequeiter_next, /* tp_iternext */
1819 : : dequeiter_methods, /* tp_methods */
1820 : : 0, /* tp_members */
1821 : : 0, /* tp_getset */
1822 : : 0, /* tp_base */
1823 : : 0, /* tp_dict */
1824 : : 0, /* tp_descr_get */
1825 : : 0, /* tp_descr_set */
1826 : : 0, /* tp_dictoffset */
1827 : : 0, /* tp_init */
1828 : : 0, /* tp_alloc */
1829 : : dequeiter_new, /* tp_new */
1830 : : 0,
1831 : : };
1832 : :
1833 : : /*********************** Deque Reverse Iterator **************************/
1834 : :
1835 : : static PyTypeObject dequereviter_type;
1836 : :
1837 : : static PyObject *
1838 : 10 : deque_reviter(dequeobject *deque, PyObject *Py_UNUSED(ignored))
1839 : : {
1840 : : dequeiterobject *it;
1841 : :
1842 : 10 : it = PyObject_GC_New(dequeiterobject, &dequereviter_type);
1843 [ - + ]: 10 : if (it == NULL)
1844 : 0 : return NULL;
1845 : 10 : it->b = deque->rightblock;
1846 : 10 : it->index = deque->rightindex;
1847 : 10 : Py_INCREF(deque);
1848 : 10 : it->deque = deque;
1849 : 10 : it->state = deque->state;
1850 : 10 : it->counter = Py_SIZE(deque);
1851 : 10 : PyObject_GC_Track(it);
1852 : 10 : return (PyObject *)it;
1853 : : }
1854 : :
1855 : : static PyObject *
1856 : 4036 : dequereviter_next(dequeiterobject *it)
1857 : : {
1858 : : PyObject *item;
1859 [ + + ]: 4036 : if (it->counter == 0)
1860 : 7 : return NULL;
1861 : :
1862 [ + + ]: 4029 : if (it->deque->state != it->state) {
1863 : 1 : it->counter = 0;
1864 : 1 : PyErr_SetString(PyExc_RuntimeError,
1865 : : "deque mutated during iteration");
1866 : 1 : return NULL;
1867 : : }
1868 : : assert (!(it->b == it->deque->leftblock &&
1869 : : it->index < it->deque->leftindex));
1870 : :
1871 : 4028 : item = it->b->data[it->index];
1872 : 4028 : it->index--;
1873 : 4028 : it->counter--;
1874 [ + + + - ]: 4028 : if (it->index < 0 && it->counter > 0) {
1875 : : CHECK_NOT_END(it->b->leftlink);
1876 : 62 : it->b = it->b->leftlink;
1877 : 62 : it->index = BLOCKLEN - 1;
1878 : : }
1879 : 4028 : Py_INCREF(item);
1880 : 4028 : return item;
1881 : : }
1882 : :
1883 : : static PyObject *
1884 : 2 : dequereviter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1885 : : {
1886 : 2 : Py_ssize_t i, index=0;
1887 : : PyObject *deque;
1888 : : dequeiterobject *it;
1889 [ - + ]: 2 : if (!PyArg_ParseTuple(args, "O!|n", &deque_type, &deque, &index))
1890 : 0 : return NULL;
1891 : : assert(type == &dequereviter_type);
1892 : :
1893 : 2 : it = (dequeiterobject*)deque_reviter((dequeobject *)deque, NULL);
1894 [ - + ]: 2 : if (!it)
1895 : 0 : return NULL;
1896 : : /* consume items from the queue */
1897 [ - + ]: 2 : for(i=0; i<index; i++) {
1898 : 0 : PyObject *item = dequereviter_next(it);
1899 [ # # ]: 0 : if (item) {
1900 : 0 : Py_DECREF(item);
1901 : : } else {
1902 [ # # ]: 0 : if (it->counter) {
1903 : 0 : Py_DECREF(it);
1904 : 0 : return NULL;
1905 : : } else
1906 : 0 : break;
1907 : : }
1908 : : }
1909 : 2 : return (PyObject*)it;
1910 : : }
1911 : :
1912 : : static PyTypeObject dequereviter_type = {
1913 : : PyVarObject_HEAD_INIT(NULL, 0)
1914 : : "_collections._deque_reverse_iterator", /* tp_name */
1915 : : sizeof(dequeiterobject), /* tp_basicsize */
1916 : : 0, /* tp_itemsize */
1917 : : /* methods */
1918 : : (destructor)dequeiter_dealloc, /* tp_dealloc */
1919 : : 0, /* tp_vectorcall_offset */
1920 : : 0, /* tp_getattr */
1921 : : 0, /* tp_setattr */
1922 : : 0, /* tp_as_async */
1923 : : 0, /* tp_repr */
1924 : : 0, /* tp_as_number */
1925 : : 0, /* tp_as_sequence */
1926 : : 0, /* tp_as_mapping */
1927 : : 0, /* tp_hash */
1928 : : 0, /* tp_call */
1929 : : 0, /* tp_str */
1930 : : PyObject_GenericGetAttr, /* tp_getattro */
1931 : : 0, /* tp_setattro */
1932 : : 0, /* tp_as_buffer */
1933 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1934 : : 0, /* tp_doc */
1935 : : (traverseproc)dequeiter_traverse, /* tp_traverse */
1936 : : 0, /* tp_clear */
1937 : : 0, /* tp_richcompare */
1938 : : 0, /* tp_weaklistoffset */
1939 : : PyObject_SelfIter, /* tp_iter */
1940 : : (iternextfunc)dequereviter_next, /* tp_iternext */
1941 : : dequeiter_methods, /* tp_methods */
1942 : : 0, /* tp_members */
1943 : : 0, /* tp_getset */
1944 : : 0, /* tp_base */
1945 : : 0, /* tp_dict */
1946 : : 0, /* tp_descr_get */
1947 : : 0, /* tp_descr_set */
1948 : : 0, /* tp_dictoffset */
1949 : : 0, /* tp_init */
1950 : : 0, /* tp_alloc */
1951 : : dequereviter_new, /* tp_new */
1952 : : 0,
1953 : : };
1954 : :
1955 : : /* defaultdict type *********************************************************/
1956 : :
1957 : : typedef struct {
1958 : : PyDictObject dict;
1959 : : PyObject *default_factory;
1960 : : } defdictobject;
1961 : :
1962 : : static PyTypeObject defdict_type; /* Forward */
1963 : :
1964 : : PyDoc_STRVAR(defdict_missing_doc,
1965 : : "__missing__(key) # Called by __getitem__ for missing key; pseudo-code:\n\
1966 : : if self.default_factory is None: raise KeyError((key,))\n\
1967 : : self[key] = value = self.default_factory()\n\
1968 : : return value\n\
1969 : : ");
1970 : :
1971 : : static PyObject *
1972 : 164077 : defdict_missing(defdictobject *dd, PyObject *key)
1973 : : {
1974 : 164077 : PyObject *factory = dd->default_factory;
1975 : : PyObject *value;
1976 [ + + + + ]: 164077 : if (factory == NULL || factory == Py_None) {
1977 : : /* XXX Call dict.__missing__(key) */
1978 : : PyObject *tup;
1979 : 3 : tup = PyTuple_Pack(1, key);
1980 [ - + ]: 3 : if (!tup) return NULL;
1981 : 3 : PyErr_SetObject(PyExc_KeyError, tup);
1982 : 3 : Py_DECREF(tup);
1983 : 3 : return NULL;
1984 : : }
1985 : 164074 : value = _PyObject_CallNoArgs(factory);
1986 [ - + ]: 164074 : if (value == NULL)
1987 : 0 : return value;
1988 [ - + ]: 164074 : if (PyObject_SetItem((PyObject *)dd, key, value) < 0) {
1989 : 0 : Py_DECREF(value);
1990 : 0 : return NULL;
1991 : : }
1992 : 164074 : return value;
1993 : : }
1994 : :
1995 : : static inline PyObject*
1996 : 10 : new_defdict(defdictobject *dd, PyObject *arg)
1997 : : {
1998 : 10 : return PyObject_CallFunctionObjArgs((PyObject*)Py_TYPE(dd),
1999 [ + + ]: 10 : dd->default_factory ? dd->default_factory : Py_None, arg, NULL);
2000 : : }
2001 : :
2002 : : PyDoc_STRVAR(defdict_copy_doc, "D.copy() -> a shallow copy of D.");
2003 : :
2004 : : static PyObject *
2005 : 6 : defdict_copy(defdictobject *dd, PyObject *Py_UNUSED(ignored))
2006 : : {
2007 : : /* This calls the object's class. That only works for subclasses
2008 : : whose class constructor has the same signature. Subclasses that
2009 : : define a different constructor signature must override copy().
2010 : : */
2011 : 6 : return new_defdict(dd, (PyObject*)dd);
2012 : : }
2013 : :
2014 : : static PyObject *
2015 : 26 : defdict_reduce(defdictobject *dd, PyObject *Py_UNUSED(ignored))
2016 : : {
2017 : : /* __reduce__ must return a 5-tuple as follows:
2018 : :
2019 : : - factory function
2020 : : - tuple of args for the factory function
2021 : : - additional state (here None)
2022 : : - sequence iterator (here None)
2023 : : - dictionary iterator (yielding successive (key, value) pairs
2024 : :
2025 : : This API is used by pickle.py and copy.py.
2026 : :
2027 : : For this to be useful with pickle.py, the default_factory
2028 : : must be picklable; e.g., None, a built-in, or a global
2029 : : function in a module or package.
2030 : :
2031 : : Both shallow and deep copying are supported, but for deep
2032 : : copying, the default_factory must be deep-copyable; e.g. None,
2033 : : or a built-in (functions are not copyable at this time).
2034 : :
2035 : : This only works for subclasses as long as their constructor
2036 : : signature is compatible; the first argument must be the
2037 : : optional default_factory, defaulting to None.
2038 : : */
2039 : : PyObject *args;
2040 : : PyObject *items;
2041 : : PyObject *iter;
2042 : : PyObject *result;
2043 : :
2044 [ + + - + ]: 26 : if (dd->default_factory == NULL || dd->default_factory == Py_None)
2045 : 18 : args = PyTuple_New(0);
2046 : : else
2047 : 8 : args = PyTuple_Pack(1, dd->default_factory);
2048 [ - + ]: 26 : if (args == NULL)
2049 : 0 : return NULL;
2050 : 26 : items = PyObject_CallMethodNoArgs((PyObject *)dd, &_Py_ID(items));
2051 [ - + ]: 26 : if (items == NULL) {
2052 : 0 : Py_DECREF(args);
2053 : 0 : return NULL;
2054 : : }
2055 : 26 : iter = PyObject_GetIter(items);
2056 [ - + ]: 26 : if (iter == NULL) {
2057 : 0 : Py_DECREF(items);
2058 : 0 : Py_DECREF(args);
2059 : 0 : return NULL;
2060 : : }
2061 : 26 : result = PyTuple_Pack(5, Py_TYPE(dd), args,
2062 : : Py_None, Py_None, iter);
2063 : 26 : Py_DECREF(iter);
2064 : 26 : Py_DECREF(items);
2065 : 26 : Py_DECREF(args);
2066 : 26 : return result;
2067 : : }
2068 : :
2069 : : static PyMethodDef defdict_methods[] = {
2070 : : {"__missing__", (PyCFunction)defdict_missing, METH_O,
2071 : : defdict_missing_doc},
2072 : : {"copy", (PyCFunction)defdict_copy, METH_NOARGS,
2073 : : defdict_copy_doc},
2074 : : {"__copy__", (PyCFunction)defdict_copy, METH_NOARGS,
2075 : : defdict_copy_doc},
2076 : : {"__reduce__", (PyCFunction)defdict_reduce, METH_NOARGS,
2077 : : reduce_doc},
2078 : : {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS,
2079 : : PyDoc_STR("See PEP 585")},
2080 : : {NULL}
2081 : : };
2082 : :
2083 : : static PyMemberDef defdict_members[] = {
2084 : : {"default_factory", T_OBJECT,
2085 : : offsetof(defdictobject, default_factory), 0,
2086 : : PyDoc_STR("Factory for default value called by __missing__().")},
2087 : : {NULL}
2088 : : };
2089 : :
2090 : : static void
2091 : 17295 : defdict_dealloc(defdictobject *dd)
2092 : : {
2093 : : /* bpo-31095: UnTrack is needed before calling any callbacks */
2094 : 17295 : PyObject_GC_UnTrack(dd);
2095 [ + + ]: 17295 : Py_CLEAR(dd->default_factory);
2096 : 17295 : PyDict_Type.tp_dealloc((PyObject *)dd);
2097 : 17295 : }
2098 : :
2099 : : static PyObject *
2100 : 16 : defdict_repr(defdictobject *dd)
2101 : : {
2102 : : PyObject *baserepr;
2103 : : PyObject *defrepr;
2104 : : PyObject *result;
2105 : 16 : baserepr = PyDict_Type.tp_repr((PyObject *)dd);
2106 [ - + ]: 16 : if (baserepr == NULL)
2107 : 0 : return NULL;
2108 [ + + ]: 16 : if (dd->default_factory == NULL)
2109 : 3 : defrepr = PyUnicode_FromString("None");
2110 : : else
2111 : : {
2112 : 13 : int status = Py_ReprEnter(dd->default_factory);
2113 [ + + ]: 13 : if (status != 0) {
2114 [ - + ]: 1 : if (status < 0) {
2115 : 0 : Py_DECREF(baserepr);
2116 : 0 : return NULL;
2117 : : }
2118 : 1 : defrepr = PyUnicode_FromString("...");
2119 : : }
2120 : : else
2121 : 12 : defrepr = PyObject_Repr(dd->default_factory);
2122 : 13 : Py_ReprLeave(dd->default_factory);
2123 : : }
2124 [ - + ]: 16 : if (defrepr == NULL) {
2125 : 0 : Py_DECREF(baserepr);
2126 : 0 : return NULL;
2127 : : }
2128 : 16 : result = PyUnicode_FromFormat("%s(%U, %U)",
2129 : : _PyType_Name(Py_TYPE(dd)),
2130 : : defrepr, baserepr);
2131 : 16 : Py_DECREF(defrepr);
2132 : 16 : Py_DECREF(baserepr);
2133 : 16 : return result;
2134 : : }
2135 : :
2136 : : static PyObject*
2137 : 6 : defdict_or(PyObject* left, PyObject* right)
2138 : : {
2139 : : PyObject *self, *other;
2140 [ + + ]: 6 : if (PyObject_TypeCheck(left, &defdict_type)) {
2141 : 4 : self = left;
2142 : 4 : other = right;
2143 : : }
2144 : : else {
2145 : 2 : self = right;
2146 : 2 : other = left;
2147 : : }
2148 [ + + ]: 6 : if (!PyDict_Check(other)) {
2149 : 2 : Py_RETURN_NOTIMPLEMENTED;
2150 : : }
2151 : : // Like copy(), this calls the object's class.
2152 : : // Override __or__/__ror__ for subclasses with different constructors.
2153 : 4 : PyObject *new = new_defdict((defdictobject*)self, left);
2154 [ - + ]: 4 : if (!new) {
2155 : 0 : return NULL;
2156 : : }
2157 [ - + ]: 4 : if (PyDict_Update(new, right)) {
2158 : 0 : Py_DECREF(new);
2159 : 0 : return NULL;
2160 : : }
2161 : 4 : return new;
2162 : : }
2163 : :
2164 : : static PyNumberMethods defdict_as_number = {
2165 : : .nb_or = defdict_or,
2166 : : };
2167 : :
2168 : : static int
2169 : 58514 : defdict_traverse(PyObject *self, visitproc visit, void *arg)
2170 : : {
2171 [ + + - + ]: 58514 : Py_VISIT(((defdictobject *)self)->default_factory);
2172 : 58514 : return PyDict_Type.tp_traverse(self, visit, arg);
2173 : : }
2174 : :
2175 : : static int
2176 : 204 : defdict_tp_clear(defdictobject *dd)
2177 : : {
2178 [ + + ]: 204 : Py_CLEAR(dd->default_factory);
2179 : 204 : return PyDict_Type.tp_clear((PyObject *)dd);
2180 : : }
2181 : :
2182 : : static int
2183 : 17294 : defdict_init(PyObject *self, PyObject *args, PyObject *kwds)
2184 : : {
2185 : 17294 : defdictobject *dd = (defdictobject *)self;
2186 : 17294 : PyObject *olddefault = dd->default_factory;
2187 : 17294 : PyObject *newdefault = NULL;
2188 : : PyObject *newargs;
2189 : : int result;
2190 [ + - - + ]: 17294 : if (args == NULL || !PyTuple_Check(args))
2191 : 0 : newargs = PyTuple_New(0);
2192 : : else {
2193 : 17294 : Py_ssize_t n = PyTuple_GET_SIZE(args);
2194 [ + + ]: 17294 : if (n > 0) {
2195 : 17255 : newdefault = PyTuple_GET_ITEM(args, 0);
2196 [ + + + + ]: 17255 : if (!PyCallable_Check(newdefault) && newdefault != Py_None) {
2197 : 2 : PyErr_SetString(PyExc_TypeError,
2198 : : "first argument must be callable or None");
2199 : 2 : return -1;
2200 : : }
2201 : : }
2202 : 17292 : newargs = PySequence_GetSlice(args, 1, n);
2203 : : }
2204 [ - + ]: 17292 : if (newargs == NULL)
2205 : 0 : return -1;
2206 : 17292 : Py_XINCREF(newdefault);
2207 : 17292 : dd->default_factory = newdefault;
2208 : 17292 : result = PyDict_Type.tp_init(self, newargs, kwds);
2209 : 17292 : Py_DECREF(newargs);
2210 : 17292 : Py_XDECREF(olddefault);
2211 : 17292 : return result;
2212 : : }
2213 : :
2214 : : PyDoc_STRVAR(defdict_doc,
2215 : : "defaultdict(default_factory=None, /, [...]) --> dict with default factory\n\
2216 : : \n\
2217 : : The default factory is called without arguments to produce\n\
2218 : : a new value when a key is not present, in __getitem__ only.\n\
2219 : : A defaultdict compares equal to a dict with the same items.\n\
2220 : : All remaining arguments are treated the same as if they were\n\
2221 : : passed to the dict constructor, including keyword arguments.\n\
2222 : : ");
2223 : :
2224 : : /* See comment in xxsubtype.c */
2225 : : #define DEFERRED_ADDRESS(ADDR) 0
2226 : :
2227 : : static PyTypeObject defdict_type = {
2228 : : PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
2229 : : "collections.defaultdict", /* tp_name */
2230 : : sizeof(defdictobject), /* tp_basicsize */
2231 : : 0, /* tp_itemsize */
2232 : : /* methods */
2233 : : (destructor)defdict_dealloc, /* tp_dealloc */
2234 : : 0, /* tp_vectorcall_offset */
2235 : : 0, /* tp_getattr */
2236 : : 0, /* tp_setattr */
2237 : : 0, /* tp_as_async */
2238 : : (reprfunc)defdict_repr, /* tp_repr */
2239 : : &defdict_as_number, /* tp_as_number */
2240 : : 0, /* tp_as_sequence */
2241 : : 0, /* tp_as_mapping */
2242 : : 0, /* tp_hash */
2243 : : 0, /* tp_call */
2244 : : 0, /* tp_str */
2245 : : PyObject_GenericGetAttr, /* tp_getattro */
2246 : : 0, /* tp_setattro */
2247 : : 0, /* tp_as_buffer */
2248 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
2249 : : /* tp_flags */
2250 : : defdict_doc, /* tp_doc */
2251 : : defdict_traverse, /* tp_traverse */
2252 : : (inquiry)defdict_tp_clear, /* tp_clear */
2253 : : 0, /* tp_richcompare */
2254 : : 0, /* tp_weaklistoffset*/
2255 : : 0, /* tp_iter */
2256 : : 0, /* tp_iternext */
2257 : : defdict_methods, /* tp_methods */
2258 : : defdict_members, /* tp_members */
2259 : : 0, /* tp_getset */
2260 : : DEFERRED_ADDRESS(&PyDict_Type), /* tp_base */
2261 : : 0, /* tp_dict */
2262 : : 0, /* tp_descr_get */
2263 : : 0, /* tp_descr_set */
2264 : : 0, /* tp_dictoffset */
2265 : : defdict_init, /* tp_init */
2266 : : PyType_GenericAlloc, /* tp_alloc */
2267 : : 0, /* tp_new */
2268 : : PyObject_GC_Del, /* tp_free */
2269 : : };
2270 : :
2271 : : /* helper function for Counter *********************************************/
2272 : :
2273 : : /*[clinic input]
2274 : : _collections._count_elements
2275 : :
2276 : : mapping: object
2277 : : iterable: object
2278 : : /
2279 : :
2280 : : Count elements in the iterable, updating the mapping
2281 : : [clinic start generated code]*/
2282 : :
2283 : : static PyObject *
2284 : 2026 : _collections__count_elements_impl(PyObject *module, PyObject *mapping,
2285 : : PyObject *iterable)
2286 : : /*[clinic end generated code: output=7e0c1789636b3d8f input=e79fad04534a0b45]*/
2287 : : {
2288 : : PyObject *it, *oldval;
2289 : 2026 : PyObject *newval = NULL;
2290 : 2026 : PyObject *key = NULL;
2291 : 2026 : PyObject *bound_get = NULL;
2292 : : PyObject *mapping_get;
2293 : : PyObject *dict_get;
2294 : : PyObject *mapping_setitem;
2295 : : PyObject *dict_setitem;
2296 : 2026 : PyObject *one = _PyLong_GetOne(); // borrowed reference
2297 : :
2298 : 2026 : it = PyObject_GetIter(iterable);
2299 [ + + ]: 2026 : if (it == NULL)
2300 : 2 : return NULL;
2301 : :
2302 : : /* Only take the fast path when get() and __setitem__()
2303 : : * have not been overridden.
2304 : : */
2305 : 2024 : mapping_get = _PyType_Lookup(Py_TYPE(mapping), &_Py_ID(get));
2306 : 2024 : dict_get = _PyType_Lookup(&PyDict_Type, &_Py_ID(get));
2307 : 2024 : mapping_setitem = _PyType_Lookup(Py_TYPE(mapping), &_Py_ID(__setitem__));
2308 : 2024 : dict_setitem = _PyType_Lookup(&PyDict_Type, &_Py_ID(__setitem__));
2309 : :
2310 [ + - + + : 2024 : if (mapping_get != NULL && mapping_get == dict_get &&
+ - ]
2311 [ + + + - ]: 4044 : mapping_setitem != NULL && mapping_setitem == dict_setitem &&
2312 : 2021 : PyDict_Check(mapping))
2313 : : {
2314 : 220580 : while (1) {
2315 : : /* Fast path advantages:
2316 : : 1. Eliminate double hashing
2317 : : (by re-using the same hash for both the get and set)
2318 : : 2. Avoid argument overhead of PyObject_CallFunctionObjArgs
2319 : : (argument tuple creation and parsing)
2320 : : 3. Avoid indirection through a bound method object
2321 : : (creates another argument tuple)
2322 : : 4. Avoid initial increment from zero
2323 : : (reuse an existing one-object instead)
2324 : : */
2325 : : Py_hash_t hash;
2326 : :
2327 : 222601 : key = PyIter_Next(it);
2328 [ + + ]: 222601 : if (key == NULL)
2329 : 2011 : break;
2330 : :
2331 [ + + ]: 220590 : if (!PyUnicode_CheckExact(key) ||
2332 [ + + ]: 16248 : (hash = _PyASCIIObject_CAST(key)->hash) == -1)
2333 : : {
2334 : 205281 : hash = PyObject_Hash(key);
2335 [ + + ]: 205281 : if (hash == -1)
2336 : 10 : goto done;
2337 : : }
2338 : :
2339 : 220580 : oldval = _PyDict_GetItem_KnownHash(mapping, key, hash);
2340 [ + + ]: 220580 : if (oldval == NULL) {
2341 [ - + ]: 13864 : if (PyErr_Occurred())
2342 : 0 : goto done;
2343 [ - + ]: 13864 : if (_PyDict_SetItem_KnownHash(mapping, key, one, hash) < 0)
2344 : 0 : goto done;
2345 : : } else {
2346 : 206716 : newval = PyNumber_Add(oldval, one);
2347 [ - + ]: 206716 : if (newval == NULL)
2348 : 0 : goto done;
2349 [ - + ]: 206716 : if (_PyDict_SetItem_KnownHash(mapping, key, newval, hash) < 0)
2350 : 0 : goto done;
2351 [ + - ]: 206716 : Py_CLEAR(newval);
2352 : : }
2353 : 220580 : Py_DECREF(key);
2354 : : }
2355 : : }
2356 : : else {
2357 : 3 : bound_get = PyObject_GetAttr(mapping, &_Py_ID(get));
2358 [ - + ]: 3 : if (bound_get == NULL)
2359 : 0 : goto done;
2360 : :
2361 : 3 : PyObject *zero = _PyLong_GetZero(); // borrowed reference
2362 : : while (1) {
2363 : 36 : key = PyIter_Next(it);
2364 [ + + ]: 36 : if (key == NULL)
2365 : 3 : break;
2366 : 33 : oldval = PyObject_CallFunctionObjArgs(bound_get, key, zero, NULL);
2367 [ - + ]: 33 : if (oldval == NULL)
2368 : 0 : break;
2369 : 33 : newval = PyNumber_Add(oldval, one);
2370 : 33 : Py_DECREF(oldval);
2371 [ - + ]: 33 : if (newval == NULL)
2372 : 0 : break;
2373 [ - + ]: 33 : if (PyObject_SetItem(mapping, key, newval) < 0)
2374 : 0 : break;
2375 [ + - ]: 33 : Py_CLEAR(newval);
2376 : 33 : Py_DECREF(key);
2377 : : }
2378 : : }
2379 : :
2380 : 2024 : done:
2381 : 2024 : Py_DECREF(it);
2382 : 2024 : Py_XDECREF(key);
2383 : 2024 : Py_XDECREF(newval);
2384 : 2024 : Py_XDECREF(bound_get);
2385 [ + + ]: 2024 : if (PyErr_Occurred())
2386 : 10 : return NULL;
2387 : 2014 : Py_RETURN_NONE;
2388 : : }
2389 : :
2390 : : /* Helper function for namedtuple() ************************************/
2391 : :
2392 : : typedef struct {
2393 : : PyObject_HEAD
2394 : : Py_ssize_t index;
2395 : : PyObject* doc;
2396 : : } _tuplegetterobject;
2397 : :
2398 : : /*[clinic input]
2399 : : @classmethod
2400 : : _tuplegetter.__new__ as tuplegetter_new
2401 : :
2402 : : index: Py_ssize_t
2403 : : doc: object
2404 : : /
2405 : : [clinic start generated code]*/
2406 : :
2407 : : static PyObject *
2408 : 131676 : tuplegetter_new_impl(PyTypeObject *type, Py_ssize_t index, PyObject *doc)
2409 : : /*[clinic end generated code: output=014be444ad80263f input=87c576a5bdbc0bbb]*/
2410 : : {
2411 : : _tuplegetterobject* self;
2412 : 131676 : self = (_tuplegetterobject *)type->tp_alloc(type, 0);
2413 [ - + ]: 131676 : if (self == NULL) {
2414 : 0 : return NULL;
2415 : : }
2416 : 131676 : self->index = index;
2417 : 131676 : Py_INCREF(doc);
2418 : 131676 : self->doc = doc;
2419 : 131676 : return (PyObject *)self;
2420 : : }
2421 : :
2422 : : static PyObject *
2423 : 1274223 : tuplegetter_descr_get(PyObject *self, PyObject *obj, PyObject *type)
2424 : : {
2425 : 1274223 : Py_ssize_t index = ((_tuplegetterobject*)self)->index;
2426 : : PyObject *result;
2427 : :
2428 [ + + ]: 1274223 : if (obj == NULL) {
2429 : 32501 : Py_INCREF(self);
2430 : 32501 : return self;
2431 : : }
2432 [ - + ]: 1241722 : if (!PyTuple_Check(obj)) {
2433 [ # # ]: 0 : if (obj == Py_None) {
2434 : 0 : Py_INCREF(self);
2435 : 0 : return self;
2436 : : }
2437 : 0 : PyErr_Format(PyExc_TypeError,
2438 : : "descriptor for index '%zd' for tuple subclasses "
2439 : : "doesn't apply to '%s' object",
2440 : : index,
2441 : 0 : Py_TYPE(obj)->tp_name);
2442 : 0 : return NULL;
2443 : : }
2444 : :
2445 [ - + ]: 1241722 : if (!valid_index(index, PyTuple_GET_SIZE(obj))) {
2446 : 0 : PyErr_SetString(PyExc_IndexError, "tuple index out of range");
2447 : 0 : return NULL;
2448 : : }
2449 : :
2450 : 1241722 : result = PyTuple_GET_ITEM(obj, index);
2451 : 1241722 : Py_INCREF(result);
2452 : 1241722 : return result;
2453 : : }
2454 : :
2455 : : static int
2456 : 4 : tuplegetter_descr_set(PyObject *self, PyObject *obj, PyObject *value)
2457 : : {
2458 [ + + ]: 4 : if (value == NULL) {
2459 : 2 : PyErr_SetString(PyExc_AttributeError, "can't delete attribute");
2460 : : } else {
2461 : 2 : PyErr_SetString(PyExc_AttributeError, "can't set attribute");
2462 : : }
2463 : 4 : return -1;
2464 : : }
2465 : :
2466 : : static int
2467 : 3987341 : tuplegetter_traverse(PyObject *self, visitproc visit, void *arg)
2468 : : {
2469 : 3987341 : _tuplegetterobject *tuplegetter = (_tuplegetterobject *)self;
2470 [ + - - + ]: 3987341 : Py_VISIT(tuplegetter->doc);
2471 : 3987341 : return 0;
2472 : : }
2473 : :
2474 : : static int
2475 : 131840 : tuplegetter_clear(PyObject *self)
2476 : : {
2477 : 131840 : _tuplegetterobject *tuplegetter = (_tuplegetterobject *)self;
2478 [ + + ]: 131840 : Py_CLEAR(tuplegetter->doc);
2479 : 131840 : return 0;
2480 : : }
2481 : :
2482 : : static void
2483 : 131259 : tuplegetter_dealloc(_tuplegetterobject *self)
2484 : : {
2485 : 131259 : PyObject_GC_UnTrack(self);
2486 : 131259 : tuplegetter_clear((PyObject*)self);
2487 : 131259 : Py_TYPE(self)->tp_free((PyObject*)self);
2488 : 131259 : }
2489 : :
2490 : : static PyObject*
2491 : 12 : tuplegetter_reduce(_tuplegetterobject *self, PyObject *Py_UNUSED(ignored))
2492 : : {
2493 : 12 : return Py_BuildValue("(O(nO))", (PyObject*) Py_TYPE(self), self->index, self->doc);
2494 : : }
2495 : :
2496 : : static PyObject*
2497 : 4 : tuplegetter_repr(_tuplegetterobject *self)
2498 : : {
2499 : 4 : return PyUnicode_FromFormat("%s(%zd, %R)",
2500 : : _PyType_Name(Py_TYPE(self)),
2501 : : self->index, self->doc);
2502 : : }
2503 : :
2504 : :
2505 : : static PyMemberDef tuplegetter_members[] = {
2506 : : {"__doc__", T_OBJECT, offsetof(_tuplegetterobject, doc), 0},
2507 : : {0}
2508 : : };
2509 : :
2510 : : static PyMethodDef tuplegetter_methods[] = {
2511 : : {"__reduce__", (PyCFunction)tuplegetter_reduce, METH_NOARGS, NULL},
2512 : : {NULL},
2513 : : };
2514 : :
2515 : : static PyTypeObject tuplegetter_type = {
2516 : : PyVarObject_HEAD_INIT(NULL, 0)
2517 : : "_collections._tuplegetter", /* tp_name */
2518 : : sizeof(_tuplegetterobject), /* tp_basicsize */
2519 : : 0, /* tp_itemsize */
2520 : : /* methods */
2521 : : (destructor)tuplegetter_dealloc, /* tp_dealloc */
2522 : : 0, /* tp_vectorcall_offset */
2523 : : 0, /* tp_getattr */
2524 : : 0, /* tp_setattr */
2525 : : 0, /* tp_as_async */
2526 : : (reprfunc)tuplegetter_repr, /* tp_repr */
2527 : : 0, /* tp_as_number */
2528 : : 0, /* tp_as_sequence */
2529 : : 0, /* tp_as_mapping */
2530 : : 0, /* tp_hash */
2531 : : 0, /* tp_call */
2532 : : 0, /* tp_str */
2533 : : 0, /* tp_getattro */
2534 : : 0, /* tp_setattro */
2535 : : 0, /* tp_as_buffer */
2536 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2537 : : 0, /* tp_doc */
2538 : : (traverseproc)tuplegetter_traverse, /* tp_traverse */
2539 : : (inquiry)tuplegetter_clear, /* tp_clear */
2540 : : 0, /* tp_richcompare */
2541 : : 0, /* tp_weaklistoffset */
2542 : : 0, /* tp_iter */
2543 : : 0, /* tp_iternext */
2544 : : tuplegetter_methods, /* tp_methods */
2545 : : tuplegetter_members, /* tp_members */
2546 : : 0, /* tp_getset */
2547 : : 0, /* tp_base */
2548 : : 0, /* tp_dict */
2549 : : tuplegetter_descr_get, /* tp_descr_get */
2550 : : tuplegetter_descr_set, /* tp_descr_set */
2551 : : 0, /* tp_dictoffset */
2552 : : 0, /* tp_init */
2553 : : 0, /* tp_alloc */
2554 : : tuplegetter_new, /* tp_new */
2555 : : 0,
2556 : : };
2557 : :
2558 : :
2559 : : /* module level code ********************************************************/
2560 : :
2561 : : PyDoc_STRVAR(collections_doc,
2562 : : "High performance data structures.\n\
2563 : : - deque: ordered collection accessible from endpoints only\n\
2564 : : - defaultdict: dict subclass with a default value factory\n\
2565 : : ");
2566 : :
2567 : : static struct PyMethodDef collections_methods[] = {
2568 : : _COLLECTIONS__COUNT_ELEMENTS_METHODDEF
2569 : : {NULL, NULL} /* sentinel */
2570 : : };
2571 : :
2572 : : static int
2573 : 1983 : collections_exec(PyObject *module) {
2574 : 1983 : PyTypeObject *typelist[] = {
2575 : : &deque_type,
2576 : : &defdict_type,
2577 : : &PyODict_Type,
2578 : : &dequeiter_type,
2579 : : &dequereviter_type,
2580 : : &tuplegetter_type
2581 : : };
2582 : :
2583 : 1983 : defdict_type.tp_base = &PyDict_Type;
2584 : :
2585 [ + + ]: 13881 : for (size_t i = 0; i < Py_ARRAY_LENGTH(typelist); i++) {
2586 [ - + ]: 11898 : if (PyModule_AddType(module, typelist[i]) < 0) {
2587 : 0 : return -1;
2588 : : }
2589 : : }
2590 : :
2591 : 1983 : return 0;
2592 : : }
2593 : :
2594 : : static struct PyModuleDef_Slot collections_slots[] = {
2595 : : {Py_mod_exec, collections_exec},
2596 : : {0, NULL}
2597 : : };
2598 : :
2599 : : static struct PyModuleDef _collectionsmodule = {
2600 : : PyModuleDef_HEAD_INIT,
2601 : : "_collections",
2602 : : collections_doc,
2603 : : 0,
2604 : : collections_methods,
2605 : : collections_slots,
2606 : : NULL,
2607 : : NULL,
2608 : : NULL
2609 : : };
2610 : :
2611 : : PyMODINIT_FUNC
2612 : 1983 : PyInit__collections(void)
2613 : : {
2614 : 1983 : return PyModuleDef_Init(&_collectionsmodule);
2615 : : }
|