blob: 4eb31bf9c543fae5778370f04b2e26b7a036da75 [file] [log] [blame]
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001#include "Python.h"
Raymond Hettinger691d8052004-05-30 07:26:47 +00002#include "structmember.h"
Raymond Hettinger756b3f32004-01-29 06:37:52 +00003
Raymond Hettingerc2083082015-02-28 23:29:16 -08004#ifdef STDC_HEADERS
5#include <stddef.h>
6#else
7#include <sys/types.h> /* For size_t */
8#endif
9
Raymond Hettinger756b3f32004-01-29 06:37:52 +000010/* collections module implementation of a deque() datatype
11 Written and maintained by Raymond D. Hettinger <python@rcn.com>
Raymond Hettingereb6b5542015-02-10 22:37:22 -060012 Copyright (c) 2004-2015 Python Software Foundation.
Raymond Hettinger756b3f32004-01-29 06:37:52 +000013 All rights reserved.
14*/
15
Raymond Hettinger77e8bf12004-10-01 15:25:53 +000016/* The block length may be set to any number over 1. Larger numbers
Raymond Hettinger20b0f872013-06-23 15:44:33 -070017 * reduce the number of calls to the memory allocator, give faster
Raymond Hettinger30c90742015-03-02 22:31:35 -080018 * indexing and rotation, and reduce the link to data overhead ratio.
Raymond Hettingerdaf57f22015-02-26 23:21:29 -080019 * Making the block length a power of two speeds-up the modulo
Raymond Hettinger30c90742015-03-02 22:31:35 -080020 * and division calculations in deque_item() and deque_ass_item().
Raymond Hettinger77e8bf12004-10-01 15:25:53 +000021 */
22
Raymond Hettingerdaf57f22015-02-26 23:21:29 -080023#define BLOCKLEN 64
Raymond Hettinger61f05fb2004-10-01 06:24:12 +000024#define CENTER ((BLOCKLEN - 1) / 2)
Raymond Hettinger756b3f32004-01-29 06:37:52 +000025
Raymond Hettinger551350a2015-03-24 00:19:53 -070026/* Data for deque objects is stored in a doubly-linked list of fixed
27 * length blocks. This assures that appends or pops never move any
28 * other data elements besides the one being appended or popped.
29 *
30 * Another advantage is that it completely avoids use of realloc(),
31 * resulting in more predictable performance.
32 *
33 * Textbook implementations of doubly-linked lists store one datum
34 * per link, but that gives them a 200% memory overhead (a prev and
35 * next link for each datum) and it costs one malloc() call per data
36 * element. By using fixed-length blocks, the link to data ratio is
37 * significantly improved and there are proportionally fewer calls
38 * to malloc() and free(). The data blocks of consecutive pointers
39 * also improve cache locality.
40 *
Raymond Hettinger61f05fb2004-10-01 06:24:12 +000041 * The list of blocks is never empty, so d.leftblock and d.rightblock
Raymond Hettinger82df9252013-07-07 01:43:42 -100042 * are never equal to NULL. The list is not circular.
43 *
44 * A deque d's first element is at d.leftblock[leftindex]
45 * and its last element is at d.rightblock[rightindex].
Raymond Hettinger61f05fb2004-10-01 06:24:12 +000046 *
Raymond Hettinger551350a2015-03-24 00:19:53 -070047 * Unlike Python slice indices, these indices are inclusive on both
48 * ends. This makes the algorithms for left and right operations
49 * more symmetrical and it simplifies the design.
Raymond Hettinger61f05fb2004-10-01 06:24:12 +000050 *
Raymond Hettinger551350a2015-03-24 00:19:53 -070051 * The indices, d.leftindex and d.rightindex are always in the range:
52 * 0 <= index < BLOCKLEN
53 *
54 * And their exact relationship is:
55 * (d.leftindex + d.len - 1) % BLOCKLEN == d.rightindex
Raymond Hettinger61f05fb2004-10-01 06:24:12 +000056 *
Raymond Hettinger8dbbae22015-03-24 21:01:50 -070057 * Whenever d.leftblock == d.rightblock, then:
Raymond Hettinger551350a2015-03-24 00:19:53 -070058 * d.leftindex + d.len - 1 == d.rightindex
Thomas Wouters0e3f5912006-08-11 14:57:12 +000059 *
Raymond Hettinger551350a2015-03-24 00:19:53 -070060 * However, when d.leftblock != d.rightblock, the d.leftindex and
61 * d.rightindex become indices into distinct blocks and either may
62 * be larger than the other.
63 *
64 * Empty deques have:
65 * d.len == 0
66 * d.leftblock == d.rightblock
67 * d.leftindex == CENTER + 1
68 * d.rightindex == CENTER
69 *
70 * Checking for d.len == 0 is the intended way to see whether d is empty.
Tim Petersd8768d32004-10-01 01:32:53 +000071 */
72
Raymond Hettinger756b3f32004-01-29 06:37:52 +000073typedef struct BLOCK {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000074 struct BLOCK *leftlink;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000075 PyObject *data[BLOCKLEN];
Raymond Hettinger20b0f872013-06-23 15:44:33 -070076 struct BLOCK *rightlink;
Raymond Hettinger756b3f32004-01-29 06:37:52 +000077} block;
78
Raymond Hettinger30c90742015-03-02 22:31:35 -080079typedef struct {
80 PyObject_VAR_HEAD
81 block *leftblock;
82 block *rightblock;
Raymond Hettinger551350a2015-03-24 00:19:53 -070083 Py_ssize_t leftindex; /* 0 <= leftindex < BLOCKLEN */
84 Py_ssize_t rightindex; /* 0 <= rightindex < BLOCKLEN */
Raymond Hettingerf9d9c792015-03-02 22:47:46 -080085 size_t state; /* incremented whenever the indices move */
Raymond Hettinger30c90742015-03-02 22:31:35 -080086 Py_ssize_t maxlen;
Raymond Hettinger0f6f9472015-03-21 01:42:10 -070087 PyObject *weakreflist;
Raymond Hettinger30c90742015-03-02 22:31:35 -080088} dequeobject;
89
90static PyTypeObject deque_type;
91
Raymond Hettinger82df9252013-07-07 01:43:42 -100092/* For debug builds, add error checking to track the endpoints
93 * in the chain of links. The goal is to make sure that link
94 * assignments only take place at endpoints so that links already
95 * in use do not get overwritten.
96 *
97 * CHECK_END should happen before each assignment to a block's link field.
98 * MARK_END should happen whenever a link field becomes a new endpoint.
99 * This happens when new blocks are added or whenever an existing
100 * block is freed leaving another existing block as the new endpoint.
101 */
102
Raymond Hettinger3223dd52013-07-26 23:14:22 -0700103#ifndef NDEBUG
Raymond Hettinger82df9252013-07-07 01:43:42 -1000104#define MARK_END(link) link = NULL;
105#define CHECK_END(link) assert(link == NULL);
106#define CHECK_NOT_END(link) assert(link != NULL);
107#else
108#define MARK_END(link)
109#define CHECK_END(link)
110#define CHECK_NOT_END(link)
111#endif
112
Raymond Hettinger41290a62015-03-31 08:12:23 -0700113/* To prevent len from overflowing PY_SSIZE_T_MAX, we refuse to
114 allocate new blocks if the current len is nearing overflow.
115*/
116
117#define MAX_DEQUE_LEN (PY_SSIZE_T_MAX - 3*BLOCKLEN)
118
Raymond Hettinger82df9252013-07-07 01:43:42 -1000119/* A simple freelisting scheme is used to minimize calls to the memory
Raymond Hettinger551350a2015-03-24 00:19:53 -0700120 allocator. It accommodates common use cases where new blocks are being
Raymond Hettinger82df9252013-07-07 01:43:42 -1000121 added at about the same rate as old blocks are being freed.
122 */
123
Guido van Rossum58da9312007-11-10 23:39:45 +0000124#define MAXFREEBLOCKS 10
Benjamin Petersond6313712008-07-31 16:23:04 +0000125static Py_ssize_t numfreeblocks = 0;
Guido van Rossum58da9312007-11-10 23:39:45 +0000126static block *freeblocks[MAXFREEBLOCKS];
127
Tim Peters6f853562004-10-01 01:04:50 +0000128static block *
Raymond Hettinger82df9252013-07-07 01:43:42 -1000129newblock(Py_ssize_t len) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000130 block *b;
Raymond Hettinger41290a62015-03-31 08:12:23 -0700131 if (len >= MAX_DEQUE_LEN) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000132 PyErr_SetString(PyExc_OverflowError,
133 "cannot add more blocks to the deque");
134 return NULL;
135 }
136 if (numfreeblocks) {
Raymond Hettinger59cf23a2013-02-07 00:57:19 -0500137 numfreeblocks--;
Raymond Hettinger82df9252013-07-07 01:43:42 -1000138 return freeblocks[numfreeblocks];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000139 }
Raymond Hettinger82df9252013-07-07 01:43:42 -1000140 b = PyMem_Malloc(sizeof(block));
141 if (b != NULL) {
142 return b;
143 }
144 PyErr_NoMemory();
145 return NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000146}
147
Martin v. Löwis59683e82008-06-13 07:50:45 +0000148static void
Guido van Rossum58da9312007-11-10 23:39:45 +0000149freeblock(block *b)
150{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000151 if (numfreeblocks < MAXFREEBLOCKS) {
152 freeblocks[numfreeblocks] = b;
153 numfreeblocks++;
154 } else {
155 PyMem_Free(b);
156 }
Guido van Rossum58da9312007-11-10 23:39:45 +0000157}
158
Raymond Hettingerda2850f2015-02-27 12:42:54 -0800159/* XXX Todo:
Raymond Hettinger54023152014-04-23 00:58:48 -0700160 If aligned memory allocations become available, make the
161 deque object 64 byte aligned so that all of the fields
162 can be retrieved or updated in a single cache line.
163*/
164
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000165static PyObject *
166deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
167{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000168 dequeobject *deque;
169 block *b;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000170
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000171 /* create dequeobject structure */
172 deque = (dequeobject *)type->tp_alloc(type, 0);
173 if (deque == NULL)
174 return NULL;
Tim Peters1065f752004-10-01 01:03:29 +0000175
Raymond Hettinger82df9252013-07-07 01:43:42 -1000176 b = newblock(0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000177 if (b == NULL) {
178 Py_DECREF(deque);
179 return NULL;
180 }
Raymond Hettinger82df9252013-07-07 01:43:42 -1000181 MARK_END(b->leftlink);
182 MARK_END(b->rightlink);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000183
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000184 assert(BLOCKLEN >= 2);
Raymond Hettinger87e69122015-03-02 23:32:02 -0800185 Py_SIZE(deque) = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 deque->leftblock = b;
187 deque->rightblock = b;
188 deque->leftindex = CENTER + 1;
189 deque->rightindex = CENTER;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000190 deque->state = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000191 deque->maxlen = -1;
Raymond Hettinger87e69122015-03-02 23:32:02 -0800192 deque->weakreflist = NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000193
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000194 return (PyObject *)deque;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000195}
196
197static PyObject *
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000198deque_pop(dequeobject *deque, PyObject *unused)
199{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000200 PyObject *item;
201 block *prevblock;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000202
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000203 if (Py_SIZE(deque) == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000204 PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
205 return NULL;
206 }
207 item = deque->rightblock->data[deque->rightindex];
208 deque->rightindex--;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000209 Py_SIZE(deque)--;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000210 deque->state++;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000211
Raymond Hettingerd3d2b2c2015-09-21 23:41:56 -0700212 if (deque->rightindex < 0) {
Raymond Hettinger8dbbae22015-03-24 21:01:50 -0700213 if (Py_SIZE(deque)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 prevblock = deque->rightblock->leftlink;
215 assert(deque->leftblock != deque->rightblock);
216 freeblock(deque->rightblock);
Raymond Hettinger82df9252013-07-07 01:43:42 -1000217 CHECK_NOT_END(prevblock);
218 MARK_END(prevblock->rightlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000219 deque->rightblock = prevblock;
220 deque->rightindex = BLOCKLEN - 1;
Raymond Hettinger8dbbae22015-03-24 21:01:50 -0700221 } else {
222 assert(deque->leftblock == deque->rightblock);
223 assert(deque->leftindex == deque->rightindex+1);
224 /* re-center instead of freeing a block */
225 deque->leftindex = CENTER + 1;
226 deque->rightindex = CENTER;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000227 }
228 }
229 return item;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000230}
231
232PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element.");
233
234static PyObject *
235deque_popleft(dequeobject *deque, PyObject *unused)
236{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000237 PyObject *item;
238 block *prevblock;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000239
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000240 if (Py_SIZE(deque) == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000241 PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
242 return NULL;
243 }
244 assert(deque->leftblock != NULL);
245 item = deque->leftblock->data[deque->leftindex];
246 deque->leftindex++;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000247 Py_SIZE(deque)--;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000248 deque->state++;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000250 if (deque->leftindex == BLOCKLEN) {
Raymond Hettinger8dbbae22015-03-24 21:01:50 -0700251 if (Py_SIZE(deque)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000252 assert(deque->leftblock != deque->rightblock);
253 prevblock = deque->leftblock->rightlink;
254 freeblock(deque->leftblock);
Raymond Hettinger82df9252013-07-07 01:43:42 -1000255 CHECK_NOT_END(prevblock);
256 MARK_END(prevblock->leftlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257 deque->leftblock = prevblock;
258 deque->leftindex = 0;
Raymond Hettinger8dbbae22015-03-24 21:01:50 -0700259 } else {
260 assert(deque->leftblock == deque->rightblock);
261 assert(deque->leftindex == deque->rightindex+1);
262 /* re-center instead of freeing a block */
263 deque->leftindex = CENTER + 1;
264 deque->rightindex = CENTER;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000265 }
266 }
267 return item;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000268}
269
270PyDoc_STRVAR(popleft_doc, "Remove and return the leftmost element.");
271
Raymond Hettingerf30f5b92015-03-02 22:23:37 -0800272/* The deque's size limit is d.maxlen. The limit can be zero or positive.
273 * If there is no limit, then d.maxlen == -1.
274 *
275 * After an item is added to a deque, we check to see if the size has grown past
276 * the limit. If it has, we get the size back down to the limit by popping an
277 * item off of the opposite end. The methods that can trigger this are append(),
278 * appendleft(), extend(), and extendleft().
279 */
280
281static void
282deque_trim_right(dequeobject *deque)
283{
284 if (deque->maxlen != -1 && Py_SIZE(deque) > deque->maxlen) {
285 PyObject *rv = deque_pop(deque, NULL);
286 assert(rv != NULL);
287 assert(Py_SIZE(deque) <= deque->maxlen);
288 Py_DECREF(rv);
289 }
290}
291
292static void
293deque_trim_left(dequeobject *deque)
294{
295 if (deque->maxlen != -1 && Py_SIZE(deque) > deque->maxlen) {
296 PyObject *rv = deque_popleft(deque, NULL);
297 assert(rv != NULL);
298 assert(Py_SIZE(deque) <= deque->maxlen);
299 Py_DECREF(rv);
300 }
301}
302
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000303static PyObject *
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000304deque_append(dequeobject *deque, PyObject *item)
305{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 deque->state++;
Raymond Hettinger8dbbae22015-03-24 21:01:50 -0700307 if (deque->rightindex == BLOCKLEN - 1) {
Raymond Hettinger82df9252013-07-07 01:43:42 -1000308 block *b = newblock(Py_SIZE(deque));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 if (b == NULL)
310 return NULL;
Raymond Hettinger82df9252013-07-07 01:43:42 -1000311 b->leftlink = deque->rightblock;
312 CHECK_END(deque->rightblock->rightlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 deque->rightblock->rightlink = b;
314 deque->rightblock = b;
Raymond Hettinger82df9252013-07-07 01:43:42 -1000315 MARK_END(b->rightlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000316 deque->rightindex = -1;
317 }
318 Py_INCREF(item);
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000319 Py_SIZE(deque)++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320 deque->rightindex++;
321 deque->rightblock->data[deque->rightindex] = item;
Raymond Hettingerf30f5b92015-03-02 22:23:37 -0800322 deque_trim_left(deque);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 Py_RETURN_NONE;
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000324}
325
326PyDoc_STRVAR(append_doc, "Add an element to the right side of the deque.");
327
328static PyObject *
329deque_appendleft(dequeobject *deque, PyObject *item)
330{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000331 deque->state++;
332 if (deque->leftindex == 0) {
Raymond Hettinger82df9252013-07-07 01:43:42 -1000333 block *b = newblock(Py_SIZE(deque));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000334 if (b == NULL)
335 return NULL;
Raymond Hettinger82df9252013-07-07 01:43:42 -1000336 b->rightlink = deque->leftblock;
337 CHECK_END(deque->leftblock->leftlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000338 deque->leftblock->leftlink = b;
339 deque->leftblock = b;
Raymond Hettinger82df9252013-07-07 01:43:42 -1000340 MARK_END(b->leftlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000341 deque->leftindex = BLOCKLEN;
342 }
343 Py_INCREF(item);
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000344 Py_SIZE(deque)++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000345 deque->leftindex--;
346 deque->leftblock->data[deque->leftindex] = item;
Raymond Hettingerf30f5b92015-03-02 22:23:37 -0800347 deque_trim_right(deque);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000348 Py_RETURN_NONE;
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000349}
350
351PyDoc_STRVAR(appendleft_doc, "Add an element to the left side of the deque.");
352
Raymond Hettinger060c7f62009-03-10 09:36:07 +0000353
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000354/* Run an iterator to exhaustion. Shortcut for
Raymond Hettinger060c7f62009-03-10 09:36:07 +0000355 the extend/extendleft methods when maxlen == 0. */
356static PyObject*
357consume_iterator(PyObject *it)
358{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359 PyObject *item;
Raymond Hettinger060c7f62009-03-10 09:36:07 +0000360
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000361 while ((item = PyIter_Next(it)) != NULL) {
362 Py_DECREF(item);
363 }
364 Py_DECREF(it);
365 if (PyErr_Occurred())
366 return NULL;
367 Py_RETURN_NONE;
Raymond Hettinger060c7f62009-03-10 09:36:07 +0000368}
369
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000370static PyObject *
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000371deque_extend(dequeobject *deque, PyObject *iterable)
372{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373 PyObject *it, *item;
Raymond Hettinger0e14e662015-09-19 00:21:33 -0600374 int trim = (deque->maxlen != -1);
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000376 /* Handle case where id(deque) == id(iterable) */
377 if ((PyObject *)deque == iterable) {
378 PyObject *result;
379 PyObject *s = PySequence_List(iterable);
380 if (s == NULL)
381 return NULL;
382 result = deque_extend(deque, s);
383 Py_DECREF(s);
384 return result;
385 }
Raymond Hettinger3f9afd82009-12-10 03:03:02 +0000386
Raymond Hettingerd9c116c2013-07-09 00:13:21 -0700387 /* Space saving heuristic. Start filling from the left */
388 if (Py_SIZE(deque) == 0) {
389 assert(deque->leftblock == deque->rightblock);
390 assert(deque->leftindex == deque->rightindex+1);
391 deque->leftindex = 1;
392 deque->rightindex = 0;
393 }
394
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000395 it = PyObject_GetIter(iterable);
396 if (it == NULL)
397 return NULL;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000398
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399 if (deque->maxlen == 0)
400 return consume_iterator(it);
Raymond Hettinger060c7f62009-03-10 09:36:07 +0000401
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 while ((item = PyIter_Next(it)) != NULL) {
403 deque->state++;
Raymond Hettinger8dbbae22015-03-24 21:01:50 -0700404 if (deque->rightindex == BLOCKLEN - 1) {
Raymond Hettinger82df9252013-07-07 01:43:42 -1000405 block *b = newblock(Py_SIZE(deque));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000406 if (b == NULL) {
407 Py_DECREF(item);
408 Py_DECREF(it);
409 return NULL;
410 }
Raymond Hettinger82df9252013-07-07 01:43:42 -1000411 b->leftlink = deque->rightblock;
412 CHECK_END(deque->rightblock->rightlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 deque->rightblock->rightlink = b;
414 deque->rightblock = b;
Raymond Hettinger82df9252013-07-07 01:43:42 -1000415 MARK_END(b->rightlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000416 deque->rightindex = -1;
417 }
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000418 Py_SIZE(deque)++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000419 deque->rightindex++;
420 deque->rightblock->data[deque->rightindex] = item;
Raymond Hettinger0e14e662015-09-19 00:21:33 -0600421 if (trim)
422 deque_trim_left(deque);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000423 }
Raymond Hettinger2b2b7532015-09-05 17:05:52 -0700424 if (PyErr_Occurred()) {
425 Py_DECREF(it);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 return NULL;
Raymond Hettinger2b2b7532015-09-05 17:05:52 -0700427 }
428 Py_DECREF(it);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000429 Py_RETURN_NONE;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000430}
431
Tim Peters1065f752004-10-01 01:03:29 +0000432PyDoc_STRVAR(extend_doc,
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000433"Extend the right side of the deque with elements from the iterable");
434
435static PyObject *
436deque_extendleft(dequeobject *deque, PyObject *iterable)
437{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000438 PyObject *it, *item;
Raymond Hettinger0e14e662015-09-19 00:21:33 -0600439 int trim = (deque->maxlen != -1);
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441 /* Handle case where id(deque) == id(iterable) */
442 if ((PyObject *)deque == iterable) {
443 PyObject *result;
444 PyObject *s = PySequence_List(iterable);
445 if (s == NULL)
446 return NULL;
447 result = deque_extendleft(deque, s);
448 Py_DECREF(s);
449 return result;
450 }
Raymond Hettinger3f9afd82009-12-10 03:03:02 +0000451
Raymond Hettingerd9c116c2013-07-09 00:13:21 -0700452 /* Space saving heuristic. Start filling from the right */
453 if (Py_SIZE(deque) == 0) {
454 assert(deque->leftblock == deque->rightblock);
455 assert(deque->leftindex == deque->rightindex+1);
456 deque->leftindex = BLOCKLEN - 1;
457 deque->rightindex = BLOCKLEN - 2;
458 }
459
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000460 it = PyObject_GetIter(iterable);
461 if (it == NULL)
462 return NULL;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000463
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000464 if (deque->maxlen == 0)
465 return consume_iterator(it);
Raymond Hettinger060c7f62009-03-10 09:36:07 +0000466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000467 while ((item = PyIter_Next(it)) != NULL) {
468 deque->state++;
469 if (deque->leftindex == 0) {
Raymond Hettinger82df9252013-07-07 01:43:42 -1000470 block *b = newblock(Py_SIZE(deque));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000471 if (b == NULL) {
472 Py_DECREF(item);
473 Py_DECREF(it);
474 return NULL;
475 }
Raymond Hettinger82df9252013-07-07 01:43:42 -1000476 b->rightlink = deque->leftblock;
477 CHECK_END(deque->leftblock->leftlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 deque->leftblock->leftlink = b;
479 deque->leftblock = b;
Raymond Hettinger82df9252013-07-07 01:43:42 -1000480 MARK_END(b->leftlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000481 deque->leftindex = BLOCKLEN;
482 }
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000483 Py_SIZE(deque)++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 deque->leftindex--;
485 deque->leftblock->data[deque->leftindex] = item;
Raymond Hettinger0e14e662015-09-19 00:21:33 -0600486 if (trim)
487 deque_trim_right(deque);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000488 }
Raymond Hettinger2b2b7532015-09-05 17:05:52 -0700489 if (PyErr_Occurred()) {
490 Py_DECREF(it);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000491 return NULL;
Raymond Hettinger2b2b7532015-09-05 17:05:52 -0700492 }
493 Py_DECREF(it);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 Py_RETURN_NONE;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000495}
496
Tim Peters1065f752004-10-01 01:03:29 +0000497PyDoc_STRVAR(extendleft_doc,
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000498"Extend the left side of the deque with elements from the iterable");
499
Raymond Hettinger3f9afd82009-12-10 03:03:02 +0000500static PyObject *
501deque_inplace_concat(dequeobject *deque, PyObject *other)
502{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000503 PyObject *result;
Raymond Hettinger3f9afd82009-12-10 03:03:02 +0000504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000505 result = deque_extend(deque, other);
506 if (result == NULL)
507 return result;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 Py_INCREF(deque);
Raymond Hettinger2b2b7532015-09-05 17:05:52 -0700509 Py_DECREF(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 return (PyObject *)deque;
Raymond Hettinger3f9afd82009-12-10 03:03:02 +0000511}
512
Raymond Hettinger41290a62015-03-31 08:12:23 -0700513static PyObject *deque_copy(PyObject *deque);
514
515static PyObject *
516deque_concat(dequeobject *deque, PyObject *other)
517{
Benjamin Peterson1a629212015-04-04 10:52:36 -0400518 PyObject *new_deque, *result;
Raymond Hettinger41290a62015-03-31 08:12:23 -0700519 int rv;
520
521 rv = PyObject_IsInstance(other, (PyObject *)&deque_type);
522 if (rv <= 0) {
523 if (rv == 0) {
524 PyErr_Format(PyExc_TypeError,
525 "can only concatenate deque (not \"%.200s\") to deque",
526 other->ob_type->tp_name);
527 }
528 return NULL;
529 }
530
531 new_deque = deque_copy((PyObject *)deque);
532 if (new_deque == NULL)
533 return NULL;
Benjamin Peterson1a629212015-04-04 10:52:36 -0400534 result = deque_extend((dequeobject *)new_deque, other);
535 if (result == NULL) {
536 Py_DECREF(new_deque);
537 return NULL;
538 }
539 Py_DECREF(result);
540 return new_deque;
Raymond Hettinger41290a62015-03-31 08:12:23 -0700541}
542
543static void deque_clear(dequeobject *deque);
544
545static PyObject *
Raymond Hettinger41290a62015-03-31 08:12:23 -0700546deque_inplace_repeat(dequeobject *deque, Py_ssize_t n)
547{
548 Py_ssize_t i, size;
549 PyObject *seq;
550 PyObject *rv;
551
552 size = Py_SIZE(deque);
553 if (size == 0 || n == 1) {
554 Py_INCREF(deque);
555 return (PyObject *)deque;
556 }
557
558 if (n <= 0) {
559 deque_clear(deque);
560 Py_INCREF(deque);
561 return (PyObject *)deque;
562 }
563
Raymond Hettinger41290a62015-03-31 08:12:23 -0700564 if (size == 1) {
565 /* common case, repeating a single element */
566 PyObject *item = deque->leftblock->data[deque->leftindex];
567
568 if (deque->maxlen != -1 && n > deque->maxlen)
569 n = deque->maxlen;
570
Raymond Hettingerf5d72f32015-09-09 22:39:44 -0400571 if (n > MAX_DEQUE_LEN)
572 return PyErr_NoMemory();
573
Raymond Hettinger67c78b52015-09-12 11:00:20 -0400574 deque->state++;
Raymond Hettingerad262252015-09-14 01:03:04 -0400575 for (i = 0 ; i < n-1 ; ) {
Raymond Hettinger67c78b52015-09-12 11:00:20 -0400576 if (deque->rightindex == BLOCKLEN - 1) {
577 block *b = newblock(Py_SIZE(deque) + i);
578 if (b == NULL) {
579 Py_SIZE(deque) += i;
580 return NULL;
581 }
582 b->leftlink = deque->rightblock;
583 CHECK_END(deque->rightblock->rightlink);
584 deque->rightblock->rightlink = b;
585 deque->rightblock = b;
586 MARK_END(b->rightlink);
587 deque->rightindex = -1;
588 }
Raymond Hettingerad262252015-09-14 01:03:04 -0400589 for ( ; i < n-1 && deque->rightindex != BLOCKLEN - 1 ; i++) {
590 deque->rightindex++;
591 Py_INCREF(item);
592 deque->rightblock->data[deque->rightindex] = item;
593 }
Raymond Hettinger41290a62015-03-31 08:12:23 -0700594 }
Raymond Hettinger67c78b52015-09-12 11:00:20 -0400595 Py_SIZE(deque) += i;
Raymond Hettinger41290a62015-03-31 08:12:23 -0700596 Py_INCREF(deque);
597 return (PyObject *)deque;
598 }
599
Raymond Hettingerf5d72f32015-09-09 22:39:44 -0400600 if ((size_t)size > MAX_DEQUE_LEN / (size_t)n) {
601 return PyErr_NoMemory();
602 }
603
Raymond Hettinger41290a62015-03-31 08:12:23 -0700604 seq = PySequence_List((PyObject *)deque);
605 if (seq == NULL)
606 return seq;
607
608 for (i = 0 ; i < n-1 ; i++) {
609 rv = deque_extend(deque, seq);
610 if (rv == NULL) {
611 Py_DECREF(seq);
612 return NULL;
613 }
614 Py_DECREF(rv);
615 }
616 Py_INCREF(deque);
617 Py_DECREF(seq);
618 return (PyObject *)deque;
619}
620
Raymond Hettingerf5d72f32015-09-09 22:39:44 -0400621static PyObject *
622deque_repeat(dequeobject *deque, Py_ssize_t n)
623{
624 dequeobject *new_deque;
Raymond Hettinger95e2cc52015-09-13 02:41:18 -0400625 PyObject *rv;
Raymond Hettingerf5d72f32015-09-09 22:39:44 -0400626
627 new_deque = (dequeobject *)deque_copy((PyObject *) deque);
628 if (new_deque == NULL)
629 return NULL;
Raymond Hettinger95e2cc52015-09-13 02:41:18 -0400630 rv = deque_inplace_repeat(new_deque, n);
631 Py_DECREF(new_deque);
632 return rv;
Raymond Hettingerf5d72f32015-09-09 22:39:44 -0400633}
634
Raymond Hettinger54023152014-04-23 00:58:48 -0700635/* The rotate() method is part of the public API and is used internally
636as a primitive for other methods.
637
638Rotation by 1 or -1 is a common case, so any optimizations for high
639volume rotations should take care not to penalize the common case.
640
641Conceptually, a rotate by one is equivalent to a pop on one side and an
642append on the other. However, a pop/append pair is unnecessarily slow
643because it requires a incref/decref pair for an object located randomly
644in memory. It is better to just move the object pointer from one block
645to the next without changing the reference count.
646
647When moving batches of pointers, it is tempting to use memcpy() but that
648proved to be slower than a simple loop for a variety of reasons.
649Memcpy() cannot know in advance that we're copying pointers instead of
650bytes, that the source and destination are pointer aligned and
651non-overlapping, that moving just one pointer is a common case, that we
652never need to move more than BLOCKLEN pointers, and that at least one
653pointer is always moved.
654
655For high volume rotations, newblock() and freeblock() are never called
656more than once. Previously emptied blocks are immediately reused as a
657destination block. If a block is left-over at the end, it is freed.
658*/
659
Raymond Hettingerdcb9d942004-10-09 16:02:18 +0000660static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000661_deque_rotate(dequeobject *deque, Py_ssize_t n)
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000662{
Raymond Hettinger3959af92013-07-13 02:34:08 -0700663 block *b = NULL;
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700664 block *leftblock = deque->leftblock;
665 block *rightblock = deque->rightblock;
666 Py_ssize_t leftindex = deque->leftindex;
667 Py_ssize_t rightindex = deque->rightindex;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000668 Py_ssize_t len=Py_SIZE(deque), halflen=len>>1;
Raymond Hettinger3959af92013-07-13 02:34:08 -0700669 int rv = -1;
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000670
Raymond Hettinger464d89b2013-01-11 22:29:50 -0800671 if (len <= 1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000672 return 0;
673 if (n > halflen || n < -halflen) {
674 n %= len;
675 if (n > halflen)
676 n -= len;
677 else if (n < -halflen)
678 n += len;
679 }
Raymond Hettinger1f0044c2013-02-05 01:30:46 -0500680 assert(len > 1);
Raymond Hettingera4409c12013-02-04 00:08:12 -0500681 assert(-halflen <= n && n <= halflen);
Raymond Hettinger231ee4d2013-02-02 11:24:43 -0800682
Raymond Hettinger464d89b2013-01-11 22:29:50 -0800683 deque->state++;
Raymond Hettinger1f0044c2013-02-05 01:30:46 -0500684 while (n > 0) {
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700685 if (leftindex == 0) {
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700686 if (b == NULL) {
Raymond Hettinger3959af92013-07-13 02:34:08 -0700687 b = newblock(len);
688 if (b == NULL)
689 goto done;
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700690 }
Raymond Hettinger82df9252013-07-07 01:43:42 -1000691 b->rightlink = leftblock;
692 CHECK_END(leftblock->leftlink);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700693 leftblock->leftlink = b;
694 leftblock = b;
Raymond Hettinger82df9252013-07-07 01:43:42 -1000695 MARK_END(b->leftlink);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700696 leftindex = BLOCKLEN;
Raymond Hettinger3959af92013-07-13 02:34:08 -0700697 b = NULL;
Raymond Hettinger464d89b2013-01-11 22:29:50 -0800698 }
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700699 assert(leftindex > 0);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700700 {
701 PyObject **src, **dest;
702 Py_ssize_t m = n;
Raymond Hettinger21777ac2013-02-02 09:56:08 -0800703
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700704 if (m > rightindex + 1)
705 m = rightindex + 1;
706 if (m > leftindex)
707 m = leftindex;
708 assert (m > 0 && m <= len);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700709 rightindex -= m;
710 leftindex -= m;
Raymond Hettinger0e259f12015-02-01 22:53:41 -0800711 src = &rightblock->data[rightindex + 1];
712 dest = &leftblock->data[leftindex];
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700713 n -= m;
Raymond Hettinger840533b2013-07-13 17:03:58 -0700714 do {
Raymond Hettinger0e259f12015-02-01 22:53:41 -0800715 *(dest++) = *(src++);
Raymond Hettinger840533b2013-07-13 17:03:58 -0700716 } while (--m);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700717 }
Raymond Hettingerd3d2b2c2015-09-21 23:41:56 -0700718 if (rightindex < 0) {
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700719 assert(leftblock != rightblock);
Raymond Hettinger840533b2013-07-13 17:03:58 -0700720 assert(b == NULL);
Raymond Hettinger3959af92013-07-13 02:34:08 -0700721 b = rightblock;
Raymond Hettingerb97cc492013-07-21 01:51:07 -0700722 CHECK_NOT_END(rightblock->leftlink);
723 rightblock = rightblock->leftlink;
724 MARK_END(rightblock->rightlink);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700725 rightindex = BLOCKLEN - 1;
Raymond Hettinger464d89b2013-01-11 22:29:50 -0800726 }
Raymond Hettinger21777ac2013-02-02 09:56:08 -0800727 }
Raymond Hettinger1f0044c2013-02-05 01:30:46 -0500728 while (n < 0) {
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700729 if (rightindex == BLOCKLEN - 1) {
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700730 if (b == NULL) {
Raymond Hettinger3959af92013-07-13 02:34:08 -0700731 b = newblock(len);
732 if (b == NULL)
733 goto done;
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700734 }
Raymond Hettinger82df9252013-07-07 01:43:42 -1000735 b->leftlink = rightblock;
736 CHECK_END(rightblock->rightlink);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700737 rightblock->rightlink = b;
738 rightblock = b;
Raymond Hettinger82df9252013-07-07 01:43:42 -1000739 MARK_END(b->rightlink);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700740 rightindex = -1;
Raymond Hettinger3959af92013-07-13 02:34:08 -0700741 b = NULL;
Raymond Hettinger464d89b2013-01-11 22:29:50 -0800742 }
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700743 assert (rightindex < BLOCKLEN - 1);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700744 {
745 PyObject **src, **dest;
746 Py_ssize_t m = -n;
Raymond Hettinger21777ac2013-02-02 09:56:08 -0800747
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700748 if (m > BLOCKLEN - leftindex)
749 m = BLOCKLEN - leftindex;
750 if (m > BLOCKLEN - 1 - rightindex)
751 m = BLOCKLEN - 1 - rightindex;
752 assert (m > 0 && m <= len);
753 src = &leftblock->data[leftindex];
754 dest = &rightblock->data[rightindex + 1];
755 leftindex += m;
756 rightindex += m;
757 n += m;
Raymond Hettinger840533b2013-07-13 17:03:58 -0700758 do {
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700759 *(dest++) = *(src++);
Raymond Hettinger840533b2013-07-13 17:03:58 -0700760 } while (--m);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700761 }
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700762 if (leftindex == BLOCKLEN) {
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700763 assert(leftblock != rightblock);
Raymond Hettinger840533b2013-07-13 17:03:58 -0700764 assert(b == NULL);
Raymond Hettinger3959af92013-07-13 02:34:08 -0700765 b = leftblock;
Raymond Hettingerb97cc492013-07-21 01:51:07 -0700766 CHECK_NOT_END(leftblock->rightlink);
767 leftblock = leftblock->rightlink;
768 MARK_END(leftblock->leftlink);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700769 leftindex = 0;
Raymond Hettinger21777ac2013-02-02 09:56:08 -0800770 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000771 }
Raymond Hettinger3959af92013-07-13 02:34:08 -0700772 rv = 0;
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700773done:
Raymond Hettinger3959af92013-07-13 02:34:08 -0700774 if (b != NULL)
775 freeblock(b);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700776 deque->leftblock = leftblock;
777 deque->rightblock = rightblock;
778 deque->leftindex = leftindex;
779 deque->rightindex = rightindex;
780
781 return rv;
Raymond Hettingerdcb9d942004-10-09 16:02:18 +0000782}
783
784static PyObject *
785deque_rotate(dequeobject *deque, PyObject *args)
786{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000787 Py_ssize_t n=1;
Raymond Hettingerdcb9d942004-10-09 16:02:18 +0000788
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000789 if (!PyArg_ParseTuple(args, "|n:rotate", &n))
790 return NULL;
Raymond Hettinger6921c132015-03-21 02:03:40 -0700791 if (!_deque_rotate(deque, n))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000792 Py_RETURN_NONE;
793 return NULL;
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000794}
795
Tim Peters1065f752004-10-01 01:03:29 +0000796PyDoc_STRVAR(rotate_doc,
Raymond Hettingeree33b272004-02-08 04:05:26 +0000797"Rotate the deque n steps to the right (default n=1). If n is negative, rotates left.");
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000798
Raymond Hettingere5fdedb2009-12-10 00:47:21 +0000799static PyObject *
800deque_reverse(dequeobject *deque, PyObject *unused)
801{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000802 block *leftblock = deque->leftblock;
803 block *rightblock = deque->rightblock;
804 Py_ssize_t leftindex = deque->leftindex;
805 Py_ssize_t rightindex = deque->rightindex;
Raymond Hettingercfe5b6c2015-07-20 00:25:50 -0400806 Py_ssize_t n = Py_SIZE(deque) >> 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000807 PyObject *tmp;
Raymond Hettingere5fdedb2009-12-10 00:47:21 +0000808
Raymond Hettinger7a237232015-09-22 01:20:36 -0700809 while (n-- > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000810 /* Validate that pointers haven't met in the middle */
811 assert(leftblock != rightblock || leftindex < rightindex);
Raymond Hettinger82df9252013-07-07 01:43:42 -1000812 CHECK_NOT_END(leftblock);
813 CHECK_NOT_END(rightblock);
Raymond Hettingere5fdedb2009-12-10 00:47:21 +0000814
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000815 /* Swap */
816 tmp = leftblock->data[leftindex];
817 leftblock->data[leftindex] = rightblock->data[rightindex];
818 rightblock->data[rightindex] = tmp;
Raymond Hettingere5fdedb2009-12-10 00:47:21 +0000819
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000820 /* Advance left block/index pair */
821 leftindex++;
822 if (leftindex == BLOCKLEN) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000823 leftblock = leftblock->rightlink;
824 leftindex = 0;
825 }
Raymond Hettingere5fdedb2009-12-10 00:47:21 +0000826
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000827 /* Step backwards with the right block/index pair */
828 rightindex--;
Raymond Hettingerd3d2b2c2015-09-21 23:41:56 -0700829 if (rightindex < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000830 rightblock = rightblock->leftlink;
831 rightindex = BLOCKLEN - 1;
832 }
833 }
834 Py_RETURN_NONE;
Raymond Hettingere5fdedb2009-12-10 00:47:21 +0000835}
836
837PyDoc_STRVAR(reverse_doc,
838"D.reverse() -- reverse *IN PLACE*");
839
Raymond Hettinger44459de2010-04-03 23:20:46 +0000840static PyObject *
841deque_count(dequeobject *deque, PyObject *v)
842{
Raymond Hettingerf3a67b72013-07-06 17:49:06 -1000843 block *b = deque->leftblock;
844 Py_ssize_t index = deque->leftindex;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000845 Py_ssize_t n = Py_SIZE(deque);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000846 Py_ssize_t i;
847 Py_ssize_t count = 0;
Raymond Hettingerf9d9c792015-03-02 22:47:46 -0800848 size_t start_state = deque->state;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000849 PyObject *item;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000850 int cmp;
Raymond Hettinger44459de2010-04-03 23:20:46 +0000851
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000852 for (i=0 ; i<n ; i++) {
Raymond Hettinger82df9252013-07-07 01:43:42 -1000853 CHECK_NOT_END(b);
Raymond Hettingerf3a67b72013-07-06 17:49:06 -1000854 item = b->data[index];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000855 cmp = PyObject_RichCompareBool(item, v, Py_EQ);
856 if (cmp > 0)
857 count++;
858 else if (cmp < 0)
859 return NULL;
Raymond Hettinger44459de2010-04-03 23:20:46 +0000860
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000861 if (start_state != deque->state) {
862 PyErr_SetString(PyExc_RuntimeError,
863 "deque mutated during iteration");
864 return NULL;
865 }
Raymond Hettinger44459de2010-04-03 23:20:46 +0000866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000867 /* Advance left block/index pair */
Raymond Hettingerf3a67b72013-07-06 17:49:06 -1000868 index++;
869 if (index == BLOCKLEN) {
870 b = b->rightlink;
871 index = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000872 }
873 }
874 return PyLong_FromSsize_t(count);
Raymond Hettinger44459de2010-04-03 23:20:46 +0000875}
876
877PyDoc_STRVAR(count_doc,
878"D.count(value) -> integer -- return number of occurrences of value");
879
Raymond Hettinger39dadf72015-03-20 16:38:56 -0700880static int
881deque_contains(dequeobject *deque, PyObject *v)
882{
883 block *b = deque->leftblock;
884 Py_ssize_t index = deque->leftindex;
885 Py_ssize_t n = Py_SIZE(deque);
886 Py_ssize_t i;
887 size_t start_state = deque->state;
888 PyObject *item;
889 int cmp;
890
891 for (i=0 ; i<n ; i++) {
892 CHECK_NOT_END(b);
893 item = b->data[index];
894 cmp = PyObject_RichCompareBool(item, v, Py_EQ);
895 if (cmp) {
896 return cmp;
897 }
898 if (start_state != deque->state) {
899 PyErr_SetString(PyExc_RuntimeError,
900 "deque mutated during iteration");
901 return -1;
902 }
903 index++;
904 if (index == BLOCKLEN) {
905 b = b->rightlink;
906 index = 0;
907 }
908 }
909 return 0;
910}
911
Martin v. Löwis18e16552006-02-15 17:27:45 +0000912static Py_ssize_t
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000913deque_len(dequeobject *deque)
914{
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000915 return Py_SIZE(deque);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000916}
917
Raymond Hettinger4aec61e2005-03-18 21:20:23 +0000918static PyObject *
Raymond Hettinger32ea1652015-03-21 01:37:37 -0700919deque_index(dequeobject *deque, PyObject *args)
920{
921 Py_ssize_t i, start=0, stop=Py_SIZE(deque);
922 PyObject *v, *item;
923 block *b = deque->leftblock;
924 Py_ssize_t index = deque->leftindex;
925 size_t start_state = deque->state;
926
927 if (!PyArg_ParseTuple(args, "O|O&O&:index", &v,
928 _PyEval_SliceIndex, &start,
929 _PyEval_SliceIndex, &stop))
930 return NULL;
931 if (start < 0) {
932 start += Py_SIZE(deque);
933 if (start < 0)
934 start = 0;
935 }
936 if (stop < 0) {
937 stop += Py_SIZE(deque);
938 if (stop < 0)
939 stop = 0;
940 }
Raymond Hettinger87674ec2015-08-26 08:08:38 -0700941 if (stop > Py_SIZE(deque))
942 stop = Py_SIZE(deque);
Raymond Hettinger32ea1652015-03-21 01:37:37 -0700943
944 for (i=0 ; i<stop ; i++) {
945 if (i >= start) {
946 int cmp;
947 CHECK_NOT_END(b);
948 item = b->data[index];
949 cmp = PyObject_RichCompareBool(item, v, Py_EQ);
950 if (cmp > 0)
951 return PyLong_FromSsize_t(i);
952 else if (cmp < 0)
953 return NULL;
954 if (start_state != deque->state) {
955 PyErr_SetString(PyExc_RuntimeError,
956 "deque mutated during iteration");
957 return NULL;
958 }
959 }
960 index++;
961 if (index == BLOCKLEN) {
962 b = b->rightlink;
963 index = 0;
964 }
965 }
966 PyErr_Format(PyExc_ValueError, "%R is not in deque", v);
967 return NULL;
968}
969
970PyDoc_STRVAR(index_doc,
971"D.index(value, [start, [stop]]) -> integer -- return first index of value.\n"
972"Raises ValueError if the value is not present.");
973
Raymond Hettinger551350a2015-03-24 00:19:53 -0700974/* insert(), remove(), and delitem() are implemented in terms of
975 rotate() for simplicity and reasonable performance near the end
976 points. If for some reason these methods become popular, it is not
977 hard to re-implement this using direct data movement (similar to
978 the code used in list slice assignments) and achieve a performance
Raymond Hettingerfef9c1b2015-03-24 21:12:57 -0700979 boost (by moving each pointer only once instead of twice).
Raymond Hettinger551350a2015-03-24 00:19:53 -0700980*/
981
Raymond Hettinger32ea1652015-03-21 01:37:37 -0700982static PyObject *
983deque_insert(dequeobject *deque, PyObject *args)
984{
985 Py_ssize_t index;
986 Py_ssize_t n = Py_SIZE(deque);
987 PyObject *value;
988 PyObject *rv;
989
990 if (!PyArg_ParseTuple(args, "nO:insert", &index, &value))
991 return NULL;
992 if (index >= n)
993 return deque_append(deque, value);
994 if (index <= -n || index == 0)
995 return deque_appendleft(deque, value);
996 if (_deque_rotate(deque, -index))
997 return NULL;
998 if (index < 0)
999 rv = deque_append(deque, value);
1000 else
1001 rv = deque_appendleft(deque, value);
1002 if (rv == NULL)
1003 return NULL;
1004 Py_DECREF(rv);
1005 if (_deque_rotate(deque, index))
1006 return NULL;
1007 Py_RETURN_NONE;
1008}
1009
1010PyDoc_STRVAR(insert_doc,
1011"D.insert(index, object) -- insert object before index");
1012
1013static PyObject *
Raymond Hettinger4aec61e2005-03-18 21:20:23 +00001014deque_remove(dequeobject *deque, PyObject *value)
1015{
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001016 Py_ssize_t i, n=Py_SIZE(deque);
Raymond Hettinger4aec61e2005-03-18 21:20:23 +00001017
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001018 for (i=0 ; i<n ; i++) {
1019 PyObject *item = deque->leftblock->data[deque->leftindex];
1020 int cmp = PyObject_RichCompareBool(item, value, Py_EQ);
Raymond Hettingerd73202c2005-03-19 00:00:51 +00001021
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001022 if (Py_SIZE(deque) != n) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 PyErr_SetString(PyExc_IndexError,
1024 "deque mutated during remove().");
1025 return NULL;
1026 }
1027 if (cmp > 0) {
1028 PyObject *tgt = deque_popleft(deque, NULL);
1029 assert (tgt != NULL);
Raymond Hettinger6921c132015-03-21 02:03:40 -07001030 if (_deque_rotate(deque, i))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001031 return NULL;
Raymond Hettingerac13ad62015-03-21 01:53:16 -07001032 Py_DECREF(tgt);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001033 Py_RETURN_NONE;
1034 }
1035 else if (cmp < 0) {
1036 _deque_rotate(deque, i);
1037 return NULL;
1038 }
1039 _deque_rotate(deque, -1);
1040 }
1041 PyErr_SetString(PyExc_ValueError, "deque.remove(x): x not in deque");
1042 return NULL;
Raymond Hettinger4aec61e2005-03-18 21:20:23 +00001043}
1044
1045PyDoc_STRVAR(remove_doc,
1046"D.remove(value) -- remove first occurrence of value.");
1047
Benjamin Peterson0e5c48a2013-01-12 21:22:18 -05001048static void
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001049deque_clear(dequeobject *deque)
1050{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001051 PyObject *item;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001052
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001053 while (Py_SIZE(deque)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001054 item = deque_pop(deque, NULL);
1055 assert (item != NULL);
1056 Py_DECREF(item);
1057 }
Raymond Hettinger87e69122015-03-02 23:32:02 -08001058 assert(deque->leftblock == deque->rightblock);
1059 assert(deque->leftindex - 1 == deque->rightindex);
1060 assert(Py_SIZE(deque) == 0);
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001061}
1062
Raymond Hettinger3c186ba2015-03-02 21:45:02 -08001063static int
1064valid_index(Py_ssize_t i, Py_ssize_t limit)
1065{
Raymond Hettinger12f896c2015-07-31 12:03:20 -07001066 /* The cast to size_t lets us use just a single comparison
Raymond Hettinger3c186ba2015-03-02 21:45:02 -08001067 to check whether i is in the range: 0 <= i < limit */
1068 return (size_t) i < (size_t) limit;
1069}
1070
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001071static PyObject *
Benjamin Petersond6313712008-07-31 16:23:04 +00001072deque_item(dequeobject *deque, Py_ssize_t i)
Raymond Hettinger0a4977c2004-03-01 23:16:22 +00001073{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001074 block *b;
1075 PyObject *item;
1076 Py_ssize_t n, index=i;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +00001077
Raymond Hettinger3c186ba2015-03-02 21:45:02 -08001078 if (!valid_index(i, Py_SIZE(deque))) {
1079 PyErr_SetString(PyExc_IndexError, "deque index out of range");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001080 return NULL;
1081 }
Raymond Hettinger0a4977c2004-03-01 23:16:22 +00001082
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001083 if (i == 0) {
1084 i = deque->leftindex;
1085 b = deque->leftblock;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001086 } else if (i == Py_SIZE(deque) - 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001087 i = deque->rightindex;
1088 b = deque->rightblock;
1089 } else {
1090 i += deque->leftindex;
Raymond Hettingerc2083082015-02-28 23:29:16 -08001091 n = (Py_ssize_t)((size_t) i / BLOCKLEN);
1092 i = (Py_ssize_t)((size_t) i % BLOCKLEN);
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001093 if (index < (Py_SIZE(deque) >> 1)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001094 b = deque->leftblock;
1095 while (n--)
1096 b = b->rightlink;
1097 } else {
Raymond Hettinger63d1ff22015-02-28 07:41:30 -08001098 n = (Py_ssize_t)(
Raymond Hettingerc2083082015-02-28 23:29:16 -08001099 ((size_t)(deque->leftindex + Py_SIZE(deque) - 1))
Raymond Hettinger63d1ff22015-02-28 07:41:30 -08001100 / BLOCKLEN - n);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001101 b = deque->rightblock;
1102 while (n--)
1103 b = b->leftlink;
1104 }
1105 }
1106 item = b->data[i];
1107 Py_INCREF(item);
1108 return item;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +00001109}
1110
1111static int
Martin v. Löwis18e16552006-02-15 17:27:45 +00001112deque_del_item(dequeobject *deque, Py_ssize_t i)
Raymond Hettinger0e371f22004-05-12 20:55:56 +00001113{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001114 PyObject *item;
Raymond Hettingerac13ad62015-03-21 01:53:16 -07001115 int rv;
Raymond Hettinger0e371f22004-05-12 20:55:56 +00001116
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001117 assert (i >= 0 && i < Py_SIZE(deque));
Raymond Hettinger6921c132015-03-21 02:03:40 -07001118 if (_deque_rotate(deque, -i))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001119 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001120 item = deque_popleft(deque, NULL);
Raymond Hettingerac13ad62015-03-21 01:53:16 -07001121 rv = _deque_rotate(deque, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001122 assert (item != NULL);
1123 Py_DECREF(item);
Raymond Hettingerac13ad62015-03-21 01:53:16 -07001124 return rv;
Raymond Hettinger0e371f22004-05-12 20:55:56 +00001125}
1126
1127static int
Martin v. Löwis18e16552006-02-15 17:27:45 +00001128deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v)
Raymond Hettinger0a4977c2004-03-01 23:16:22 +00001129{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001130 PyObject *old_value;
1131 block *b;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001132 Py_ssize_t n, len=Py_SIZE(deque), halflen=(len+1)>>1, index=i;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +00001133
Raymond Hettinger3c186ba2015-03-02 21:45:02 -08001134 if (!valid_index(i, len)) {
1135 PyErr_SetString(PyExc_IndexError, "deque index out of range");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001136 return -1;
1137 }
1138 if (v == NULL)
1139 return deque_del_item(deque, i);
Raymond Hettinger0e371f22004-05-12 20:55:56 +00001140
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001141 i += deque->leftindex;
Raymond Hettingerc2083082015-02-28 23:29:16 -08001142 n = (Py_ssize_t)((size_t) i / BLOCKLEN);
1143 i = (Py_ssize_t)((size_t) i % BLOCKLEN);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001144 if (index <= halflen) {
1145 b = deque->leftblock;
1146 while (n--)
1147 b = b->rightlink;
1148 } else {
Raymond Hettingera473b9d2015-02-28 17:49:47 -08001149 n = (Py_ssize_t)(
Raymond Hettingerc2083082015-02-28 23:29:16 -08001150 ((size_t)(deque->leftindex + Py_SIZE(deque) - 1))
Raymond Hettingera473b9d2015-02-28 17:49:47 -08001151 / BLOCKLEN - n);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001152 b = deque->rightblock;
1153 while (n--)
1154 b = b->leftlink;
1155 }
1156 Py_INCREF(v);
1157 old_value = b->data[i];
1158 b->data[i] = v;
1159 Py_DECREF(old_value);
1160 return 0;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +00001161}
1162
1163static PyObject *
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001164deque_clearmethod(dequeobject *deque)
1165{
Benjamin Peterson0e5c48a2013-01-12 21:22:18 -05001166 deque_clear(deque);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001167 Py_RETURN_NONE;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001168}
1169
1170PyDoc_STRVAR(clear_doc, "Remove all elements from the deque.");
1171
1172static void
1173deque_dealloc(dequeobject *deque)
1174{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001175 PyObject_GC_UnTrack(deque);
1176 if (deque->weakreflist != NULL)
1177 PyObject_ClearWeakRefs((PyObject *) deque);
1178 if (deque->leftblock != NULL) {
1179 deque_clear(deque);
1180 assert(deque->leftblock != NULL);
1181 freeblock(deque->leftblock);
1182 }
1183 deque->leftblock = NULL;
1184 deque->rightblock = NULL;
1185 Py_TYPE(deque)->tp_free(deque);
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001186}
1187
1188static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +00001189deque_traverse(dequeobject *deque, visitproc visit, void *arg)
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001190{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001191 block *b;
1192 PyObject *item;
1193 Py_ssize_t index;
1194 Py_ssize_t indexlo = deque->leftindex;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001195
Raymond Hettinger5bfa8672013-07-06 11:58:09 -10001196 for (b = deque->leftblock; b != deque->rightblock; b = b->rightlink) {
1197 for (index = indexlo; index < BLOCKLEN ; index++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001198 item = b->data[index];
1199 Py_VISIT(item);
1200 }
1201 indexlo = 0;
1202 }
Raymond Hettinger5bfa8672013-07-06 11:58:09 -10001203 for (index = indexlo; index <= deque->rightindex; index++) {
1204 item = b->data[index];
1205 Py_VISIT(item);
1206 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001207 return 0;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001208}
1209
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001210static PyObject *
1211deque_copy(PyObject *deque)
1212{
Raymond Hettingeraed88302015-09-19 09:05:42 -07001213 dequeobject *old_deque = (dequeobject *)deque;
Raymond Hettingere4f34672015-09-13 19:27:01 -04001214 if (Py_TYPE(deque) == &deque_type) {
1215 dequeobject *new_deque;
1216 PyObject *rv;
1217
1218 new_deque = (dequeobject *)deque_new(&deque_type, (PyObject *)NULL, (PyObject *)NULL);
1219 if (new_deque == NULL)
1220 return NULL;
Raymond Hettingeraed88302015-09-19 09:05:42 -07001221 new_deque->maxlen = old_deque->maxlen;
1222 /* Fast path for the deque_repeat() common case where len(deque) == 1 */
1223 if (Py_SIZE(deque) == 1 && new_deque->maxlen != 0) {
1224 PyObject *item = old_deque->leftblock->data[old_deque->leftindex];
1225 rv = deque_append(new_deque, item);
1226 } else {
1227 rv = deque_extend(new_deque, deque);
1228 }
Raymond Hettingere4f34672015-09-13 19:27:01 -04001229 if (rv != NULL) {
1230 Py_DECREF(rv);
1231 return (PyObject *)new_deque;
1232 }
1233 Py_DECREF(new_deque);
1234 return NULL;
1235 }
Raymond Hettingerd3d2b2c2015-09-21 23:41:56 -07001236 if (old_deque->maxlen < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001237 return PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "O", deque, NULL);
1238 else
1239 return PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "Oi",
Raymond Hettingeraed88302015-09-19 09:05:42 -07001240 deque, old_deque->maxlen, NULL);
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001241}
1242
1243PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque.");
1244
1245static PyObject *
1246deque_reduce(dequeobject *deque)
1247{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 PyObject *dict, *result, *aslist;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001249 _Py_IDENTIFIER(__dict__);
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001250
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001251 dict = _PyObject_GetAttrId((PyObject *)deque, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 if (dict == NULL)
1253 PyErr_Clear();
1254 aslist = PySequence_List((PyObject *)deque);
1255 if (aslist == NULL) {
1256 Py_XDECREF(dict);
1257 return NULL;
1258 }
1259 if (dict == NULL) {
Raymond Hettingerd3d2b2c2015-09-21 23:41:56 -07001260 if (deque->maxlen < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001261 result = Py_BuildValue("O(O)", Py_TYPE(deque), aslist);
1262 else
1263 result = Py_BuildValue("O(On)", Py_TYPE(deque), aslist, deque->maxlen);
1264 } else {
Raymond Hettingerd3d2b2c2015-09-21 23:41:56 -07001265 if (deque->maxlen < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001266 result = Py_BuildValue("O(OO)O", Py_TYPE(deque), aslist, Py_None, dict);
1267 else
1268 result = Py_BuildValue("O(On)O", Py_TYPE(deque), aslist, deque->maxlen, dict);
1269 }
1270 Py_XDECREF(dict);
1271 Py_DECREF(aslist);
1272 return result;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001273}
1274
1275PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
1276
1277static PyObject *
1278deque_repr(PyObject *deque)
1279{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001280 PyObject *aslist, *result;
1281 int i;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001283 i = Py_ReprEnter(deque);
1284 if (i != 0) {
1285 if (i < 0)
1286 return NULL;
1287 return PyUnicode_FromString("[...]");
1288 }
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001289
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001290 aslist = PySequence_List(deque);
1291 if (aslist == NULL) {
1292 Py_ReprLeave(deque);
1293 return NULL;
1294 }
1295 if (((dequeobject *)deque)->maxlen != -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001296 result = PyUnicode_FromFormat("deque(%R, maxlen=%zd)",
1297 aslist, ((dequeobject *)deque)->maxlen);
1298 else
1299 result = PyUnicode_FromFormat("deque(%R)", aslist);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001300 Py_ReprLeave(deque);
Raymond Hettinger2b2b7532015-09-05 17:05:52 -07001301 Py_DECREF(aslist);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 return result;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001303}
1304
Raymond Hettinger738ec902004-02-29 02:15:56 +00001305static PyObject *
1306deque_richcompare(PyObject *v, PyObject *w, int op)
1307{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 PyObject *it1=NULL, *it2=NULL, *x, *y;
1309 Py_ssize_t vs, ws;
1310 int b, cmp=-1;
Raymond Hettinger738ec902004-02-29 02:15:56 +00001311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 if (!PyObject_TypeCheck(v, &deque_type) ||
1313 !PyObject_TypeCheck(w, &deque_type)) {
Brian Curtindfc80e32011-08-10 20:28:54 -05001314 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001315 }
Raymond Hettinger738ec902004-02-29 02:15:56 +00001316
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001317 /* Shortcuts */
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001318 vs = Py_SIZE((dequeobject *)v);
1319 ws = Py_SIZE((dequeobject *)w);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 if (op == Py_EQ) {
1321 if (v == w)
1322 Py_RETURN_TRUE;
1323 if (vs != ws)
1324 Py_RETURN_FALSE;
1325 }
1326 if (op == Py_NE) {
1327 if (v == w)
1328 Py_RETURN_FALSE;
1329 if (vs != ws)
1330 Py_RETURN_TRUE;
1331 }
Raymond Hettinger738ec902004-02-29 02:15:56 +00001332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001333 /* Search for the first index where items are different */
1334 it1 = PyObject_GetIter(v);
1335 if (it1 == NULL)
1336 goto done;
1337 it2 = PyObject_GetIter(w);
1338 if (it2 == NULL)
1339 goto done;
1340 for (;;) {
1341 x = PyIter_Next(it1);
1342 if (x == NULL && PyErr_Occurred())
1343 goto done;
1344 y = PyIter_Next(it2);
1345 if (x == NULL || y == NULL)
1346 break;
1347 b = PyObject_RichCompareBool(x, y, Py_EQ);
1348 if (b == 0) {
1349 cmp = PyObject_RichCompareBool(x, y, op);
1350 Py_DECREF(x);
1351 Py_DECREF(y);
1352 goto done;
1353 }
1354 Py_DECREF(x);
1355 Py_DECREF(y);
Raymond Hettingerd3d2b2c2015-09-21 23:41:56 -07001356 if (b < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001357 goto done;
1358 }
1359 /* We reached the end of one deque or both */
1360 Py_XDECREF(x);
1361 Py_XDECREF(y);
1362 if (PyErr_Occurred())
1363 goto done;
1364 switch (op) {
1365 case Py_LT: cmp = y != NULL; break; /* if w was longer */
1366 case Py_LE: cmp = x == NULL; break; /* if v was not longer */
1367 case Py_EQ: cmp = x == y; break; /* if we reached the end of both */
1368 case Py_NE: cmp = x != y; break; /* if one deque continues */
1369 case Py_GT: cmp = x != NULL; break; /* if v was longer */
1370 case Py_GE: cmp = y == NULL; break; /* if w was not longer */
1371 }
Tim Peters1065f752004-10-01 01:03:29 +00001372
Raymond Hettinger738ec902004-02-29 02:15:56 +00001373done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001374 Py_XDECREF(it1);
1375 Py_XDECREF(it2);
1376 if (cmp == 1)
1377 Py_RETURN_TRUE;
1378 if (cmp == 0)
1379 Py_RETURN_FALSE;
1380 return NULL;
Raymond Hettinger738ec902004-02-29 02:15:56 +00001381}
1382
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001383static int
Guido van Rossum8ce8a782007-11-01 19:42:39 +00001384deque_init(dequeobject *deque, PyObject *args, PyObject *kwdargs)
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001385{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 PyObject *iterable = NULL;
1387 PyObject *maxlenobj = NULL;
1388 Py_ssize_t maxlen = -1;
1389 char *kwlist[] = {"iterable", "maxlen", 0};
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 if (!PyArg_ParseTupleAndKeywords(args, kwdargs, "|OO:deque", kwlist, &iterable, &maxlenobj))
1392 return -1;
1393 if (maxlenobj != NULL && maxlenobj != Py_None) {
1394 maxlen = PyLong_AsSsize_t(maxlenobj);
1395 if (maxlen == -1 && PyErr_Occurred())
1396 return -1;
1397 if (maxlen < 0) {
1398 PyErr_SetString(PyExc_ValueError, "maxlen must be non-negative");
1399 return -1;
1400 }
1401 }
1402 deque->maxlen = maxlen;
1403 deque_clear(deque);
1404 if (iterable != NULL) {
1405 PyObject *rv = deque_extend(deque, iterable);
1406 if (rv == NULL)
1407 return -1;
1408 Py_DECREF(rv);
1409 }
1410 return 0;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001411}
1412
Raymond Hettinger5bb0f0e2009-03-10 12:56:32 +00001413static PyObject *
Jesus Cea16e2fca2012-08-03 14:49:42 +02001414deque_sizeof(dequeobject *deque, void *unused)
1415{
1416 Py_ssize_t res;
1417 Py_ssize_t blocks;
1418
1419 res = sizeof(dequeobject);
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001420 blocks = (deque->leftindex + Py_SIZE(deque) + BLOCKLEN - 1) / BLOCKLEN;
1421 assert(deque->leftindex + Py_SIZE(deque) - 1 ==
Jesus Cea16e2fca2012-08-03 14:49:42 +02001422 (blocks - 1) * BLOCKLEN + deque->rightindex);
1423 res += blocks * sizeof(block);
1424 return PyLong_FromSsize_t(res);
1425}
1426
1427PyDoc_STRVAR(sizeof_doc,
1428"D.__sizeof__() -- size of D in memory, in bytes");
1429
Raymond Hettinger0f1451c2015-03-23 23:23:55 -07001430static int
1431deque_bool(dequeobject *deque)
1432{
1433 return Py_SIZE(deque) != 0;
1434}
1435
Jesus Cea16e2fca2012-08-03 14:49:42 +02001436static PyObject *
Raymond Hettinger5bb0f0e2009-03-10 12:56:32 +00001437deque_get_maxlen(dequeobject *deque)
1438{
Raymond Hettingerd3d2b2c2015-09-21 23:41:56 -07001439 if (deque->maxlen < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 Py_RETURN_NONE;
1441 return PyLong_FromSsize_t(deque->maxlen);
Raymond Hettinger5bb0f0e2009-03-10 12:56:32 +00001442}
1443
Raymond Hettinger41290a62015-03-31 08:12:23 -07001444
1445/* deque object ********************************************************/
1446
Raymond Hettinger5bb0f0e2009-03-10 12:56:32 +00001447static PyGetSetDef deque_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001448 {"maxlen", (getter)deque_get_maxlen, (setter)NULL,
1449 "maximum size of a deque or None if unbounded"},
1450 {0}
Raymond Hettinger5bb0f0e2009-03-10 12:56:32 +00001451};
1452
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001453static PySequenceMethods deque_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001454 (lenfunc)deque_len, /* sq_length */
Raymond Hettinger41290a62015-03-31 08:12:23 -07001455 (binaryfunc)deque_concat, /* sq_concat */
1456 (ssizeargfunc)deque_repeat, /* sq_repeat */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001457 (ssizeargfunc)deque_item, /* sq_item */
1458 0, /* sq_slice */
Raymond Hettinger87e69122015-03-02 23:32:02 -08001459 (ssizeobjargproc)deque_ass_item, /* sq_ass_item */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001460 0, /* sq_ass_slice */
Raymond Hettinger39dadf72015-03-20 16:38:56 -07001461 (objobjproc)deque_contains, /* sq_contains */
Raymond Hettinger87e69122015-03-02 23:32:02 -08001462 (binaryfunc)deque_inplace_concat, /* sq_inplace_concat */
Raymond Hettinger41290a62015-03-31 08:12:23 -07001463 (ssizeargfunc)deque_inplace_repeat, /* sq_inplace_repeat */
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001464};
1465
Raymond Hettinger0f1451c2015-03-23 23:23:55 -07001466static PyNumberMethods deque_as_number = {
1467 0, /* nb_add */
1468 0, /* nb_subtract */
1469 0, /* nb_multiply */
1470 0, /* nb_remainder */
1471 0, /* nb_divmod */
1472 0, /* nb_power */
1473 0, /* nb_negative */
1474 0, /* nb_positive */
1475 0, /* nb_absolute */
1476 (inquiry)deque_bool, /* nb_bool */
1477 0, /* nb_invert */
Raymond Hettinger0f1451c2015-03-23 23:23:55 -07001478 };
1479
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001480static PyObject *deque_iter(dequeobject *deque);
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001481static PyObject *deque_reviter(dequeobject *deque);
Tim Peters1065f752004-10-01 01:03:29 +00001482PyDoc_STRVAR(reversed_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001483 "D.__reversed__() -- return a reverse iterator over the deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001484
1485static PyMethodDef deque_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001486 {"append", (PyCFunction)deque_append,
1487 METH_O, append_doc},
1488 {"appendleft", (PyCFunction)deque_appendleft,
1489 METH_O, appendleft_doc},
1490 {"clear", (PyCFunction)deque_clearmethod,
1491 METH_NOARGS, clear_doc},
1492 {"__copy__", (PyCFunction)deque_copy,
1493 METH_NOARGS, copy_doc},
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001494 {"copy", (PyCFunction)deque_copy,
1495 METH_NOARGS, copy_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001496 {"count", (PyCFunction)deque_count,
Raymond Hettinger0f6f9472015-03-21 01:42:10 -07001497 METH_O, count_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001498 {"extend", (PyCFunction)deque_extend,
1499 METH_O, extend_doc},
1500 {"extendleft", (PyCFunction)deque_extendleft,
1501 METH_O, extendleft_doc},
Raymond Hettinger32ea1652015-03-21 01:37:37 -07001502 {"index", (PyCFunction)deque_index,
1503 METH_VARARGS, index_doc},
1504 {"insert", (PyCFunction)deque_insert,
1505 METH_VARARGS, insert_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001506 {"pop", (PyCFunction)deque_pop,
1507 METH_NOARGS, pop_doc},
1508 {"popleft", (PyCFunction)deque_popleft,
1509 METH_NOARGS, popleft_doc},
Raymond Hettinger0f6f9472015-03-21 01:42:10 -07001510 {"__reduce__", (PyCFunction)deque_reduce,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 METH_NOARGS, reduce_doc},
1512 {"remove", (PyCFunction)deque_remove,
1513 METH_O, remove_doc},
1514 {"__reversed__", (PyCFunction)deque_reviter,
1515 METH_NOARGS, reversed_doc},
1516 {"reverse", (PyCFunction)deque_reverse,
1517 METH_NOARGS, reverse_doc},
1518 {"rotate", (PyCFunction)deque_rotate,
Jesus Cea16e2fca2012-08-03 14:49:42 +02001519 METH_VARARGS, rotate_doc},
1520 {"__sizeof__", (PyCFunction)deque_sizeof,
1521 METH_NOARGS, sizeof_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001522 {NULL, NULL} /* sentinel */
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001523};
1524
1525PyDoc_STRVAR(deque_doc,
Andrew Svetlov6a5c7c32012-10-31 11:50:40 +02001526"deque([iterable[, maxlen]]) --> deque object\n\
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001527\n\
Raymond Hettinger41290a62015-03-31 08:12:23 -07001528A list-like sequence optimized for data accesses near its endpoints.");
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001529
Neal Norwitz87f10132004-02-29 15:40:53 +00001530static PyTypeObject deque_type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001531 PyVarObject_HEAD_INIT(NULL, 0)
1532 "collections.deque", /* tp_name */
1533 sizeof(dequeobject), /* tp_basicsize */
1534 0, /* tp_itemsize */
1535 /* methods */
1536 (destructor)deque_dealloc, /* tp_dealloc */
1537 0, /* tp_print */
1538 0, /* tp_getattr */
1539 0, /* tp_setattr */
1540 0, /* tp_reserved */
1541 deque_repr, /* tp_repr */
Raymond Hettinger0f1451c2015-03-23 23:23:55 -07001542 &deque_as_number, /* tp_as_number */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001543 &deque_as_sequence, /* tp_as_sequence */
1544 0, /* tp_as_mapping */
Georg Brandlf038b322010-10-18 07:35:09 +00001545 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001546 0, /* tp_call */
1547 0, /* tp_str */
1548 PyObject_GenericGetAttr, /* tp_getattro */
1549 0, /* tp_setattro */
1550 0, /* tp_as_buffer */
1551 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Georg Brandlf038b322010-10-18 07:35:09 +00001552 /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001553 deque_doc, /* tp_doc */
1554 (traverseproc)deque_traverse, /* tp_traverse */
1555 (inquiry)deque_clear, /* tp_clear */
1556 (richcmpfunc)deque_richcompare, /* tp_richcompare */
Georg Brandlf038b322010-10-18 07:35:09 +00001557 offsetof(dequeobject, weakreflist), /* tp_weaklistoffset*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 (getiterfunc)deque_iter, /* tp_iter */
1559 0, /* tp_iternext */
1560 deque_methods, /* tp_methods */
1561 0, /* tp_members */
Georg Brandlf038b322010-10-18 07:35:09 +00001562 deque_getset, /* tp_getset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001563 0, /* tp_base */
1564 0, /* tp_dict */
1565 0, /* tp_descr_get */
1566 0, /* tp_descr_set */
1567 0, /* tp_dictoffset */
1568 (initproc)deque_init, /* tp_init */
1569 PyType_GenericAlloc, /* tp_alloc */
1570 deque_new, /* tp_new */
1571 PyObject_GC_Del, /* tp_free */
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001572};
1573
1574/*********************** Deque Iterator **************************/
1575
1576typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001577 PyObject_HEAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001578 block *b;
Raymond Hettinger87e69122015-03-02 23:32:02 -08001579 Py_ssize_t index;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001580 dequeobject *deque;
Raymond Hettingerf9d9c792015-03-02 22:47:46 -08001581 size_t state; /* state when the iterator is created */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001582 Py_ssize_t counter; /* number of items remaining for iteration */
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001583} dequeiterobject;
1584
Martin v. Löwis59683e82008-06-13 07:50:45 +00001585static PyTypeObject dequeiter_type;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001586
1587static PyObject *
1588deque_iter(dequeobject *deque)
1589{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001590 dequeiterobject *it;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001591
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001592 it = PyObject_GC_New(dequeiterobject, &dequeiter_type);
1593 if (it == NULL)
1594 return NULL;
1595 it->b = deque->leftblock;
1596 it->index = deque->leftindex;
1597 Py_INCREF(deque);
1598 it->deque = deque;
1599 it->state = deque->state;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001600 it->counter = Py_SIZE(deque);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001601 PyObject_GC_Track(it);
1602 return (PyObject *)it;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001603}
1604
Antoine Pitrou7ddda782009-01-01 15:35:33 +00001605static int
1606dequeiter_traverse(dequeiterobject *dio, visitproc visit, void *arg)
1607{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 Py_VISIT(dio->deque);
1609 return 0;
Antoine Pitrou7ddda782009-01-01 15:35:33 +00001610}
1611
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001612static void
1613dequeiter_dealloc(dequeiterobject *dio)
1614{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001615 Py_XDECREF(dio->deque);
1616 PyObject_GC_Del(dio);
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001617}
1618
1619static PyObject *
1620dequeiter_next(dequeiterobject *it)
1621{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001622 PyObject *item;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +00001623
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 if (it->deque->state != it->state) {
1625 it->counter = 0;
1626 PyErr_SetString(PyExc_RuntimeError,
1627 "deque mutated during iteration");
1628 return NULL;
1629 }
1630 if (it->counter == 0)
1631 return NULL;
1632 assert (!(it->b == it->deque->rightblock &&
1633 it->index > it->deque->rightindex));
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 item = it->b->data[it->index];
1636 it->index++;
1637 it->counter--;
1638 if (it->index == BLOCKLEN && it->counter > 0) {
Raymond Hettinger82df9252013-07-07 01:43:42 -10001639 CHECK_NOT_END(it->b->rightlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001640 it->b = it->b->rightlink;
1641 it->index = 0;
1642 }
1643 Py_INCREF(item);
1644 return item;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001645}
1646
Raymond Hettinger6b27cda2005-09-24 21:23:05 +00001647static PyObject *
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001648dequeiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1649{
1650 Py_ssize_t i, index=0;
1651 PyObject *deque;
1652 dequeiterobject *it;
1653 if (!PyArg_ParseTuple(args, "O!|n", &deque_type, &deque, &index))
1654 return NULL;
1655 assert(type == &dequeiter_type);
1656
1657 it = (dequeiterobject*)deque_iter((dequeobject *)deque);
1658 if (!it)
1659 return NULL;
1660 /* consume items from the queue */
1661 for(i=0; i<index; i++) {
1662 PyObject *item = dequeiter_next(it);
1663 if (item) {
1664 Py_DECREF(item);
1665 } else {
1666 if (it->counter) {
1667 Py_DECREF(it);
1668 return NULL;
1669 } else
1670 break;
1671 }
1672 }
1673 return (PyObject*)it;
1674}
1675
1676static PyObject *
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001677dequeiter_len(dequeiterobject *it)
1678{
Antoine Pitrou554f3342010-08-17 18:30:06 +00001679 return PyLong_FromSsize_t(it->counter);
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001680}
1681
Armin Rigof5b3e362006-02-11 21:32:43 +00001682PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +00001683
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001684static PyObject *
1685dequeiter_reduce(dequeiterobject *it)
1686{
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001687 return Py_BuildValue("O(On)", Py_TYPE(it), it->deque, Py_SIZE(it->deque) - it->counter);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001688}
1689
Raymond Hettinger6b27cda2005-09-24 21:23:05 +00001690static PyMethodDef dequeiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001691 {"__length_hint__", (PyCFunction)dequeiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001692 {"__reduce__", (PyCFunction)dequeiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001693 {NULL, NULL} /* sentinel */
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001694};
1695
Martin v. Löwis59683e82008-06-13 07:50:45 +00001696static PyTypeObject dequeiter_type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001697 PyVarObject_HEAD_INIT(NULL, 0)
Raymond Hettinger87e69122015-03-02 23:32:02 -08001698 "_collections._deque_iterator", /* tp_name */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001699 sizeof(dequeiterobject), /* tp_basicsize */
1700 0, /* tp_itemsize */
1701 /* methods */
1702 (destructor)dequeiter_dealloc, /* tp_dealloc */
1703 0, /* tp_print */
1704 0, /* tp_getattr */
1705 0, /* tp_setattr */
1706 0, /* tp_reserved */
1707 0, /* tp_repr */
1708 0, /* tp_as_number */
1709 0, /* tp_as_sequence */
1710 0, /* tp_as_mapping */
1711 0, /* tp_hash */
1712 0, /* tp_call */
1713 0, /* tp_str */
1714 PyObject_GenericGetAttr, /* tp_getattro */
1715 0, /* tp_setattro */
1716 0, /* tp_as_buffer */
Raymond Hettinger87e69122015-03-02 23:32:02 -08001717 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001718 0, /* tp_doc */
1719 (traverseproc)dequeiter_traverse, /* tp_traverse */
1720 0, /* tp_clear */
1721 0, /* tp_richcompare */
1722 0, /* tp_weaklistoffset */
1723 PyObject_SelfIter, /* tp_iter */
1724 (iternextfunc)dequeiter_next, /* tp_iternext */
1725 dequeiter_methods, /* tp_methods */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001726 0, /* tp_members */
1727 0, /* tp_getset */
1728 0, /* tp_base */
1729 0, /* tp_dict */
1730 0, /* tp_descr_get */
1731 0, /* tp_descr_set */
1732 0, /* tp_dictoffset */
1733 0, /* tp_init */
1734 0, /* tp_alloc */
1735 dequeiter_new, /* tp_new */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001736 0,
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001737};
1738
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001739/*********************** Deque Reverse Iterator **************************/
1740
Martin v. Löwis59683e82008-06-13 07:50:45 +00001741static PyTypeObject dequereviter_type;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001742
1743static PyObject *
1744deque_reviter(dequeobject *deque)
1745{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001746 dequeiterobject *it;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001747
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001748 it = PyObject_GC_New(dequeiterobject, &dequereviter_type);
1749 if (it == NULL)
1750 return NULL;
1751 it->b = deque->rightblock;
1752 it->index = deque->rightindex;
1753 Py_INCREF(deque);
1754 it->deque = deque;
1755 it->state = deque->state;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001756 it->counter = Py_SIZE(deque);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001757 PyObject_GC_Track(it);
1758 return (PyObject *)it;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001759}
1760
1761static PyObject *
1762dequereviter_next(dequeiterobject *it)
1763{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001764 PyObject *item;
1765 if (it->counter == 0)
1766 return NULL;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001767
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001768 if (it->deque->state != it->state) {
1769 it->counter = 0;
1770 PyErr_SetString(PyExc_RuntimeError,
1771 "deque mutated during iteration");
1772 return NULL;
1773 }
1774 assert (!(it->b == it->deque->leftblock &&
1775 it->index < it->deque->leftindex));
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001776
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001777 item = it->b->data[it->index];
1778 it->index--;
1779 it->counter--;
Raymond Hettingerd3d2b2c2015-09-21 23:41:56 -07001780 if (it->index < 0 && it->counter > 0) {
Raymond Hettinger82df9252013-07-07 01:43:42 -10001781 CHECK_NOT_END(it->b->leftlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001782 it->b = it->b->leftlink;
1783 it->index = BLOCKLEN - 1;
1784 }
1785 Py_INCREF(item);
1786 return item;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001787}
1788
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001789static PyObject *
1790dequereviter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1791{
1792 Py_ssize_t i, index=0;
1793 PyObject *deque;
1794 dequeiterobject *it;
1795 if (!PyArg_ParseTuple(args, "O!|n", &deque_type, &deque, &index))
1796 return NULL;
1797 assert(type == &dequereviter_type);
1798
1799 it = (dequeiterobject*)deque_reviter((dequeobject *)deque);
1800 if (!it)
1801 return NULL;
1802 /* consume items from the queue */
1803 for(i=0; i<index; i++) {
1804 PyObject *item = dequereviter_next(it);
1805 if (item) {
1806 Py_DECREF(item);
1807 } else {
1808 if (it->counter) {
1809 Py_DECREF(it);
1810 return NULL;
1811 } else
1812 break;
1813 }
1814 }
1815 return (PyObject*)it;
1816}
1817
Martin v. Löwis59683e82008-06-13 07:50:45 +00001818static PyTypeObject dequereviter_type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001819 PyVarObject_HEAD_INIT(NULL, 0)
Raymond Hettinger87e69122015-03-02 23:32:02 -08001820 "_collections._deque_reverse_iterator", /* tp_name */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001821 sizeof(dequeiterobject), /* tp_basicsize */
1822 0, /* tp_itemsize */
1823 /* methods */
1824 (destructor)dequeiter_dealloc, /* tp_dealloc */
1825 0, /* tp_print */
1826 0, /* tp_getattr */
1827 0, /* tp_setattr */
1828 0, /* tp_reserved */
1829 0, /* tp_repr */
1830 0, /* tp_as_number */
1831 0, /* tp_as_sequence */
1832 0, /* tp_as_mapping */
1833 0, /* tp_hash */
1834 0, /* tp_call */
1835 0, /* tp_str */
1836 PyObject_GenericGetAttr, /* tp_getattro */
1837 0, /* tp_setattro */
1838 0, /* tp_as_buffer */
Raymond Hettinger87e69122015-03-02 23:32:02 -08001839 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001840 0, /* tp_doc */
1841 (traverseproc)dequeiter_traverse, /* tp_traverse */
1842 0, /* tp_clear */
1843 0, /* tp_richcompare */
1844 0, /* tp_weaklistoffset */
1845 PyObject_SelfIter, /* tp_iter */
1846 (iternextfunc)dequereviter_next, /* tp_iternext */
1847 dequeiter_methods, /* tp_methods */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001848 0, /* tp_members */
1849 0, /* tp_getset */
1850 0, /* tp_base */
1851 0, /* tp_dict */
1852 0, /* tp_descr_get */
1853 0, /* tp_descr_set */
1854 0, /* tp_dictoffset */
1855 0, /* tp_init */
1856 0, /* tp_alloc */
1857 dequereviter_new, /* tp_new */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001858 0,
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001859};
1860
Guido van Rossum1968ad32006-02-25 22:38:04 +00001861/* defaultdict type *********************************************************/
1862
1863typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 PyDictObject dict;
1865 PyObject *default_factory;
Guido van Rossum1968ad32006-02-25 22:38:04 +00001866} defdictobject;
1867
1868static PyTypeObject defdict_type; /* Forward */
1869
1870PyDoc_STRVAR(defdict_missing_doc,
1871"__missing__(key) # Called by __getitem__ for missing key; pseudo-code:\n\
Guido van Rossumd8faa362007-04-27 19:54:29 +00001872 if self.default_factory is None: raise KeyError((key,))\n\
Guido van Rossum1968ad32006-02-25 22:38:04 +00001873 self[key] = value = self.default_factory()\n\
1874 return value\n\
1875");
1876
1877static PyObject *
1878defdict_missing(defdictobject *dd, PyObject *key)
1879{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001880 PyObject *factory = dd->default_factory;
1881 PyObject *value;
1882 if (factory == NULL || factory == Py_None) {
1883 /* XXX Call dict.__missing__(key) */
1884 PyObject *tup;
1885 tup = PyTuple_Pack(1, key);
1886 if (!tup) return NULL;
1887 PyErr_SetObject(PyExc_KeyError, tup);
1888 Py_DECREF(tup);
1889 return NULL;
1890 }
1891 value = PyEval_CallObject(factory, NULL);
1892 if (value == NULL)
1893 return value;
1894 if (PyObject_SetItem((PyObject *)dd, key, value) < 0) {
1895 Py_DECREF(value);
1896 return NULL;
1897 }
1898 return value;
Guido van Rossum1968ad32006-02-25 22:38:04 +00001899}
1900
1901PyDoc_STRVAR(defdict_copy_doc, "D.copy() -> a shallow copy of D.");
1902
1903static PyObject *
1904defdict_copy(defdictobject *dd)
1905{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 /* This calls the object's class. That only works for subclasses
1907 whose class constructor has the same signature. Subclasses that
1908 define a different constructor signature must override copy().
1909 */
Raymond Hettinger54628fa2009-08-04 19:16:39 +00001910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 if (dd->default_factory == NULL)
1912 return PyObject_CallFunctionObjArgs((PyObject*)Py_TYPE(dd), Py_None, dd, NULL);
1913 return PyObject_CallFunctionObjArgs((PyObject*)Py_TYPE(dd),
1914 dd->default_factory, dd, NULL);
Guido van Rossum1968ad32006-02-25 22:38:04 +00001915}
1916
1917static PyObject *
1918defdict_reduce(defdictobject *dd)
1919{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001920 /* __reduce__ must return a 5-tuple as follows:
Guido van Rossum1968ad32006-02-25 22:38:04 +00001921
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001922 - factory function
1923 - tuple of args for the factory function
1924 - additional state (here None)
1925 - sequence iterator (here None)
1926 - dictionary iterator (yielding successive (key, value) pairs
Guido van Rossum1968ad32006-02-25 22:38:04 +00001927
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001928 This API is used by pickle.py and copy.py.
Guido van Rossum1968ad32006-02-25 22:38:04 +00001929
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001930 For this to be useful with pickle.py, the default_factory
1931 must be picklable; e.g., None, a built-in, or a global
1932 function in a module or package.
Guido van Rossum1968ad32006-02-25 22:38:04 +00001933
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001934 Both shallow and deep copying are supported, but for deep
1935 copying, the default_factory must be deep-copyable; e.g. None,
1936 or a built-in (functions are not copyable at this time).
Guido van Rossum1968ad32006-02-25 22:38:04 +00001937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001938 This only works for subclasses as long as their constructor
1939 signature is compatible; the first argument must be the
1940 optional default_factory, defaulting to None.
1941 */
1942 PyObject *args;
1943 PyObject *items;
1944 PyObject *iter;
1945 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001946 _Py_IDENTIFIER(items);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001947
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001948 if (dd->default_factory == NULL || dd->default_factory == Py_None)
1949 args = PyTuple_New(0);
1950 else
1951 args = PyTuple_Pack(1, dd->default_factory);
1952 if (args == NULL)
1953 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001954 items = _PyObject_CallMethodId((PyObject *)dd, &PyId_items, "()");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001955 if (items == NULL) {
1956 Py_DECREF(args);
1957 return NULL;
1958 }
1959 iter = PyObject_GetIter(items);
1960 if (iter == NULL) {
1961 Py_DECREF(items);
1962 Py_DECREF(args);
1963 return NULL;
1964 }
1965 result = PyTuple_Pack(5, Py_TYPE(dd), args,
1966 Py_None, Py_None, iter);
1967 Py_DECREF(iter);
1968 Py_DECREF(items);
1969 Py_DECREF(args);
1970 return result;
Guido van Rossum1968ad32006-02-25 22:38:04 +00001971}
1972
1973static PyMethodDef defdict_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001974 {"__missing__", (PyCFunction)defdict_missing, METH_O,
1975 defdict_missing_doc},
1976 {"copy", (PyCFunction)defdict_copy, METH_NOARGS,
1977 defdict_copy_doc},
1978 {"__copy__", (PyCFunction)defdict_copy, METH_NOARGS,
1979 defdict_copy_doc},
1980 {"__reduce__", (PyCFunction)defdict_reduce, METH_NOARGS,
1981 reduce_doc},
1982 {NULL}
Guido van Rossum1968ad32006-02-25 22:38:04 +00001983};
1984
1985static PyMemberDef defdict_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001986 {"default_factory", T_OBJECT,
1987 offsetof(defdictobject, default_factory), 0,
1988 PyDoc_STR("Factory for default value called by __missing__().")},
1989 {NULL}
Guido van Rossum1968ad32006-02-25 22:38:04 +00001990};
1991
1992static void
1993defdict_dealloc(defdictobject *dd)
1994{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001995 Py_CLEAR(dd->default_factory);
1996 PyDict_Type.tp_dealloc((PyObject *)dd);
Guido van Rossum1968ad32006-02-25 22:38:04 +00001997}
1998
Guido van Rossum1968ad32006-02-25 22:38:04 +00001999static PyObject *
2000defdict_repr(defdictobject *dd)
2001{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002002 PyObject *baserepr;
2003 PyObject *defrepr;
2004 PyObject *result;
2005 baserepr = PyDict_Type.tp_repr((PyObject *)dd);
2006 if (baserepr == NULL)
2007 return NULL;
2008 if (dd->default_factory == NULL)
2009 defrepr = PyUnicode_FromString("None");
2010 else
2011 {
2012 int status = Py_ReprEnter(dd->default_factory);
2013 if (status != 0) {
Antoine Pitrouf5f1fe02012-02-15 02:42:46 +01002014 if (status < 0) {
2015 Py_DECREF(baserepr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002016 return NULL;
Antoine Pitrouf5f1fe02012-02-15 02:42:46 +01002017 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002018 defrepr = PyUnicode_FromString("...");
2019 }
2020 else
2021 defrepr = PyObject_Repr(dd->default_factory);
2022 Py_ReprLeave(dd->default_factory);
2023 }
2024 if (defrepr == NULL) {
2025 Py_DECREF(baserepr);
2026 return NULL;
2027 }
2028 result = PyUnicode_FromFormat("defaultdict(%U, %U)",
2029 defrepr, baserepr);
2030 Py_DECREF(defrepr);
2031 Py_DECREF(baserepr);
2032 return result;
Guido van Rossum1968ad32006-02-25 22:38:04 +00002033}
2034
2035static int
2036defdict_traverse(PyObject *self, visitproc visit, void *arg)
2037{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002038 Py_VISIT(((defdictobject *)self)->default_factory);
2039 return PyDict_Type.tp_traverse(self, visit, arg);
Guido van Rossum1968ad32006-02-25 22:38:04 +00002040}
2041
2042static int
2043defdict_tp_clear(defdictobject *dd)
2044{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002045 Py_CLEAR(dd->default_factory);
2046 return PyDict_Type.tp_clear((PyObject *)dd);
Guido van Rossum1968ad32006-02-25 22:38:04 +00002047}
2048
2049static int
2050defdict_init(PyObject *self, PyObject *args, PyObject *kwds)
2051{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002052 defdictobject *dd = (defdictobject *)self;
2053 PyObject *olddefault = dd->default_factory;
2054 PyObject *newdefault = NULL;
2055 PyObject *newargs;
2056 int result;
2057 if (args == NULL || !PyTuple_Check(args))
2058 newargs = PyTuple_New(0);
2059 else {
2060 Py_ssize_t n = PyTuple_GET_SIZE(args);
2061 if (n > 0) {
2062 newdefault = PyTuple_GET_ITEM(args, 0);
2063 if (!PyCallable_Check(newdefault) && newdefault != Py_None) {
2064 PyErr_SetString(PyExc_TypeError,
Raymond Hettinger239aba72015-07-20 03:09:22 -04002065 "first argument must be callable or None");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002066 return -1;
2067 }
2068 }
2069 newargs = PySequence_GetSlice(args, 1, n);
2070 }
2071 if (newargs == NULL)
2072 return -1;
2073 Py_XINCREF(newdefault);
2074 dd->default_factory = newdefault;
2075 result = PyDict_Type.tp_init(self, newargs, kwds);
2076 Py_DECREF(newargs);
2077 Py_XDECREF(olddefault);
2078 return result;
Guido van Rossum1968ad32006-02-25 22:38:04 +00002079}
2080
2081PyDoc_STRVAR(defdict_doc,
Benjamin Peterson9cb33b72014-01-13 23:56:05 -05002082"defaultdict(default_factory[, ...]) --> dict with default factory\n\
Guido van Rossum1968ad32006-02-25 22:38:04 +00002083\n\
2084The default factory is called without arguments to produce\n\
2085a new value when a key is not present, in __getitem__ only.\n\
2086A defaultdict compares equal to a dict with the same items.\n\
Benjamin Peterson9cb33b72014-01-13 23:56:05 -05002087All remaining arguments are treated the same as if they were\n\
2088passed to the dict constructor, including keyword arguments.\n\
Guido van Rossum1968ad32006-02-25 22:38:04 +00002089");
2090
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002091/* See comment in xxsubtype.c */
2092#define DEFERRED_ADDRESS(ADDR) 0
2093
Guido van Rossum1968ad32006-02-25 22:38:04 +00002094static PyTypeObject defdict_type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002095 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
2096 "collections.defaultdict", /* tp_name */
2097 sizeof(defdictobject), /* tp_basicsize */
2098 0, /* tp_itemsize */
2099 /* methods */
2100 (destructor)defdict_dealloc, /* tp_dealloc */
2101 0, /* tp_print */
2102 0, /* tp_getattr */
2103 0, /* tp_setattr */
2104 0, /* tp_reserved */
2105 (reprfunc)defdict_repr, /* tp_repr */
2106 0, /* tp_as_number */
2107 0, /* tp_as_sequence */
2108 0, /* tp_as_mapping */
2109 0, /* tp_hash */
2110 0, /* tp_call */
2111 0, /* tp_str */
2112 PyObject_GenericGetAttr, /* tp_getattro */
2113 0, /* tp_setattro */
2114 0, /* tp_as_buffer */
2115 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
2116 /* tp_flags */
2117 defdict_doc, /* tp_doc */
2118 defdict_traverse, /* tp_traverse */
2119 (inquiry)defdict_tp_clear, /* tp_clear */
2120 0, /* tp_richcompare */
2121 0, /* tp_weaklistoffset*/
2122 0, /* tp_iter */
2123 0, /* tp_iternext */
2124 defdict_methods, /* tp_methods */
2125 defdict_members, /* tp_members */
2126 0, /* tp_getset */
2127 DEFERRED_ADDRESS(&PyDict_Type), /* tp_base */
2128 0, /* tp_dict */
2129 0, /* tp_descr_get */
2130 0, /* tp_descr_set */
2131 0, /* tp_dictoffset */
2132 defdict_init, /* tp_init */
2133 PyType_GenericAlloc, /* tp_alloc */
2134 0, /* tp_new */
2135 PyObject_GC_Del, /* tp_free */
Guido van Rossum1968ad32006-02-25 22:38:04 +00002136};
2137
Raymond Hettinger96f34102010-12-15 16:30:37 +00002138/* helper function for Counter *********************************************/
2139
2140PyDoc_STRVAR(_count_elements_doc,
2141"_count_elements(mapping, iterable) -> None\n\
2142\n\
2143Count elements in the iterable, updating the mappping");
2144
2145static PyObject *
2146_count_elements(PyObject *self, PyObject *args)
2147{
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002148 _Py_IDENTIFIER(get);
Raymond Hettinger2ff21902013-10-01 00:55:43 -07002149 _Py_IDENTIFIER(__setitem__);
Raymond Hettinger96f34102010-12-15 16:30:37 +00002150 PyObject *it, *iterable, *mapping, *oldval;
2151 PyObject *newval = NULL;
2152 PyObject *key = NULL;
Raymond Hettinger224c87d2013-10-01 21:36:09 -07002153 PyObject *zero = NULL;
Raymond Hettinger96f34102010-12-15 16:30:37 +00002154 PyObject *one = NULL;
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002155 PyObject *bound_get = NULL;
2156 PyObject *mapping_get;
2157 PyObject *dict_get;
Raymond Hettinger2ff21902013-10-01 00:55:43 -07002158 PyObject *mapping_setitem;
Raymond Hettinger2ff21902013-10-01 00:55:43 -07002159 PyObject *dict_setitem;
Raymond Hettinger96f34102010-12-15 16:30:37 +00002160
2161 if (!PyArg_UnpackTuple(args, "_count_elements", 2, 2, &mapping, &iterable))
2162 return NULL;
2163
Raymond Hettinger96f34102010-12-15 16:30:37 +00002164 it = PyObject_GetIter(iterable);
2165 if (it == NULL)
2166 return NULL;
Raymond Hettinger426e0522011-01-03 02:12:02 +00002167
Raymond Hettinger96f34102010-12-15 16:30:37 +00002168 one = PyLong_FromLong(1);
Raymond Hettinger224c87d2013-10-01 21:36:09 -07002169 if (one == NULL)
2170 goto done;
Raymond Hettinger426e0522011-01-03 02:12:02 +00002171
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002172 /* Only take the fast path when get() and __setitem__()
2173 * have not been overridden.
2174 */
2175 mapping_get = _PyType_LookupId(Py_TYPE(mapping), &PyId_get);
2176 dict_get = _PyType_LookupId(&PyDict_Type, &PyId_get);
Raymond Hettinger2ff21902013-10-01 00:55:43 -07002177 mapping_setitem = _PyType_LookupId(Py_TYPE(mapping), &PyId___setitem__);
2178 dict_setitem = _PyType_LookupId(&PyDict_Type, &PyId___setitem__);
2179
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002180 if (mapping_get != NULL && mapping_get == dict_get &&
2181 mapping_setitem != NULL && mapping_setitem == dict_setitem) {
Raymond Hettinger426e0522011-01-03 02:12:02 +00002182 while (1) {
Raymond Hettinger507d9972014-05-18 21:32:40 +01002183 /* Fast path advantages:
2184 1. Eliminate double hashing
2185 (by re-using the same hash for both the get and set)
2186 2. Avoid argument overhead of PyObject_CallFunctionObjArgs
2187 (argument tuple creation and parsing)
2188 3. Avoid indirection through a bound method object
2189 (creates another argument tuple)
2190 4. Avoid initial increment from zero
2191 (reuse an existing one-object instead)
2192 */
Raymond Hettinger4b0b1ac2014-05-03 16:41:19 -07002193 Py_hash_t hash;
2194
Raymond Hettinger426e0522011-01-03 02:12:02 +00002195 key = PyIter_Next(it);
Victor Stinnera154b5c2011-04-20 23:23:52 +02002196 if (key == NULL)
2197 break;
Raymond Hettinger4b0b1ac2014-05-03 16:41:19 -07002198
2199 if (!PyUnicode_CheckExact(key) ||
2200 (hash = ((PyASCIIObject *) key)->hash) == -1)
2201 {
2202 hash = PyObject_Hash(key);
Raymond Hettingerda2850f2015-02-27 12:42:54 -08002203 if (hash == -1)
Raymond Hettinger4b0b1ac2014-05-03 16:41:19 -07002204 goto done;
2205 }
2206
2207 oldval = _PyDict_GetItem_KnownHash(mapping, key, hash);
Raymond Hettinger426e0522011-01-03 02:12:02 +00002208 if (oldval == NULL) {
Raymond Hettinger28c995d2015-08-14 02:07:41 -07002209 if (_PyDict_SetItem_KnownHash(mapping, key, one, hash) < 0)
Raymond Hettinger507d9972014-05-18 21:32:40 +01002210 goto done;
Raymond Hettinger426e0522011-01-03 02:12:02 +00002211 } else {
2212 newval = PyNumber_Add(oldval, one);
2213 if (newval == NULL)
Raymond Hettinger507d9972014-05-18 21:32:40 +01002214 goto done;
Raymond Hettinger28c995d2015-08-14 02:07:41 -07002215 if (_PyDict_SetItem_KnownHash(mapping, key, newval, hash) < 0)
Raymond Hettinger507d9972014-05-18 21:32:40 +01002216 goto done;
Raymond Hettinger426e0522011-01-03 02:12:02 +00002217 Py_CLEAR(newval);
2218 }
2219 Py_DECREF(key);
Raymond Hettinger96f34102010-12-15 16:30:37 +00002220 }
Raymond Hettinger426e0522011-01-03 02:12:02 +00002221 } else {
Victor Stinnere7f516c2013-11-06 23:52:55 +01002222 bound_get = _PyObject_GetAttrId(mapping, &PyId_get);
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002223 if (bound_get == NULL)
Raymond Hettinger224c87d2013-10-01 21:36:09 -07002224 goto done;
2225
2226 zero = PyLong_FromLong(0);
2227 if (zero == NULL)
2228 goto done;
2229
Raymond Hettinger426e0522011-01-03 02:12:02 +00002230 while (1) {
2231 key = PyIter_Next(it);
Victor Stinnera154b5c2011-04-20 23:23:52 +02002232 if (key == NULL)
2233 break;
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002234 oldval = PyObject_CallFunctionObjArgs(bound_get, key, zero, NULL);
Raymond Hettinger224c87d2013-10-01 21:36:09 -07002235 if (oldval == NULL)
2236 break;
2237 newval = PyNumber_Add(oldval, one);
2238 Py_DECREF(oldval);
2239 if (newval == NULL)
2240 break;
Raymond Hettinger28c995d2015-08-14 02:07:41 -07002241 if (PyObject_SetItem(mapping, key, newval) < 0)
Raymond Hettinger96f34102010-12-15 16:30:37 +00002242 break;
2243 Py_CLEAR(newval);
Raymond Hettinger426e0522011-01-03 02:12:02 +00002244 Py_DECREF(key);
Raymond Hettinger96f34102010-12-15 16:30:37 +00002245 }
Raymond Hettinger96f34102010-12-15 16:30:37 +00002246 }
Raymond Hettinger426e0522011-01-03 02:12:02 +00002247
Raymond Hettinger224c87d2013-10-01 21:36:09 -07002248done:
Raymond Hettinger96f34102010-12-15 16:30:37 +00002249 Py_DECREF(it);
2250 Py_XDECREF(key);
2251 Py_XDECREF(newval);
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07002252 Py_XDECREF(bound_get);
Raymond Hettinger224c87d2013-10-01 21:36:09 -07002253 Py_XDECREF(zero);
2254 Py_XDECREF(one);
Raymond Hettinger96f34102010-12-15 16:30:37 +00002255 if (PyErr_Occurred())
2256 return NULL;
2257 Py_RETURN_NONE;
2258}
2259
Raymond Hettinger756b3f32004-01-29 06:37:52 +00002260/* module level code ********************************************************/
2261
2262PyDoc_STRVAR(module_doc,
Guido van Rossum1968ad32006-02-25 22:38:04 +00002263"High performance data structures.\n\
2264- deque: ordered collection accessible from endpoints only\n\
2265- defaultdict: dict subclass with a default value factory\n\
Raymond Hettinger756b3f32004-01-29 06:37:52 +00002266");
2267
Raymond Hettinger96f34102010-12-15 16:30:37 +00002268static struct PyMethodDef module_functions[] = {
2269 {"_count_elements", _count_elements, METH_VARARGS, _count_elements_doc},
2270 {NULL, NULL} /* sentinel */
2271};
Martin v. Löwis1a214512008-06-11 05:26:20 +00002272
2273static struct PyModuleDef _collectionsmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002274 PyModuleDef_HEAD_INIT,
2275 "_collections",
2276 module_doc,
2277 -1,
Raymond Hettinger96f34102010-12-15 16:30:37 +00002278 module_functions,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002279 NULL,
2280 NULL,
2281 NULL,
2282 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002283};
2284
Raymond Hettinger756b3f32004-01-29 06:37:52 +00002285PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002286PyInit__collections(void)
Raymond Hettinger756b3f32004-01-29 06:37:52 +00002287{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002288 PyObject *m;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00002289
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002290 m = PyModule_Create(&_collectionsmodule);
2291 if (m == NULL)
2292 return NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00002293
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002294 if (PyType_Ready(&deque_type) < 0)
2295 return NULL;
2296 Py_INCREF(&deque_type);
2297 PyModule_AddObject(m, "deque", (PyObject *)&deque_type);
Raymond Hettinger756b3f32004-01-29 06:37:52 +00002298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002299 defdict_type.tp_base = &PyDict_Type;
2300 if (PyType_Ready(&defdict_type) < 0)
2301 return NULL;
2302 Py_INCREF(&defdict_type);
2303 PyModule_AddObject(m, "defaultdict", (PyObject *)&defdict_type);
Guido van Rossum1968ad32006-02-25 22:38:04 +00002304
Eric Snow47db7172015-05-29 22:21:39 -06002305 Py_INCREF(&PyODict_Type);
2306 PyModule_AddObject(m, "OrderedDict", (PyObject *)&PyODict_Type);
2307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002308 if (PyType_Ready(&dequeiter_type) < 0)
2309 return NULL;
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002310 Py_INCREF(&dequeiter_type);
2311 PyModule_AddObject(m, "_deque_iterator", (PyObject *)&dequeiter_type);
Raymond Hettinger756b3f32004-01-29 06:37:52 +00002312
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002313 if (PyType_Ready(&dequereviter_type) < 0)
2314 return NULL;
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00002315 Py_INCREF(&dequereviter_type);
2316 PyModule_AddObject(m, "_deque_reverse_iterator", (PyObject *)&dequereviter_type);
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00002317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002318 return m;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00002319}