blob: 6115c702a9391e2f1db6c4b41d77d3d8ff63e112 [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
4/* collections module implementation of a deque() datatype
5 Written and maintained by Raymond D. Hettinger <python@rcn.com>
Raymond Hettinger756b3f32004-01-29 06:37:52 +00006*/
7
Raymond Hettinger77e8bf12004-10-01 15:25:53 +00008/* The block length may be set to any number over 1. Larger numbers
Raymond Hettinger20b0f872013-06-23 15:44:33 -07009 * reduce the number of calls to the memory allocator, give faster
10 * indexing and rotation, and reduce the link::data overhead ratio.
Raymond Hettinger77578202013-07-28 02:39:49 -070011 *
12 * Ideally, the block length will be set to two less than some
13 * multiple of the cache-line length (so that the full block
14 * including the leftlink and rightlink will fit neatly into
15 * cache lines).
Raymond Hettinger77e8bf12004-10-01 15:25:53 +000016 */
17
Raymond Hettinger77578202013-07-28 02:39:49 -070018#define BLOCKLEN 62
Raymond Hettinger61f05fb2004-10-01 06:24:12 +000019#define CENTER ((BLOCKLEN - 1) / 2)
Raymond Hettinger756b3f32004-01-29 06:37:52 +000020
Tim Petersd8768d32004-10-01 01:32:53 +000021/* A `dequeobject` is composed of a doubly-linked list of `block` nodes.
Raymond Hettinger61f05fb2004-10-01 06:24:12 +000022 * The list of blocks is never empty, so d.leftblock and d.rightblock
Raymond Hettinger82df9252013-07-07 01:43:42 -100023 * are never equal to NULL. The list is not circular.
24 *
25 * A deque d's first element is at d.leftblock[leftindex]
26 * and its last element is at d.rightblock[rightindex].
27 * Unlike Python slice indices, these indices are inclusive
28 * on both ends. This makes the algorithms for left and
29 * right operations more symmetrical and simplifies the design.
Raymond Hettinger61f05fb2004-10-01 06:24:12 +000030 *
31 * The indices, d.leftindex and d.rightindex are always in the range
32 * 0 <= index < BLOCKLEN.
Raymond Hettinger4ca4c7c2004-10-01 15:14:39 +000033 * Their exact relationship is:
34 * (d.leftindex + d.len - 1) % BLOCKLEN == d.rightindex.
Raymond Hettinger61f05fb2004-10-01 06:24:12 +000035 *
36 * Empty deques have d.len == 0; d.leftblock==d.rightblock;
37 * d.leftindex == CENTER+1; and d.rightindex == CENTER.
38 * Checking for d.len == 0 is the intended way to see whether d is empty.
39 *
Thomas Wouters0e3f5912006-08-11 14:57:12 +000040 * Whenever d.leftblock == d.rightblock,
Raymond Hettinger4ca4c7c2004-10-01 15:14:39 +000041 * d.leftindex + d.len - 1 == d.rightindex.
Thomas Wouters0e3f5912006-08-11 14:57:12 +000042 *
Raymond Hettinger4ca4c7c2004-10-01 15:14:39 +000043 * However, when d.leftblock != d.rightblock, d.leftindex and d.rightindex
Thomas Wouters0e3f5912006-08-11 14:57:12 +000044 * become indices into distinct blocks and either may be larger than the
Raymond Hettinger4ca4c7c2004-10-01 15:14:39 +000045 * other.
Tim Petersd8768d32004-10-01 01:32:53 +000046 */
47
Raymond Hettinger756b3f32004-01-29 06:37:52 +000048typedef struct BLOCK {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000049 struct BLOCK *leftlink;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000050 PyObject *data[BLOCKLEN];
Raymond Hettinger20b0f872013-06-23 15:44:33 -070051 struct BLOCK *rightlink;
Raymond Hettinger756b3f32004-01-29 06:37:52 +000052} block;
53
Raymond Hettinger82df9252013-07-07 01:43:42 -100054/* For debug builds, add error checking to track the endpoints
55 * in the chain of links. The goal is to make sure that link
56 * assignments only take place at endpoints so that links already
57 * in use do not get overwritten.
58 *
59 * CHECK_END should happen before each assignment to a block's link field.
60 * MARK_END should happen whenever a link field becomes a new endpoint.
61 * This happens when new blocks are added or whenever an existing
62 * block is freed leaving another existing block as the new endpoint.
63 */
64
Raymond Hettinger3223dd52013-07-26 23:14:22 -070065#ifndef NDEBUG
Raymond Hettinger82df9252013-07-07 01:43:42 -100066#define MARK_END(link) link = NULL;
67#define CHECK_END(link) assert(link == NULL);
68#define CHECK_NOT_END(link) assert(link != NULL);
69#else
70#define MARK_END(link)
71#define CHECK_END(link)
72#define CHECK_NOT_END(link)
73#endif
74
75/* A simple freelisting scheme is used to minimize calls to the memory
76 allocator. It accomodates common use cases where new blocks are being
77 added at about the same rate as old blocks are being freed.
78 */
79
Guido van Rossum58da9312007-11-10 23:39:45 +000080#define MAXFREEBLOCKS 10
Benjamin Petersond6313712008-07-31 16:23:04 +000081static Py_ssize_t numfreeblocks = 0;
Guido van Rossum58da9312007-11-10 23:39:45 +000082static block *freeblocks[MAXFREEBLOCKS];
83
Tim Peters6f853562004-10-01 01:04:50 +000084static block *
Raymond Hettinger82df9252013-07-07 01:43:42 -100085newblock(Py_ssize_t len) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000086 block *b;
Raymond Hettinger20b0f872013-06-23 15:44:33 -070087 /* To prevent len from overflowing PY_SSIZE_T_MAX, we refuse to
88 * allocate new blocks if the current len is nearing overflow. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000089 if (len >= PY_SSIZE_T_MAX - 2*BLOCKLEN) {
90 PyErr_SetString(PyExc_OverflowError,
91 "cannot add more blocks to the deque");
92 return NULL;
93 }
94 if (numfreeblocks) {
Raymond Hettinger59cf23a2013-02-07 00:57:19 -050095 numfreeblocks--;
Raymond Hettinger82df9252013-07-07 01:43:42 -100096 return freeblocks[numfreeblocks];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000097 }
Raymond Hettinger82df9252013-07-07 01:43:42 -100098 b = PyMem_Malloc(sizeof(block));
99 if (b != NULL) {
100 return b;
101 }
102 PyErr_NoMemory();
103 return NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000104}
105
Martin v. Löwis59683e82008-06-13 07:50:45 +0000106static void
Guido van Rossum58da9312007-11-10 23:39:45 +0000107freeblock(block *b)
108{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000109 if (numfreeblocks < MAXFREEBLOCKS) {
110 freeblocks[numfreeblocks] = b;
111 numfreeblocks++;
112 } else {
113 PyMem_Free(b);
114 }
Guido van Rossum58da9312007-11-10 23:39:45 +0000115}
116
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000117typedef struct {
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000118 PyObject_VAR_HEAD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000119 block *leftblock;
120 block *rightblock;
121 Py_ssize_t leftindex; /* in range(BLOCKLEN) */
122 Py_ssize_t rightindex; /* in range(BLOCKLEN) */
Raymond Hettinger90dea4c2013-07-13 22:30:25 -0700123 long state; /* incremented whenever the indices move */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000124 Py_ssize_t maxlen;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000125 PyObject *weakreflist; /* List of weak references */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000126} dequeobject;
127
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000128/* The deque's size limit is d.maxlen. The limit can be zero or positive.
129 * If there is no limit, then d.maxlen == -1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000130 *
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000131 * After an item is added to a deque, we check to see if the size has grown past
132 * the limit. If it has, we get the size back down to the limit by popping an
133 * item off of the opposite end. The methods that can trigger this are append(),
134 * appendleft(), extend(), and extendleft().
135 */
136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000137#define TRIM(d, popfunction) \
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000138 if (d->maxlen != -1 && Py_SIZE(d) > d->maxlen) { \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000139 PyObject *rv = popfunction(d, NULL); \
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000140 assert(rv != NULL && Py_SIZE(d) <= d->maxlen); \
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000141 Py_DECREF(rv); \
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000142 }
143
Neal Norwitz87f10132004-02-29 15:40:53 +0000144static PyTypeObject deque_type;
Raymond Hettinger738ec902004-02-29 02:15:56 +0000145
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000146static PyObject *
147deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
148{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000149 dequeobject *deque;
150 block *b;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000151
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000152 /* create dequeobject structure */
153 deque = (dequeobject *)type->tp_alloc(type, 0);
154 if (deque == NULL)
155 return NULL;
Tim Peters1065f752004-10-01 01:03:29 +0000156
Raymond Hettinger82df9252013-07-07 01:43:42 -1000157 b = newblock(0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000158 if (b == NULL) {
159 Py_DECREF(deque);
160 return NULL;
161 }
Raymond Hettinger82df9252013-07-07 01:43:42 -1000162 MARK_END(b->leftlink);
163 MARK_END(b->rightlink);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 assert(BLOCKLEN >= 2);
166 deque->leftblock = b;
167 deque->rightblock = b;
168 deque->leftindex = CENTER + 1;
169 deque->rightindex = CENTER;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000170 Py_SIZE(deque) = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000171 deque->state = 0;
172 deque->weakreflist = NULL;
173 deque->maxlen = -1;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000175 return (PyObject *)deque;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000176}
177
178static PyObject *
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000179deque_pop(dequeobject *deque, PyObject *unused)
180{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000181 PyObject *item;
182 block *prevblock;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000183
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000184 if (Py_SIZE(deque) == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000185 PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
186 return NULL;
187 }
188 item = deque->rightblock->data[deque->rightindex];
189 deque->rightindex--;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000190 Py_SIZE(deque)--;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000191 deque->state++;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000192
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000193 if (deque->rightindex == -1) {
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000194 if (Py_SIZE(deque) == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000195 assert(deque->leftblock == deque->rightblock);
196 assert(deque->leftindex == deque->rightindex+1);
197 /* re-center instead of freeing a block */
198 deque->leftindex = CENTER + 1;
199 deque->rightindex = CENTER;
200 } else {
201 prevblock = deque->rightblock->leftlink;
202 assert(deque->leftblock != deque->rightblock);
203 freeblock(deque->rightblock);
Raymond Hettinger82df9252013-07-07 01:43:42 -1000204 CHECK_NOT_END(prevblock);
205 MARK_END(prevblock->rightlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000206 deque->rightblock = prevblock;
207 deque->rightindex = BLOCKLEN - 1;
208 }
209 }
210 return item;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000211}
212
213PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element.");
214
215static PyObject *
216deque_popleft(dequeobject *deque, PyObject *unused)
217{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000218 PyObject *item;
219 block *prevblock;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000220
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000221 if (Py_SIZE(deque) == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
223 return NULL;
224 }
225 assert(deque->leftblock != NULL);
226 item = deque->leftblock->data[deque->leftindex];
227 deque->leftindex++;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000228 Py_SIZE(deque)--;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000229 deque->state++;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000231 if (deque->leftindex == BLOCKLEN) {
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000232 if (Py_SIZE(deque) == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000233 assert(deque->leftblock == deque->rightblock);
234 assert(deque->leftindex == deque->rightindex+1);
235 /* re-center instead of freeing a block */
236 deque->leftindex = CENTER + 1;
237 deque->rightindex = CENTER;
238 } else {
239 assert(deque->leftblock != deque->rightblock);
240 prevblock = deque->leftblock->rightlink;
241 freeblock(deque->leftblock);
Raymond Hettinger82df9252013-07-07 01:43:42 -1000242 CHECK_NOT_END(prevblock);
243 MARK_END(prevblock->leftlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000244 deque->leftblock = prevblock;
245 deque->leftindex = 0;
246 }
247 }
248 return item;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000249}
250
251PyDoc_STRVAR(popleft_doc, "Remove and return the leftmost element.");
252
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000253static PyObject *
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000254deque_append(dequeobject *deque, PyObject *item)
255{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 deque->state++;
257 if (deque->rightindex == BLOCKLEN-1) {
Raymond Hettinger82df9252013-07-07 01:43:42 -1000258 block *b = newblock(Py_SIZE(deque));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 if (b == NULL)
260 return NULL;
Raymond Hettinger82df9252013-07-07 01:43:42 -1000261 b->leftlink = deque->rightblock;
262 CHECK_END(deque->rightblock->rightlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000263 deque->rightblock->rightlink = b;
264 deque->rightblock = b;
Raymond Hettinger82df9252013-07-07 01:43:42 -1000265 MARK_END(b->rightlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000266 deque->rightindex = -1;
267 }
268 Py_INCREF(item);
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000269 Py_SIZE(deque)++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000270 deque->rightindex++;
271 deque->rightblock->data[deque->rightindex] = item;
272 TRIM(deque, deque_popleft);
273 Py_RETURN_NONE;
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000274}
275
276PyDoc_STRVAR(append_doc, "Add an element to the right side of the deque.");
277
278static PyObject *
279deque_appendleft(dequeobject *deque, PyObject *item)
280{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000281 deque->state++;
282 if (deque->leftindex == 0) {
Raymond Hettinger82df9252013-07-07 01:43:42 -1000283 block *b = newblock(Py_SIZE(deque));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 if (b == NULL)
285 return NULL;
Raymond Hettinger82df9252013-07-07 01:43:42 -1000286 b->rightlink = deque->leftblock;
287 CHECK_END(deque->leftblock->leftlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 deque->leftblock->leftlink = b;
289 deque->leftblock = b;
Raymond Hettinger82df9252013-07-07 01:43:42 -1000290 MARK_END(b->leftlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291 deque->leftindex = BLOCKLEN;
292 }
293 Py_INCREF(item);
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000294 Py_SIZE(deque)++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000295 deque->leftindex--;
296 deque->leftblock->data[deque->leftindex] = item;
297 TRIM(deque, deque_pop);
298 Py_RETURN_NONE;
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000299}
300
301PyDoc_STRVAR(appendleft_doc, "Add an element to the left side of the deque.");
302
Raymond Hettinger060c7f62009-03-10 09:36:07 +0000303
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304/* Run an iterator to exhaustion. Shortcut for
Raymond Hettinger060c7f62009-03-10 09:36:07 +0000305 the extend/extendleft methods when maxlen == 0. */
306static PyObject*
307consume_iterator(PyObject *it)
308{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 PyObject *item;
Raymond Hettinger060c7f62009-03-10 09:36:07 +0000310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 while ((item = PyIter_Next(it)) != NULL) {
312 Py_DECREF(item);
313 }
314 Py_DECREF(it);
315 if (PyErr_Occurred())
316 return NULL;
317 Py_RETURN_NONE;
Raymond Hettinger060c7f62009-03-10 09:36:07 +0000318}
319
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000320static PyObject *
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000321deque_extend(dequeobject *deque, PyObject *iterable)
322{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 PyObject *it, *item;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000325 /* Handle case where id(deque) == id(iterable) */
326 if ((PyObject *)deque == iterable) {
327 PyObject *result;
328 PyObject *s = PySequence_List(iterable);
329 if (s == NULL)
330 return NULL;
331 result = deque_extend(deque, s);
332 Py_DECREF(s);
333 return result;
334 }
Raymond Hettinger3f9afd82009-12-10 03:03:02 +0000335
Raymond Hettingerd9c116c2013-07-09 00:13:21 -0700336 /* Space saving heuristic. Start filling from the left */
337 if (Py_SIZE(deque) == 0) {
338 assert(deque->leftblock == deque->rightblock);
339 assert(deque->leftindex == deque->rightindex+1);
340 deque->leftindex = 1;
341 deque->rightindex = 0;
342 }
343
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000344 it = PyObject_GetIter(iterable);
345 if (it == NULL)
346 return NULL;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000347
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000348 if (deque->maxlen == 0)
349 return consume_iterator(it);
Raymond Hettinger060c7f62009-03-10 09:36:07 +0000350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000351 while ((item = PyIter_Next(it)) != NULL) {
352 deque->state++;
353 if (deque->rightindex == BLOCKLEN-1) {
Raymond Hettinger82df9252013-07-07 01:43:42 -1000354 block *b = newblock(Py_SIZE(deque));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 if (b == NULL) {
356 Py_DECREF(item);
357 Py_DECREF(it);
358 return NULL;
359 }
Raymond Hettinger82df9252013-07-07 01:43:42 -1000360 b->leftlink = deque->rightblock;
361 CHECK_END(deque->rightblock->rightlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000362 deque->rightblock->rightlink = b;
363 deque->rightblock = b;
Raymond Hettinger82df9252013-07-07 01:43:42 -1000364 MARK_END(b->rightlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000365 deque->rightindex = -1;
366 }
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000367 Py_SIZE(deque)++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000368 deque->rightindex++;
369 deque->rightblock->data[deque->rightindex] = item;
370 TRIM(deque, deque_popleft);
371 }
372 Py_DECREF(it);
373 if (PyErr_Occurred())
374 return NULL;
375 Py_RETURN_NONE;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000376}
377
Tim Peters1065f752004-10-01 01:03:29 +0000378PyDoc_STRVAR(extend_doc,
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000379"Extend the right side of the deque with elements from the iterable");
380
381static PyObject *
382deque_extendleft(dequeobject *deque, PyObject *iterable)
383{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000384 PyObject *it, *item;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000386 /* Handle case where id(deque) == id(iterable) */
387 if ((PyObject *)deque == iterable) {
388 PyObject *result;
389 PyObject *s = PySequence_List(iterable);
390 if (s == NULL)
391 return NULL;
392 result = deque_extendleft(deque, s);
393 Py_DECREF(s);
394 return result;
395 }
Raymond Hettinger3f9afd82009-12-10 03:03:02 +0000396
Raymond Hettingerd9c116c2013-07-09 00:13:21 -0700397 /* Space saving heuristic. Start filling from the right */
398 if (Py_SIZE(deque) == 0) {
399 assert(deque->leftblock == deque->rightblock);
400 assert(deque->leftindex == deque->rightindex+1);
401 deque->leftindex = BLOCKLEN - 1;
402 deque->rightindex = BLOCKLEN - 2;
403 }
404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 it = PyObject_GetIter(iterable);
406 if (it == NULL)
407 return NULL;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000408
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000409 if (deque->maxlen == 0)
410 return consume_iterator(it);
Raymond Hettinger060c7f62009-03-10 09:36:07 +0000411
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412 while ((item = PyIter_Next(it)) != NULL) {
413 deque->state++;
414 if (deque->leftindex == 0) {
Raymond Hettinger82df9252013-07-07 01:43:42 -1000415 block *b = newblock(Py_SIZE(deque));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000416 if (b == NULL) {
417 Py_DECREF(item);
418 Py_DECREF(it);
419 return NULL;
420 }
Raymond Hettinger82df9252013-07-07 01:43:42 -1000421 b->rightlink = deque->leftblock;
422 CHECK_END(deque->leftblock->leftlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000423 deque->leftblock->leftlink = b;
424 deque->leftblock = b;
Raymond Hettinger82df9252013-07-07 01:43:42 -1000425 MARK_END(b->leftlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 deque->leftindex = BLOCKLEN;
427 }
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000428 Py_SIZE(deque)++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000429 deque->leftindex--;
430 deque->leftblock->data[deque->leftindex] = item;
431 TRIM(deque, deque_pop);
432 }
433 Py_DECREF(it);
434 if (PyErr_Occurred())
435 return NULL;
436 Py_RETURN_NONE;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000437}
438
Tim Peters1065f752004-10-01 01:03:29 +0000439PyDoc_STRVAR(extendleft_doc,
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000440"Extend the left side of the deque with elements from the iterable");
441
Raymond Hettinger3f9afd82009-12-10 03:03:02 +0000442static PyObject *
443deque_inplace_concat(dequeobject *deque, PyObject *other)
444{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000445 PyObject *result;
Raymond Hettinger3f9afd82009-12-10 03:03:02 +0000446
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000447 result = deque_extend(deque, other);
448 if (result == NULL)
449 return result;
450 Py_DECREF(result);
451 Py_INCREF(deque);
452 return (PyObject *)deque;
Raymond Hettinger3f9afd82009-12-10 03:03:02 +0000453}
454
Raymond Hettingerdcb9d942004-10-09 16:02:18 +0000455static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000456_deque_rotate(dequeobject *deque, Py_ssize_t n)
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000457{
Raymond Hettinger3959af92013-07-13 02:34:08 -0700458 block *b = NULL;
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700459 block *leftblock = deque->leftblock;
460 block *rightblock = deque->rightblock;
461 Py_ssize_t leftindex = deque->leftindex;
462 Py_ssize_t rightindex = deque->rightindex;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000463 Py_ssize_t len=Py_SIZE(deque), halflen=len>>1;
Raymond Hettinger3959af92013-07-13 02:34:08 -0700464 int rv = -1;
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000465
Raymond Hettinger464d89b2013-01-11 22:29:50 -0800466 if (len <= 1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000467 return 0;
468 if (n > halflen || n < -halflen) {
469 n %= len;
470 if (n > halflen)
471 n -= len;
472 else if (n < -halflen)
473 n += len;
474 }
Raymond Hettinger1f0044c2013-02-05 01:30:46 -0500475 assert(len > 1);
Raymond Hettingera4409c12013-02-04 00:08:12 -0500476 assert(-halflen <= n && n <= halflen);
Raymond Hettinger231ee4d2013-02-02 11:24:43 -0800477
Raymond Hettinger464d89b2013-01-11 22:29:50 -0800478 deque->state++;
Raymond Hettinger1f0044c2013-02-05 01:30:46 -0500479 while (n > 0) {
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700480 if (leftindex == 0) {
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700481 if (b == NULL) {
Raymond Hettinger3959af92013-07-13 02:34:08 -0700482 b = newblock(len);
483 if (b == NULL)
484 goto done;
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700485 }
Raymond Hettinger82df9252013-07-07 01:43:42 -1000486 b->rightlink = leftblock;
487 CHECK_END(leftblock->leftlink);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700488 leftblock->leftlink = b;
489 leftblock = b;
Raymond Hettinger82df9252013-07-07 01:43:42 -1000490 MARK_END(b->leftlink);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700491 leftindex = BLOCKLEN;
Raymond Hettinger3959af92013-07-13 02:34:08 -0700492 b = NULL;
Raymond Hettinger464d89b2013-01-11 22:29:50 -0800493 }
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700494 assert(leftindex > 0);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700495 {
496 PyObject **src, **dest;
497 Py_ssize_t m = n;
Raymond Hettinger21777ac2013-02-02 09:56:08 -0800498
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700499 if (m > rightindex + 1)
500 m = rightindex + 1;
501 if (m > leftindex)
502 m = leftindex;
503 assert (m > 0 && m <= len);
504 src = &rightblock->data[rightindex];
505 dest = &leftblock->data[leftindex - 1];
506 rightindex -= m;
507 leftindex -= m;
508 n -= m;
Raymond Hettinger840533b2013-07-13 17:03:58 -0700509 do {
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700510 *(dest--) = *(src--);
Raymond Hettinger840533b2013-07-13 17:03:58 -0700511 } while (--m);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700512 }
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700513 if (rightindex == -1) {
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700514 assert(leftblock != rightblock);
Raymond Hettinger840533b2013-07-13 17:03:58 -0700515 assert(b == NULL);
Raymond Hettinger3959af92013-07-13 02:34:08 -0700516 b = rightblock;
Raymond Hettingerb97cc492013-07-21 01:51:07 -0700517 CHECK_NOT_END(rightblock->leftlink);
518 rightblock = rightblock->leftlink;
519 MARK_END(rightblock->rightlink);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700520 rightindex = BLOCKLEN - 1;
Raymond Hettinger464d89b2013-01-11 22:29:50 -0800521 }
Raymond Hettinger21777ac2013-02-02 09:56:08 -0800522 }
Raymond Hettinger1f0044c2013-02-05 01:30:46 -0500523 while (n < 0) {
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700524 if (rightindex == BLOCKLEN - 1) {
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700525 if (b == NULL) {
Raymond Hettinger3959af92013-07-13 02:34:08 -0700526 b = newblock(len);
527 if (b == NULL)
528 goto done;
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700529 }
Raymond Hettinger82df9252013-07-07 01:43:42 -1000530 b->leftlink = rightblock;
531 CHECK_END(rightblock->rightlink);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700532 rightblock->rightlink = b;
533 rightblock = b;
Raymond Hettinger82df9252013-07-07 01:43:42 -1000534 MARK_END(b->rightlink);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700535 rightindex = -1;
Raymond Hettinger3959af92013-07-13 02:34:08 -0700536 b = NULL;
Raymond Hettinger464d89b2013-01-11 22:29:50 -0800537 }
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700538 assert (rightindex < BLOCKLEN - 1);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700539 {
540 PyObject **src, **dest;
541 Py_ssize_t m = -n;
Raymond Hettinger21777ac2013-02-02 09:56:08 -0800542
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700543 if (m > BLOCKLEN - leftindex)
544 m = BLOCKLEN - leftindex;
545 if (m > BLOCKLEN - 1 - rightindex)
546 m = BLOCKLEN - 1 - rightindex;
547 assert (m > 0 && m <= len);
548 src = &leftblock->data[leftindex];
549 dest = &rightblock->data[rightindex + 1];
550 leftindex += m;
551 rightindex += m;
552 n += m;
Raymond Hettinger840533b2013-07-13 17:03:58 -0700553 do {
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700554 *(dest++) = *(src++);
Raymond Hettinger840533b2013-07-13 17:03:58 -0700555 } while (--m);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700556 }
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700557 if (leftindex == BLOCKLEN) {
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700558 assert(leftblock != rightblock);
Raymond Hettinger840533b2013-07-13 17:03:58 -0700559 assert(b == NULL);
Raymond Hettinger3959af92013-07-13 02:34:08 -0700560 b = leftblock;
Raymond Hettingerb97cc492013-07-21 01:51:07 -0700561 CHECK_NOT_END(leftblock->rightlink);
562 leftblock = leftblock->rightlink;
563 MARK_END(leftblock->leftlink);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700564 leftindex = 0;
Raymond Hettinger21777ac2013-02-02 09:56:08 -0800565 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 }
Raymond Hettinger3959af92013-07-13 02:34:08 -0700567 rv = 0;
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700568done:
Raymond Hettinger3959af92013-07-13 02:34:08 -0700569 if (b != NULL)
570 freeblock(b);
Raymond Hettinger20b0f872013-06-23 15:44:33 -0700571 deque->leftblock = leftblock;
572 deque->rightblock = rightblock;
573 deque->leftindex = leftindex;
574 deque->rightindex = rightindex;
575
576 return rv;
Raymond Hettingerdcb9d942004-10-09 16:02:18 +0000577}
578
579static PyObject *
580deque_rotate(dequeobject *deque, PyObject *args)
581{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000582 Py_ssize_t n=1;
Raymond Hettingerdcb9d942004-10-09 16:02:18 +0000583
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000584 if (!PyArg_ParseTuple(args, "|n:rotate", &n))
585 return NULL;
586 if (_deque_rotate(deque, n) == 0)
587 Py_RETURN_NONE;
588 return NULL;
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000589}
590
Tim Peters1065f752004-10-01 01:03:29 +0000591PyDoc_STRVAR(rotate_doc,
Raymond Hettingeree33b272004-02-08 04:05:26 +0000592"Rotate the deque n steps to the right (default n=1). If n is negative, rotates left.");
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000593
Raymond Hettingere5fdedb2009-12-10 00:47:21 +0000594static PyObject *
595deque_reverse(dequeobject *deque, PyObject *unused)
596{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000597 block *leftblock = deque->leftblock;
598 block *rightblock = deque->rightblock;
599 Py_ssize_t leftindex = deque->leftindex;
600 Py_ssize_t rightindex = deque->rightindex;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000601 Py_ssize_t n = (Py_SIZE(deque))/2;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000602 Py_ssize_t i;
603 PyObject *tmp;
Raymond Hettingere5fdedb2009-12-10 00:47:21 +0000604
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000605 for (i=0 ; i<n ; i++) {
606 /* Validate that pointers haven't met in the middle */
607 assert(leftblock != rightblock || leftindex < rightindex);
Raymond Hettinger82df9252013-07-07 01:43:42 -1000608 CHECK_NOT_END(leftblock);
609 CHECK_NOT_END(rightblock);
Raymond Hettingere5fdedb2009-12-10 00:47:21 +0000610
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000611 /* Swap */
612 tmp = leftblock->data[leftindex];
613 leftblock->data[leftindex] = rightblock->data[rightindex];
614 rightblock->data[rightindex] = tmp;
Raymond Hettingere5fdedb2009-12-10 00:47:21 +0000615
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000616 /* Advance left block/index pair */
617 leftindex++;
618 if (leftindex == BLOCKLEN) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000619 leftblock = leftblock->rightlink;
620 leftindex = 0;
621 }
Raymond Hettingere5fdedb2009-12-10 00:47:21 +0000622
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000623 /* Step backwards with the right block/index pair */
624 rightindex--;
625 if (rightindex == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 rightblock = rightblock->leftlink;
627 rightindex = BLOCKLEN - 1;
628 }
629 }
630 Py_RETURN_NONE;
Raymond Hettingere5fdedb2009-12-10 00:47:21 +0000631}
632
633PyDoc_STRVAR(reverse_doc,
634"D.reverse() -- reverse *IN PLACE*");
635
Raymond Hettinger44459de2010-04-03 23:20:46 +0000636static PyObject *
637deque_count(dequeobject *deque, PyObject *v)
638{
Raymond Hettingerf3a67b72013-07-06 17:49:06 -1000639 block *b = deque->leftblock;
640 Py_ssize_t index = deque->leftindex;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000641 Py_ssize_t n = Py_SIZE(deque);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000642 Py_ssize_t i;
643 Py_ssize_t count = 0;
644 PyObject *item;
645 long start_state = deque->state;
646 int cmp;
Raymond Hettinger44459de2010-04-03 23:20:46 +0000647
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 for (i=0 ; i<n ; i++) {
Raymond Hettinger82df9252013-07-07 01:43:42 -1000649 CHECK_NOT_END(b);
Raymond Hettingerf3a67b72013-07-06 17:49:06 -1000650 item = b->data[index];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000651 cmp = PyObject_RichCompareBool(item, v, Py_EQ);
652 if (cmp > 0)
653 count++;
654 else if (cmp < 0)
655 return NULL;
Raymond Hettinger44459de2010-04-03 23:20:46 +0000656
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000657 if (start_state != deque->state) {
658 PyErr_SetString(PyExc_RuntimeError,
659 "deque mutated during iteration");
660 return NULL;
661 }
Raymond Hettinger44459de2010-04-03 23:20:46 +0000662
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000663 /* Advance left block/index pair */
Raymond Hettingerf3a67b72013-07-06 17:49:06 -1000664 index++;
665 if (index == BLOCKLEN) {
666 b = b->rightlink;
667 index = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000668 }
669 }
670 return PyLong_FromSsize_t(count);
Raymond Hettinger44459de2010-04-03 23:20:46 +0000671}
672
673PyDoc_STRVAR(count_doc,
674"D.count(value) -> integer -- return number of occurrences of value");
675
Martin v. Löwis18e16552006-02-15 17:27:45 +0000676static Py_ssize_t
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000677deque_len(dequeobject *deque)
678{
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000679 return Py_SIZE(deque);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000680}
681
Raymond Hettinger4aec61e2005-03-18 21:20:23 +0000682static PyObject *
683deque_remove(dequeobject *deque, PyObject *value)
684{
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000685 Py_ssize_t i, n=Py_SIZE(deque);
Raymond Hettinger4aec61e2005-03-18 21:20:23 +0000686
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000687 for (i=0 ; i<n ; i++) {
688 PyObject *item = deque->leftblock->data[deque->leftindex];
689 int cmp = PyObject_RichCompareBool(item, value, Py_EQ);
Raymond Hettingerd73202c2005-03-19 00:00:51 +0000690
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000691 if (Py_SIZE(deque) != n) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000692 PyErr_SetString(PyExc_IndexError,
693 "deque mutated during remove().");
694 return NULL;
695 }
696 if (cmp > 0) {
697 PyObject *tgt = deque_popleft(deque, NULL);
698 assert (tgt != NULL);
Raymond Hettingerc6249a62015-05-02 10:44:17 -0700699 if (_deque_rotate(deque, i))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000700 return NULL;
Raymond Hettingerc6249a62015-05-02 10:44:17 -0700701 Py_DECREF(tgt);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000702 Py_RETURN_NONE;
703 }
704 else if (cmp < 0) {
705 _deque_rotate(deque, i);
706 return NULL;
707 }
708 _deque_rotate(deque, -1);
709 }
710 PyErr_SetString(PyExc_ValueError, "deque.remove(x): x not in deque");
711 return NULL;
Raymond Hettinger4aec61e2005-03-18 21:20:23 +0000712}
713
714PyDoc_STRVAR(remove_doc,
715"D.remove(value) -- remove first occurrence of value.");
716
Benjamin Peterson0e5c48a2013-01-12 21:22:18 -0500717static void
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000718deque_clear(dequeobject *deque)
719{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 PyObject *item;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000721
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000722 while (Py_SIZE(deque)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 item = deque_pop(deque, NULL);
724 assert (item != NULL);
725 Py_DECREF(item);
726 }
727 assert(deque->leftblock == deque->rightblock &&
728 deque->leftindex - 1 == deque->rightindex &&
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000729 Py_SIZE(deque) == 0);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000730}
731
732static PyObject *
Benjamin Petersond6313712008-07-31 16:23:04 +0000733deque_item(dequeobject *deque, Py_ssize_t i)
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000734{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000735 block *b;
736 PyObject *item;
737 Py_ssize_t n, index=i;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000738
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000739 if (i < 0 || i >= Py_SIZE(deque)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000740 PyErr_SetString(PyExc_IndexError,
741 "deque index out of range");
742 return NULL;
743 }
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000744
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000745 if (i == 0) {
746 i = deque->leftindex;
747 b = deque->leftblock;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000748 } else if (i == Py_SIZE(deque) - 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000749 i = deque->rightindex;
750 b = deque->rightblock;
751 } else {
752 i += deque->leftindex;
753 n = i / BLOCKLEN;
754 i %= BLOCKLEN;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000755 if (index < (Py_SIZE(deque) >> 1)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000756 b = deque->leftblock;
757 while (n--)
758 b = b->rightlink;
759 } else {
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000760 n = (deque->leftindex + Py_SIZE(deque) - 1) / BLOCKLEN - n;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000761 b = deque->rightblock;
762 while (n--)
763 b = b->leftlink;
764 }
765 }
766 item = b->data[i];
767 Py_INCREF(item);
768 return item;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000769}
770
Raymond Hettinger616f4f62004-06-26 04:42:06 +0000771/* delitem() implemented in terms of rotate for simplicity and reasonable
772 performance near the end points. If for some reason this method becomes
Tim Peters1065f752004-10-01 01:03:29 +0000773 popular, it is not hard to re-implement this using direct data movement
Raymond Hettinger616f4f62004-06-26 04:42:06 +0000774 (similar to code in list slice assignment) and achieve a two or threefold
775 performance boost.
776*/
777
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000778static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000779deque_del_item(dequeobject *deque, Py_ssize_t i)
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000780{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000781 PyObject *item;
Raymond Hettingerc6249a62015-05-02 10:44:17 -0700782 int rv;
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000783
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000784 assert (i >= 0 && i < Py_SIZE(deque));
Raymond Hettingerc6249a62015-05-02 10:44:17 -0700785 if (_deque_rotate(deque, -i))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000786 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000787 item = deque_popleft(deque, NULL);
Raymond Hettingerc6249a62015-05-02 10:44:17 -0700788 rv = _deque_rotate(deque, i);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000789 assert (item != NULL);
790 Py_DECREF(item);
Raymond Hettingerc6249a62015-05-02 10:44:17 -0700791 return rv;
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000792}
793
794static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000795deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v)
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000796{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000797 PyObject *old_value;
798 block *b;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000799 Py_ssize_t n, len=Py_SIZE(deque), halflen=(len+1)>>1, index=i;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000800
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000801 if (i < 0 || i >= len) {
802 PyErr_SetString(PyExc_IndexError,
803 "deque index out of range");
804 return -1;
805 }
806 if (v == NULL)
807 return deque_del_item(deque, i);
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000808
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000809 i += deque->leftindex;
810 n = i / BLOCKLEN;
811 i %= BLOCKLEN;
812 if (index <= halflen) {
813 b = deque->leftblock;
814 while (n--)
815 b = b->rightlink;
816 } else {
817 n = (deque->leftindex + len - 1) / BLOCKLEN - n;
818 b = deque->rightblock;
819 while (n--)
820 b = b->leftlink;
821 }
822 Py_INCREF(v);
823 old_value = b->data[i];
824 b->data[i] = v;
825 Py_DECREF(old_value);
826 return 0;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000827}
828
829static PyObject *
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000830deque_clearmethod(dequeobject *deque)
831{
Benjamin Peterson0e5c48a2013-01-12 21:22:18 -0500832 deque_clear(deque);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000833 Py_RETURN_NONE;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000834}
835
836PyDoc_STRVAR(clear_doc, "Remove all elements from the deque.");
837
838static void
839deque_dealloc(dequeobject *deque)
840{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000841 PyObject_GC_UnTrack(deque);
842 if (deque->weakreflist != NULL)
843 PyObject_ClearWeakRefs((PyObject *) deque);
844 if (deque->leftblock != NULL) {
845 deque_clear(deque);
846 assert(deque->leftblock != NULL);
847 freeblock(deque->leftblock);
848 }
849 deque->leftblock = NULL;
850 deque->rightblock = NULL;
851 Py_TYPE(deque)->tp_free(deque);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000852}
853
854static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000855deque_traverse(dequeobject *deque, visitproc visit, void *arg)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000856{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000857 block *b;
858 PyObject *item;
859 Py_ssize_t index;
860 Py_ssize_t indexlo = deque->leftindex;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000861
Raymond Hettinger5bfa8672013-07-06 11:58:09 -1000862 for (b = deque->leftblock; b != deque->rightblock; b = b->rightlink) {
863 for (index = indexlo; index < BLOCKLEN ; index++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000864 item = b->data[index];
865 Py_VISIT(item);
866 }
867 indexlo = 0;
868 }
Raymond Hettinger5bfa8672013-07-06 11:58:09 -1000869 for (index = indexlo; index <= deque->rightindex; index++) {
870 item = b->data[index];
871 Py_VISIT(item);
872 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000873 return 0;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000874}
875
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000876static PyObject *
877deque_copy(PyObject *deque)
878{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000879 if (((dequeobject *)deque)->maxlen == -1)
880 return PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "O", deque, NULL);
881 else
882 return PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "Oi",
883 deque, ((dequeobject *)deque)->maxlen, NULL);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000884}
885
886PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque.");
887
888static PyObject *
889deque_reduce(dequeobject *deque)
890{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000891 PyObject *dict, *result, *aslist;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200892 _Py_IDENTIFIER(__dict__);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000893
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +0200894 dict = _PyObject_GetAttrId((PyObject *)deque, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000895 if (dict == NULL)
896 PyErr_Clear();
897 aslist = PySequence_List((PyObject *)deque);
898 if (aslist == NULL) {
899 Py_XDECREF(dict);
900 return NULL;
901 }
902 if (dict == NULL) {
903 if (deque->maxlen == -1)
904 result = Py_BuildValue("O(O)", Py_TYPE(deque), aslist);
905 else
906 result = Py_BuildValue("O(On)", Py_TYPE(deque), aslist, deque->maxlen);
907 } else {
908 if (deque->maxlen == -1)
909 result = Py_BuildValue("O(OO)O", Py_TYPE(deque), aslist, Py_None, dict);
910 else
911 result = Py_BuildValue("O(On)O", Py_TYPE(deque), aslist, deque->maxlen, dict);
912 }
913 Py_XDECREF(dict);
914 Py_DECREF(aslist);
915 return result;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000916}
917
918PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
919
920static PyObject *
921deque_repr(PyObject *deque)
922{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000923 PyObject *aslist, *result;
924 int i;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000925
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000926 i = Py_ReprEnter(deque);
927 if (i != 0) {
928 if (i < 0)
929 return NULL;
930 return PyUnicode_FromString("[...]");
931 }
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000932
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000933 aslist = PySequence_List(deque);
934 if (aslist == NULL) {
935 Py_ReprLeave(deque);
936 return NULL;
937 }
938 if (((dequeobject *)deque)->maxlen != -1)
Benjamin Petersona786b022008-08-25 21:05:21 +0000939
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000940 result = PyUnicode_FromFormat("deque(%R, maxlen=%zd)",
941 aslist, ((dequeobject *)deque)->maxlen);
942 else
943 result = PyUnicode_FromFormat("deque(%R)", aslist);
944 Py_DECREF(aslist);
945 Py_ReprLeave(deque);
946 return result;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000947}
948
Raymond Hettinger738ec902004-02-29 02:15:56 +0000949static PyObject *
950deque_richcompare(PyObject *v, PyObject *w, int op)
951{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000952 PyObject *it1=NULL, *it2=NULL, *x, *y;
953 Py_ssize_t vs, ws;
954 int b, cmp=-1;
Raymond Hettinger738ec902004-02-29 02:15:56 +0000955
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000956 if (!PyObject_TypeCheck(v, &deque_type) ||
957 !PyObject_TypeCheck(w, &deque_type)) {
Brian Curtindfc80e32011-08-10 20:28:54 -0500958 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000959 }
Raymond Hettinger738ec902004-02-29 02:15:56 +0000960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000961 /* Shortcuts */
Raymond Hettingerdf715ba2013-07-06 13:01:13 -1000962 vs = Py_SIZE((dequeobject *)v);
963 ws = Py_SIZE((dequeobject *)w);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000964 if (op == Py_EQ) {
965 if (v == w)
966 Py_RETURN_TRUE;
967 if (vs != ws)
968 Py_RETURN_FALSE;
969 }
970 if (op == Py_NE) {
971 if (v == w)
972 Py_RETURN_FALSE;
973 if (vs != ws)
974 Py_RETURN_TRUE;
975 }
Raymond Hettinger738ec902004-02-29 02:15:56 +0000976
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000977 /* Search for the first index where items are different */
978 it1 = PyObject_GetIter(v);
979 if (it1 == NULL)
980 goto done;
981 it2 = PyObject_GetIter(w);
982 if (it2 == NULL)
983 goto done;
984 for (;;) {
985 x = PyIter_Next(it1);
986 if (x == NULL && PyErr_Occurred())
987 goto done;
988 y = PyIter_Next(it2);
989 if (x == NULL || y == NULL)
990 break;
991 b = PyObject_RichCompareBool(x, y, Py_EQ);
992 if (b == 0) {
993 cmp = PyObject_RichCompareBool(x, y, op);
994 Py_DECREF(x);
995 Py_DECREF(y);
996 goto done;
997 }
998 Py_DECREF(x);
999 Py_DECREF(y);
1000 if (b == -1)
1001 goto done;
1002 }
1003 /* We reached the end of one deque or both */
1004 Py_XDECREF(x);
1005 Py_XDECREF(y);
1006 if (PyErr_Occurred())
1007 goto done;
1008 switch (op) {
1009 case Py_LT: cmp = y != NULL; break; /* if w was longer */
1010 case Py_LE: cmp = x == NULL; break; /* if v was not longer */
1011 case Py_EQ: cmp = x == y; break; /* if we reached the end of both */
1012 case Py_NE: cmp = x != y; break; /* if one deque continues */
1013 case Py_GT: cmp = x != NULL; break; /* if v was longer */
1014 case Py_GE: cmp = y == NULL; break; /* if w was not longer */
1015 }
Tim Peters1065f752004-10-01 01:03:29 +00001016
Raymond Hettinger738ec902004-02-29 02:15:56 +00001017done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001018 Py_XDECREF(it1);
1019 Py_XDECREF(it2);
1020 if (cmp == 1)
1021 Py_RETURN_TRUE;
1022 if (cmp == 0)
1023 Py_RETURN_FALSE;
1024 return NULL;
Raymond Hettinger738ec902004-02-29 02:15:56 +00001025}
1026
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001027static int
Guido van Rossum8ce8a782007-11-01 19:42:39 +00001028deque_init(dequeobject *deque, PyObject *args, PyObject *kwdargs)
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001029{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001030 PyObject *iterable = NULL;
1031 PyObject *maxlenobj = NULL;
1032 Py_ssize_t maxlen = -1;
1033 char *kwlist[] = {"iterable", "maxlen", 0};
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001035 if (!PyArg_ParseTupleAndKeywords(args, kwdargs, "|OO:deque", kwlist, &iterable, &maxlenobj))
1036 return -1;
1037 if (maxlenobj != NULL && maxlenobj != Py_None) {
1038 maxlen = PyLong_AsSsize_t(maxlenobj);
1039 if (maxlen == -1 && PyErr_Occurred())
1040 return -1;
1041 if (maxlen < 0) {
1042 PyErr_SetString(PyExc_ValueError, "maxlen must be non-negative");
1043 return -1;
1044 }
1045 }
1046 deque->maxlen = maxlen;
1047 deque_clear(deque);
1048 if (iterable != NULL) {
1049 PyObject *rv = deque_extend(deque, iterable);
1050 if (rv == NULL)
1051 return -1;
1052 Py_DECREF(rv);
1053 }
1054 return 0;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001055}
1056
Raymond Hettinger5bb0f0e2009-03-10 12:56:32 +00001057static PyObject *
Jesus Cea16e2fca2012-08-03 14:49:42 +02001058deque_sizeof(dequeobject *deque, void *unused)
1059{
1060 Py_ssize_t res;
1061 Py_ssize_t blocks;
1062
1063 res = sizeof(dequeobject);
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001064 blocks = (deque->leftindex + Py_SIZE(deque) + BLOCKLEN - 1) / BLOCKLEN;
1065 assert(deque->leftindex + Py_SIZE(deque) - 1 ==
Jesus Cea16e2fca2012-08-03 14:49:42 +02001066 (blocks - 1) * BLOCKLEN + deque->rightindex);
1067 res += blocks * sizeof(block);
1068 return PyLong_FromSsize_t(res);
1069}
1070
1071PyDoc_STRVAR(sizeof_doc,
1072"D.__sizeof__() -- size of D in memory, in bytes");
1073
1074static PyObject *
Raymond Hettinger5bb0f0e2009-03-10 12:56:32 +00001075deque_get_maxlen(dequeobject *deque)
1076{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 if (deque->maxlen == -1)
1078 Py_RETURN_NONE;
1079 return PyLong_FromSsize_t(deque->maxlen);
Raymond Hettinger5bb0f0e2009-03-10 12:56:32 +00001080}
1081
1082static PyGetSetDef deque_getset[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001083 {"maxlen", (getter)deque_get_maxlen, (setter)NULL,
1084 "maximum size of a deque or None if unbounded"},
1085 {0}
Raymond Hettinger5bb0f0e2009-03-10 12:56:32 +00001086};
1087
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001088static PySequenceMethods deque_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001089 (lenfunc)deque_len, /* sq_length */
1090 0, /* sq_concat */
1091 0, /* sq_repeat */
1092 (ssizeargfunc)deque_item, /* sq_item */
1093 0, /* sq_slice */
1094 (ssizeobjargproc)deque_ass_item, /* sq_ass_item */
1095 0, /* sq_ass_slice */
1096 0, /* sq_contains */
1097 (binaryfunc)deque_inplace_concat, /* sq_inplace_concat */
1098 0, /* sq_inplace_repeat */
Raymond Hettinger3f9afd82009-12-10 03:03:02 +00001099
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001100};
1101
1102/* deque object ********************************************************/
1103
1104static PyObject *deque_iter(dequeobject *deque);
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001105static PyObject *deque_reviter(dequeobject *deque);
Tim Peters1065f752004-10-01 01:03:29 +00001106PyDoc_STRVAR(reversed_doc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001107 "D.__reversed__() -- return a reverse iterator over the deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001108
1109static PyMethodDef deque_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001110 {"append", (PyCFunction)deque_append,
1111 METH_O, append_doc},
1112 {"appendleft", (PyCFunction)deque_appendleft,
1113 METH_O, appendleft_doc},
1114 {"clear", (PyCFunction)deque_clearmethod,
1115 METH_NOARGS, clear_doc},
1116 {"__copy__", (PyCFunction)deque_copy,
1117 METH_NOARGS, copy_doc},
1118 {"count", (PyCFunction)deque_count,
1119 METH_O, count_doc},
1120 {"extend", (PyCFunction)deque_extend,
1121 METH_O, extend_doc},
1122 {"extendleft", (PyCFunction)deque_extendleft,
1123 METH_O, extendleft_doc},
1124 {"pop", (PyCFunction)deque_pop,
1125 METH_NOARGS, pop_doc},
1126 {"popleft", (PyCFunction)deque_popleft,
1127 METH_NOARGS, popleft_doc},
1128 {"__reduce__", (PyCFunction)deque_reduce,
1129 METH_NOARGS, reduce_doc},
1130 {"remove", (PyCFunction)deque_remove,
1131 METH_O, remove_doc},
1132 {"__reversed__", (PyCFunction)deque_reviter,
1133 METH_NOARGS, reversed_doc},
1134 {"reverse", (PyCFunction)deque_reverse,
1135 METH_NOARGS, reverse_doc},
1136 {"rotate", (PyCFunction)deque_rotate,
Jesus Cea16e2fca2012-08-03 14:49:42 +02001137 METH_VARARGS, rotate_doc},
1138 {"__sizeof__", (PyCFunction)deque_sizeof,
1139 METH_NOARGS, sizeof_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 {NULL, NULL} /* sentinel */
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001141};
1142
1143PyDoc_STRVAR(deque_doc,
Andrew Svetlov6a5c7c32012-10-31 11:50:40 +02001144"deque([iterable[, maxlen]]) --> deque object\n\
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001145\n\
Raymond Hettinger49747052011-03-29 17:36:31 -07001146Build an ordered collection with optimized access from its endpoints.");
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001147
Neal Norwitz87f10132004-02-29 15:40:53 +00001148static PyTypeObject deque_type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 PyVarObject_HEAD_INIT(NULL, 0)
1150 "collections.deque", /* tp_name */
1151 sizeof(dequeobject), /* tp_basicsize */
1152 0, /* tp_itemsize */
1153 /* methods */
1154 (destructor)deque_dealloc, /* tp_dealloc */
1155 0, /* tp_print */
1156 0, /* tp_getattr */
1157 0, /* tp_setattr */
1158 0, /* tp_reserved */
1159 deque_repr, /* tp_repr */
1160 0, /* tp_as_number */
1161 &deque_as_sequence, /* tp_as_sequence */
1162 0, /* tp_as_mapping */
Georg Brandlf038b322010-10-18 07:35:09 +00001163 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 0, /* tp_call */
1165 0, /* tp_str */
1166 PyObject_GenericGetAttr, /* tp_getattro */
1167 0, /* tp_setattro */
1168 0, /* tp_as_buffer */
1169 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
Georg Brandlf038b322010-10-18 07:35:09 +00001170 /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001171 deque_doc, /* tp_doc */
1172 (traverseproc)deque_traverse, /* tp_traverse */
1173 (inquiry)deque_clear, /* tp_clear */
1174 (richcmpfunc)deque_richcompare, /* tp_richcompare */
Georg Brandlf038b322010-10-18 07:35:09 +00001175 offsetof(dequeobject, weakreflist), /* tp_weaklistoffset*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001176 (getiterfunc)deque_iter, /* tp_iter */
1177 0, /* tp_iternext */
1178 deque_methods, /* tp_methods */
1179 0, /* tp_members */
Georg Brandlf038b322010-10-18 07:35:09 +00001180 deque_getset, /* tp_getset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001181 0, /* tp_base */
1182 0, /* tp_dict */
1183 0, /* tp_descr_get */
1184 0, /* tp_descr_set */
1185 0, /* tp_dictoffset */
1186 (initproc)deque_init, /* tp_init */
1187 PyType_GenericAlloc, /* tp_alloc */
1188 deque_new, /* tp_new */
1189 PyObject_GC_Del, /* tp_free */
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001190};
1191
1192/*********************** Deque Iterator **************************/
1193
1194typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001195 PyObject_HEAD
1196 Py_ssize_t index;
1197 block *b;
1198 dequeobject *deque;
1199 long state; /* state when the iterator is created */
1200 Py_ssize_t counter; /* number of items remaining for iteration */
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001201} dequeiterobject;
1202
Martin v. Löwis59683e82008-06-13 07:50:45 +00001203static PyTypeObject dequeiter_type;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001204
1205static PyObject *
1206deque_iter(dequeobject *deque)
1207{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001208 dequeiterobject *it;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001209
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001210 it = PyObject_GC_New(dequeiterobject, &dequeiter_type);
1211 if (it == NULL)
1212 return NULL;
1213 it->b = deque->leftblock;
1214 it->index = deque->leftindex;
1215 Py_INCREF(deque);
1216 it->deque = deque;
1217 it->state = deque->state;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001218 it->counter = Py_SIZE(deque);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001219 PyObject_GC_Track(it);
1220 return (PyObject *)it;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001221}
1222
Antoine Pitrou7ddda782009-01-01 15:35:33 +00001223static int
1224dequeiter_traverse(dequeiterobject *dio, visitproc visit, void *arg)
1225{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001226 Py_VISIT(dio->deque);
1227 return 0;
Antoine Pitrou7ddda782009-01-01 15:35:33 +00001228}
1229
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001230static void
1231dequeiter_dealloc(dequeiterobject *dio)
1232{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001233 Py_XDECREF(dio->deque);
1234 PyObject_GC_Del(dio);
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001235}
1236
1237static PyObject *
1238dequeiter_next(dequeiterobject *it)
1239{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001240 PyObject *item;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +00001241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001242 if (it->deque->state != it->state) {
1243 it->counter = 0;
1244 PyErr_SetString(PyExc_RuntimeError,
1245 "deque mutated during iteration");
1246 return NULL;
1247 }
1248 if (it->counter == 0)
1249 return NULL;
1250 assert (!(it->b == it->deque->rightblock &&
1251 it->index > it->deque->rightindex));
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 item = it->b->data[it->index];
1254 it->index++;
1255 it->counter--;
1256 if (it->index == BLOCKLEN && it->counter > 0) {
Raymond Hettinger82df9252013-07-07 01:43:42 -10001257 CHECK_NOT_END(it->b->rightlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001258 it->b = it->b->rightlink;
1259 it->index = 0;
1260 }
1261 Py_INCREF(item);
1262 return item;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001263}
1264
Raymond Hettinger6b27cda2005-09-24 21:23:05 +00001265static PyObject *
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001266dequeiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1267{
1268 Py_ssize_t i, index=0;
1269 PyObject *deque;
1270 dequeiterobject *it;
1271 if (!PyArg_ParseTuple(args, "O!|n", &deque_type, &deque, &index))
1272 return NULL;
1273 assert(type == &dequeiter_type);
1274
1275 it = (dequeiterobject*)deque_iter((dequeobject *)deque);
1276 if (!it)
1277 return NULL;
1278 /* consume items from the queue */
1279 for(i=0; i<index; i++) {
1280 PyObject *item = dequeiter_next(it);
1281 if (item) {
1282 Py_DECREF(item);
1283 } else {
1284 if (it->counter) {
1285 Py_DECREF(it);
1286 return NULL;
1287 } else
1288 break;
1289 }
1290 }
1291 return (PyObject*)it;
1292}
1293
1294static PyObject *
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001295dequeiter_len(dequeiterobject *it)
1296{
Antoine Pitrou554f3342010-08-17 18:30:06 +00001297 return PyLong_FromSsize_t(it->counter);
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001298}
1299
Armin Rigof5b3e362006-02-11 21:32:43 +00001300PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +00001301
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001302static PyObject *
1303dequeiter_reduce(dequeiterobject *it)
1304{
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001305 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 +00001306}
1307
Raymond Hettinger6b27cda2005-09-24 21:23:05 +00001308static PyMethodDef dequeiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001309 {"__length_hint__", (PyCFunction)dequeiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001310 {"__reduce__", (PyCFunction)dequeiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001311 {NULL, NULL} /* sentinel */
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001312};
1313
Martin v. Löwis59683e82008-06-13 07:50:45 +00001314static PyTypeObject dequeiter_type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001315 PyVarObject_HEAD_INIT(NULL, 0)
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001316 "_collections._deque_iterator", /* tp_name */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001317 sizeof(dequeiterobject), /* tp_basicsize */
1318 0, /* tp_itemsize */
1319 /* methods */
1320 (destructor)dequeiter_dealloc, /* tp_dealloc */
1321 0, /* tp_print */
1322 0, /* tp_getattr */
1323 0, /* tp_setattr */
1324 0, /* tp_reserved */
1325 0, /* tp_repr */
1326 0, /* tp_as_number */
1327 0, /* tp_as_sequence */
1328 0, /* tp_as_mapping */
1329 0, /* tp_hash */
1330 0, /* tp_call */
1331 0, /* tp_str */
1332 PyObject_GenericGetAttr, /* tp_getattro */
1333 0, /* tp_setattro */
1334 0, /* tp_as_buffer */
1335 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
1336 0, /* tp_doc */
1337 (traverseproc)dequeiter_traverse, /* tp_traverse */
1338 0, /* tp_clear */
1339 0, /* tp_richcompare */
1340 0, /* tp_weaklistoffset */
1341 PyObject_SelfIter, /* tp_iter */
1342 (iternextfunc)dequeiter_next, /* tp_iternext */
1343 dequeiter_methods, /* tp_methods */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001344 0, /* tp_members */
1345 0, /* tp_getset */
1346 0, /* tp_base */
1347 0, /* tp_dict */
1348 0, /* tp_descr_get */
1349 0, /* tp_descr_set */
1350 0, /* tp_dictoffset */
1351 0, /* tp_init */
1352 0, /* tp_alloc */
1353 dequeiter_new, /* tp_new */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001354 0,
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001355};
1356
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001357/*********************** Deque Reverse Iterator **************************/
1358
Martin v. Löwis59683e82008-06-13 07:50:45 +00001359static PyTypeObject dequereviter_type;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001360
1361static PyObject *
1362deque_reviter(dequeobject *deque)
1363{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001364 dequeiterobject *it;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001366 it = PyObject_GC_New(dequeiterobject, &dequereviter_type);
1367 if (it == NULL)
1368 return NULL;
1369 it->b = deque->rightblock;
1370 it->index = deque->rightindex;
1371 Py_INCREF(deque);
1372 it->deque = deque;
1373 it->state = deque->state;
Raymond Hettingerdf715ba2013-07-06 13:01:13 -10001374 it->counter = Py_SIZE(deque);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 PyObject_GC_Track(it);
1376 return (PyObject *)it;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001377}
1378
1379static PyObject *
1380dequereviter_next(dequeiterobject *it)
1381{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001382 PyObject *item;
1383 if (it->counter == 0)
1384 return NULL;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 if (it->deque->state != it->state) {
1387 it->counter = 0;
1388 PyErr_SetString(PyExc_RuntimeError,
1389 "deque mutated during iteration");
1390 return NULL;
1391 }
1392 assert (!(it->b == it->deque->leftblock &&
1393 it->index < it->deque->leftindex));
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001394
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001395 item = it->b->data[it->index];
1396 it->index--;
1397 it->counter--;
1398 if (it->index == -1 && it->counter > 0) {
Raymond Hettinger82df9252013-07-07 01:43:42 -10001399 CHECK_NOT_END(it->b->leftlink);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001400 it->b = it->b->leftlink;
1401 it->index = BLOCKLEN - 1;
1402 }
1403 Py_INCREF(item);
1404 return item;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001405}
1406
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001407static PyObject *
1408dequereviter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1409{
1410 Py_ssize_t i, index=0;
1411 PyObject *deque;
1412 dequeiterobject *it;
1413 if (!PyArg_ParseTuple(args, "O!|n", &deque_type, &deque, &index))
1414 return NULL;
1415 assert(type == &dequereviter_type);
1416
1417 it = (dequeiterobject*)deque_reviter((dequeobject *)deque);
1418 if (!it)
1419 return NULL;
1420 /* consume items from the queue */
1421 for(i=0; i<index; i++) {
1422 PyObject *item = dequereviter_next(it);
1423 if (item) {
1424 Py_DECREF(item);
1425 } else {
1426 if (it->counter) {
1427 Py_DECREF(it);
1428 return NULL;
1429 } else
1430 break;
1431 }
1432 }
1433 return (PyObject*)it;
1434}
1435
Martin v. Löwis59683e82008-06-13 07:50:45 +00001436static PyTypeObject dequereviter_type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001437 PyVarObject_HEAD_INIT(NULL, 0)
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001438 "_collections._deque_reverse_iterator", /* tp_name */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001439 sizeof(dequeiterobject), /* tp_basicsize */
1440 0, /* tp_itemsize */
1441 /* methods */
1442 (destructor)dequeiter_dealloc, /* tp_dealloc */
1443 0, /* tp_print */
1444 0, /* tp_getattr */
1445 0, /* tp_setattr */
1446 0, /* tp_reserved */
1447 0, /* tp_repr */
1448 0, /* tp_as_number */
1449 0, /* tp_as_sequence */
1450 0, /* tp_as_mapping */
1451 0, /* tp_hash */
1452 0, /* tp_call */
1453 0, /* tp_str */
1454 PyObject_GenericGetAttr, /* tp_getattro */
1455 0, /* tp_setattro */
1456 0, /* tp_as_buffer */
1457 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
1458 0, /* tp_doc */
1459 (traverseproc)dequeiter_traverse, /* tp_traverse */
1460 0, /* tp_clear */
1461 0, /* tp_richcompare */
1462 0, /* tp_weaklistoffset */
1463 PyObject_SelfIter, /* tp_iter */
1464 (iternextfunc)dequereviter_next, /* tp_iternext */
1465 dequeiter_methods, /* tp_methods */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001466 0, /* tp_members */
1467 0, /* tp_getset */
1468 0, /* tp_base */
1469 0, /* tp_dict */
1470 0, /* tp_descr_get */
1471 0, /* tp_descr_set */
1472 0, /* tp_dictoffset */
1473 0, /* tp_init */
1474 0, /* tp_alloc */
1475 dequereviter_new, /* tp_new */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001476 0,
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001477};
1478
Guido van Rossum1968ad32006-02-25 22:38:04 +00001479/* defaultdict type *********************************************************/
1480
1481typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001482 PyDictObject dict;
1483 PyObject *default_factory;
Guido van Rossum1968ad32006-02-25 22:38:04 +00001484} defdictobject;
1485
1486static PyTypeObject defdict_type; /* Forward */
1487
1488PyDoc_STRVAR(defdict_missing_doc,
1489"__missing__(key) # Called by __getitem__ for missing key; pseudo-code:\n\
Guido van Rossumd8faa362007-04-27 19:54:29 +00001490 if self.default_factory is None: raise KeyError((key,))\n\
Guido van Rossum1968ad32006-02-25 22:38:04 +00001491 self[key] = value = self.default_factory()\n\
1492 return value\n\
1493");
1494
1495static PyObject *
1496defdict_missing(defdictobject *dd, PyObject *key)
1497{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001498 PyObject *factory = dd->default_factory;
1499 PyObject *value;
1500 if (factory == NULL || factory == Py_None) {
1501 /* XXX Call dict.__missing__(key) */
1502 PyObject *tup;
1503 tup = PyTuple_Pack(1, key);
1504 if (!tup) return NULL;
1505 PyErr_SetObject(PyExc_KeyError, tup);
1506 Py_DECREF(tup);
1507 return NULL;
1508 }
1509 value = PyEval_CallObject(factory, NULL);
1510 if (value == NULL)
1511 return value;
1512 if (PyObject_SetItem((PyObject *)dd, key, value) < 0) {
1513 Py_DECREF(value);
1514 return NULL;
1515 }
1516 return value;
Guido van Rossum1968ad32006-02-25 22:38:04 +00001517}
1518
1519PyDoc_STRVAR(defdict_copy_doc, "D.copy() -> a shallow copy of D.");
1520
1521static PyObject *
1522defdict_copy(defdictobject *dd)
1523{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 /* This calls the object's class. That only works for subclasses
1525 whose class constructor has the same signature. Subclasses that
1526 define a different constructor signature must override copy().
1527 */
Raymond Hettinger54628fa2009-08-04 19:16:39 +00001528
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001529 if (dd->default_factory == NULL)
1530 return PyObject_CallFunctionObjArgs((PyObject*)Py_TYPE(dd), Py_None, dd, NULL);
1531 return PyObject_CallFunctionObjArgs((PyObject*)Py_TYPE(dd),
1532 dd->default_factory, dd, NULL);
Guido van Rossum1968ad32006-02-25 22:38:04 +00001533}
1534
1535static PyObject *
1536defdict_reduce(defdictobject *dd)
1537{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001538 /* __reduce__ must return a 5-tuple as follows:
Guido van Rossum1968ad32006-02-25 22:38:04 +00001539
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001540 - factory function
1541 - tuple of args for the factory function
1542 - additional state (here None)
1543 - sequence iterator (here None)
1544 - dictionary iterator (yielding successive (key, value) pairs
Guido van Rossum1968ad32006-02-25 22:38:04 +00001545
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001546 This API is used by pickle.py and copy.py.
Guido van Rossum1968ad32006-02-25 22:38:04 +00001547
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001548 For this to be useful with pickle.py, the default_factory
1549 must be picklable; e.g., None, a built-in, or a global
1550 function in a module or package.
Guido van Rossum1968ad32006-02-25 22:38:04 +00001551
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001552 Both shallow and deep copying are supported, but for deep
1553 copying, the default_factory must be deep-copyable; e.g. None,
1554 or a built-in (functions are not copyable at this time).
Guido van Rossum1968ad32006-02-25 22:38:04 +00001555
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001556 This only works for subclasses as long as their constructor
1557 signature is compatible; the first argument must be the
1558 optional default_factory, defaulting to None.
1559 */
1560 PyObject *args;
1561 PyObject *items;
1562 PyObject *iter;
1563 PyObject *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001564 _Py_IDENTIFIER(items);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001565
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001566 if (dd->default_factory == NULL || dd->default_factory == Py_None)
1567 args = PyTuple_New(0);
1568 else
1569 args = PyTuple_Pack(1, dd->default_factory);
1570 if (args == NULL)
1571 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001572 items = _PyObject_CallMethodId((PyObject *)dd, &PyId_items, "()");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001573 if (items == NULL) {
1574 Py_DECREF(args);
1575 return NULL;
1576 }
1577 iter = PyObject_GetIter(items);
1578 if (iter == NULL) {
1579 Py_DECREF(items);
1580 Py_DECREF(args);
1581 return NULL;
1582 }
1583 result = PyTuple_Pack(5, Py_TYPE(dd), args,
1584 Py_None, Py_None, iter);
1585 Py_DECREF(iter);
1586 Py_DECREF(items);
1587 Py_DECREF(args);
1588 return result;
Guido van Rossum1968ad32006-02-25 22:38:04 +00001589}
1590
1591static PyMethodDef defdict_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001592 {"__missing__", (PyCFunction)defdict_missing, METH_O,
1593 defdict_missing_doc},
1594 {"copy", (PyCFunction)defdict_copy, METH_NOARGS,
1595 defdict_copy_doc},
1596 {"__copy__", (PyCFunction)defdict_copy, METH_NOARGS,
1597 defdict_copy_doc},
1598 {"__reduce__", (PyCFunction)defdict_reduce, METH_NOARGS,
1599 reduce_doc},
1600 {NULL}
Guido van Rossum1968ad32006-02-25 22:38:04 +00001601};
1602
1603static PyMemberDef defdict_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001604 {"default_factory", T_OBJECT,
1605 offsetof(defdictobject, default_factory), 0,
1606 PyDoc_STR("Factory for default value called by __missing__().")},
1607 {NULL}
Guido van Rossum1968ad32006-02-25 22:38:04 +00001608};
1609
1610static void
1611defdict_dealloc(defdictobject *dd)
1612{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 Py_CLEAR(dd->default_factory);
1614 PyDict_Type.tp_dealloc((PyObject *)dd);
Guido van Rossum1968ad32006-02-25 22:38:04 +00001615}
1616
Guido van Rossum1968ad32006-02-25 22:38:04 +00001617static PyObject *
1618defdict_repr(defdictobject *dd)
1619{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 PyObject *baserepr;
1621 PyObject *defrepr;
1622 PyObject *result;
1623 baserepr = PyDict_Type.tp_repr((PyObject *)dd);
1624 if (baserepr == NULL)
1625 return NULL;
1626 if (dd->default_factory == NULL)
1627 defrepr = PyUnicode_FromString("None");
1628 else
1629 {
1630 int status = Py_ReprEnter(dd->default_factory);
1631 if (status != 0) {
Antoine Pitrouf5f1fe02012-02-15 02:42:46 +01001632 if (status < 0) {
1633 Py_DECREF(baserepr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001634 return NULL;
Antoine Pitrouf5f1fe02012-02-15 02:42:46 +01001635 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001636 defrepr = PyUnicode_FromString("...");
1637 }
1638 else
1639 defrepr = PyObject_Repr(dd->default_factory);
1640 Py_ReprLeave(dd->default_factory);
1641 }
1642 if (defrepr == NULL) {
1643 Py_DECREF(baserepr);
1644 return NULL;
1645 }
1646 result = PyUnicode_FromFormat("defaultdict(%U, %U)",
1647 defrepr, baserepr);
1648 Py_DECREF(defrepr);
1649 Py_DECREF(baserepr);
1650 return result;
Guido van Rossum1968ad32006-02-25 22:38:04 +00001651}
1652
1653static int
1654defdict_traverse(PyObject *self, visitproc visit, void *arg)
1655{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001656 Py_VISIT(((defdictobject *)self)->default_factory);
1657 return PyDict_Type.tp_traverse(self, visit, arg);
Guido van Rossum1968ad32006-02-25 22:38:04 +00001658}
1659
1660static int
1661defdict_tp_clear(defdictobject *dd)
1662{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001663 Py_CLEAR(dd->default_factory);
1664 return PyDict_Type.tp_clear((PyObject *)dd);
Guido van Rossum1968ad32006-02-25 22:38:04 +00001665}
1666
1667static int
1668defdict_init(PyObject *self, PyObject *args, PyObject *kwds)
1669{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001670 defdictobject *dd = (defdictobject *)self;
1671 PyObject *olddefault = dd->default_factory;
1672 PyObject *newdefault = NULL;
1673 PyObject *newargs;
1674 int result;
1675 if (args == NULL || !PyTuple_Check(args))
1676 newargs = PyTuple_New(0);
1677 else {
1678 Py_ssize_t n = PyTuple_GET_SIZE(args);
1679 if (n > 0) {
1680 newdefault = PyTuple_GET_ITEM(args, 0);
1681 if (!PyCallable_Check(newdefault) && newdefault != Py_None) {
1682 PyErr_SetString(PyExc_TypeError,
Raymond Hettinger239aba72015-07-20 03:09:22 -04001683 "first argument must be callable or None");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001684 return -1;
1685 }
1686 }
1687 newargs = PySequence_GetSlice(args, 1, n);
1688 }
1689 if (newargs == NULL)
1690 return -1;
1691 Py_XINCREF(newdefault);
1692 dd->default_factory = newdefault;
1693 result = PyDict_Type.tp_init(self, newargs, kwds);
1694 Py_DECREF(newargs);
1695 Py_XDECREF(olddefault);
1696 return result;
Guido van Rossum1968ad32006-02-25 22:38:04 +00001697}
1698
1699PyDoc_STRVAR(defdict_doc,
Benjamin Peterson9cb33b72014-01-13 23:56:05 -05001700"defaultdict(default_factory[, ...]) --> dict with default factory\n\
Guido van Rossum1968ad32006-02-25 22:38:04 +00001701\n\
1702The default factory is called without arguments to produce\n\
1703a new value when a key is not present, in __getitem__ only.\n\
1704A defaultdict compares equal to a dict with the same items.\n\
Benjamin Peterson9cb33b72014-01-13 23:56:05 -05001705All remaining arguments are treated the same as if they were\n\
1706passed to the dict constructor, including keyword arguments.\n\
Guido van Rossum1968ad32006-02-25 22:38:04 +00001707");
1708
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001709/* See comment in xxsubtype.c */
1710#define DEFERRED_ADDRESS(ADDR) 0
1711
Guido van Rossum1968ad32006-02-25 22:38:04 +00001712static PyTypeObject defdict_type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001713 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
1714 "collections.defaultdict", /* tp_name */
1715 sizeof(defdictobject), /* tp_basicsize */
1716 0, /* tp_itemsize */
1717 /* methods */
1718 (destructor)defdict_dealloc, /* tp_dealloc */
1719 0, /* tp_print */
1720 0, /* tp_getattr */
1721 0, /* tp_setattr */
1722 0, /* tp_reserved */
1723 (reprfunc)defdict_repr, /* tp_repr */
1724 0, /* tp_as_number */
1725 0, /* tp_as_sequence */
1726 0, /* tp_as_mapping */
1727 0, /* tp_hash */
1728 0, /* tp_call */
1729 0, /* tp_str */
1730 PyObject_GenericGetAttr, /* tp_getattro */
1731 0, /* tp_setattro */
1732 0, /* tp_as_buffer */
1733 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
1734 /* tp_flags */
1735 defdict_doc, /* tp_doc */
1736 defdict_traverse, /* tp_traverse */
1737 (inquiry)defdict_tp_clear, /* tp_clear */
1738 0, /* tp_richcompare */
1739 0, /* tp_weaklistoffset*/
1740 0, /* tp_iter */
1741 0, /* tp_iternext */
1742 defdict_methods, /* tp_methods */
1743 defdict_members, /* tp_members */
1744 0, /* tp_getset */
1745 DEFERRED_ADDRESS(&PyDict_Type), /* tp_base */
1746 0, /* tp_dict */
1747 0, /* tp_descr_get */
1748 0, /* tp_descr_set */
1749 0, /* tp_dictoffset */
1750 defdict_init, /* tp_init */
1751 PyType_GenericAlloc, /* tp_alloc */
1752 0, /* tp_new */
1753 PyObject_GC_Del, /* tp_free */
Guido van Rossum1968ad32006-02-25 22:38:04 +00001754};
1755
Raymond Hettinger96f34102010-12-15 16:30:37 +00001756/* helper function for Counter *********************************************/
1757
1758PyDoc_STRVAR(_count_elements_doc,
1759"_count_elements(mapping, iterable) -> None\n\
1760\n\
1761Count elements in the iterable, updating the mappping");
1762
1763static PyObject *
1764_count_elements(PyObject *self, PyObject *args)
1765{
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001766 _Py_IDENTIFIER(get);
Raymond Hettinger2ff21902013-10-01 00:55:43 -07001767 _Py_IDENTIFIER(__setitem__);
Raymond Hettinger96f34102010-12-15 16:30:37 +00001768 PyObject *it, *iterable, *mapping, *oldval;
1769 PyObject *newval = NULL;
1770 PyObject *key = NULL;
Raymond Hettinger224c87d2013-10-01 21:36:09 -07001771 PyObject *zero = NULL;
Raymond Hettinger96f34102010-12-15 16:30:37 +00001772 PyObject *one = NULL;
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001773 PyObject *bound_get = NULL;
1774 PyObject *mapping_get;
1775 PyObject *dict_get;
Raymond Hettinger2ff21902013-10-01 00:55:43 -07001776 PyObject *mapping_setitem;
Raymond Hettinger2ff21902013-10-01 00:55:43 -07001777 PyObject *dict_setitem;
Raymond Hettinger96f34102010-12-15 16:30:37 +00001778
1779 if (!PyArg_UnpackTuple(args, "_count_elements", 2, 2, &mapping, &iterable))
1780 return NULL;
1781
Raymond Hettinger96f34102010-12-15 16:30:37 +00001782 it = PyObject_GetIter(iterable);
1783 if (it == NULL)
1784 return NULL;
Raymond Hettinger426e0522011-01-03 02:12:02 +00001785
Raymond Hettinger96f34102010-12-15 16:30:37 +00001786 one = PyLong_FromLong(1);
Raymond Hettinger224c87d2013-10-01 21:36:09 -07001787 if (one == NULL)
1788 goto done;
Raymond Hettinger426e0522011-01-03 02:12:02 +00001789
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001790 /* Only take the fast path when get() and __setitem__()
1791 * have not been overridden.
1792 */
1793 mapping_get = _PyType_LookupId(Py_TYPE(mapping), &PyId_get);
1794 dict_get = _PyType_LookupId(&PyDict_Type, &PyId_get);
Raymond Hettinger2ff21902013-10-01 00:55:43 -07001795 mapping_setitem = _PyType_LookupId(Py_TYPE(mapping), &PyId___setitem__);
1796 dict_setitem = _PyType_LookupId(&PyDict_Type, &PyId___setitem__);
1797
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001798 if (mapping_get != NULL && mapping_get == dict_get &&
1799 mapping_setitem != NULL && mapping_setitem == dict_setitem) {
Raymond Hettinger426e0522011-01-03 02:12:02 +00001800 while (1) {
1801 key = PyIter_Next(it);
Victor Stinnera154b5c2011-04-20 23:23:52 +02001802 if (key == NULL)
1803 break;
Raymond Hettinger426e0522011-01-03 02:12:02 +00001804 oldval = PyDict_GetItem(mapping, key);
1805 if (oldval == NULL) {
1806 if (PyDict_SetItem(mapping, key, one) == -1)
1807 break;
1808 } else {
1809 newval = PyNumber_Add(oldval, one);
1810 if (newval == NULL)
1811 break;
1812 if (PyDict_SetItem(mapping, key, newval) == -1)
1813 break;
1814 Py_CLEAR(newval);
1815 }
1816 Py_DECREF(key);
Raymond Hettinger96f34102010-12-15 16:30:37 +00001817 }
Raymond Hettinger426e0522011-01-03 02:12:02 +00001818 } else {
Victor Stinnere7f516c2013-11-06 23:52:55 +01001819 bound_get = _PyObject_GetAttrId(mapping, &PyId_get);
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001820 if (bound_get == NULL)
Raymond Hettinger224c87d2013-10-01 21:36:09 -07001821 goto done;
1822
1823 zero = PyLong_FromLong(0);
1824 if (zero == NULL)
1825 goto done;
1826
Raymond Hettinger426e0522011-01-03 02:12:02 +00001827 while (1) {
1828 key = PyIter_Next(it);
Victor Stinnera154b5c2011-04-20 23:23:52 +02001829 if (key == NULL)
1830 break;
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001831 oldval = PyObject_CallFunctionObjArgs(bound_get, key, zero, NULL);
Raymond Hettinger224c87d2013-10-01 21:36:09 -07001832 if (oldval == NULL)
1833 break;
1834 newval = PyNumber_Add(oldval, one);
1835 Py_DECREF(oldval);
1836 if (newval == NULL)
1837 break;
Raymond Hettinger426e0522011-01-03 02:12:02 +00001838 if (PyObject_SetItem(mapping, key, newval) == -1)
Raymond Hettinger96f34102010-12-15 16:30:37 +00001839 break;
1840 Py_CLEAR(newval);
Raymond Hettinger426e0522011-01-03 02:12:02 +00001841 Py_DECREF(key);
Raymond Hettinger96f34102010-12-15 16:30:37 +00001842 }
Raymond Hettinger96f34102010-12-15 16:30:37 +00001843 }
Raymond Hettinger426e0522011-01-03 02:12:02 +00001844
Raymond Hettinger224c87d2013-10-01 21:36:09 -07001845done:
Raymond Hettinger96f34102010-12-15 16:30:37 +00001846 Py_DECREF(it);
1847 Py_XDECREF(key);
1848 Py_XDECREF(newval);
Raymond Hettingercb1d96f2013-10-04 16:51:02 -07001849 Py_XDECREF(bound_get);
Raymond Hettinger224c87d2013-10-01 21:36:09 -07001850 Py_XDECREF(zero);
1851 Py_XDECREF(one);
Raymond Hettinger96f34102010-12-15 16:30:37 +00001852 if (PyErr_Occurred())
1853 return NULL;
1854 Py_RETURN_NONE;
1855}
1856
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001857/* module level code ********************************************************/
1858
1859PyDoc_STRVAR(module_doc,
Guido van Rossum1968ad32006-02-25 22:38:04 +00001860"High performance data structures.\n\
1861- deque: ordered collection accessible from endpoints only\n\
1862- defaultdict: dict subclass with a default value factory\n\
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001863");
1864
Raymond Hettinger96f34102010-12-15 16:30:37 +00001865static struct PyMethodDef module_functions[] = {
1866 {"_count_elements", _count_elements, METH_VARARGS, _count_elements_doc},
1867 {NULL, NULL} /* sentinel */
1868};
Martin v. Löwis1a214512008-06-11 05:26:20 +00001869
1870static struct PyModuleDef _collectionsmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001871 PyModuleDef_HEAD_INIT,
1872 "_collections",
1873 module_doc,
1874 -1,
Raymond Hettinger96f34102010-12-15 16:30:37 +00001875 module_functions,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876 NULL,
1877 NULL,
1878 NULL,
1879 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001880};
1881
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001882PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001883PyInit__collections(void)
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001884{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 PyObject *m;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001886
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 m = PyModule_Create(&_collectionsmodule);
1888 if (m == NULL)
1889 return NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001891 if (PyType_Ready(&deque_type) < 0)
1892 return NULL;
1893 Py_INCREF(&deque_type);
1894 PyModule_AddObject(m, "deque", (PyObject *)&deque_type);
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001895
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 defdict_type.tp_base = &PyDict_Type;
1897 if (PyType_Ready(&defdict_type) < 0)
1898 return NULL;
1899 Py_INCREF(&defdict_type);
1900 PyModule_AddObject(m, "defaultdict", (PyObject *)&defdict_type);
Guido van Rossum1968ad32006-02-25 22:38:04 +00001901
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001902 if (PyType_Ready(&dequeiter_type) < 0)
1903 return NULL;
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001904 Py_INCREF(&dequeiter_type);
1905 PyModule_AddObject(m, "_deque_iterator", (PyObject *)&dequeiter_type);
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001906
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001907 if (PyType_Ready(&dequereviter_type) < 0)
1908 return NULL;
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +00001909 Py_INCREF(&dequereviter_type);
1910 PyModule_AddObject(m, "_deque_reverse_iterator", (PyObject *)&dequereviter_type);
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001911
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001912 return m;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001913}