blob: 10b08f941f9dd3873c268e415c455e148ec8d7e3 [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>
6 Copyright (c) 2004 Python Software Foundation.
7 All rights reserved.
8*/
9
Raymond Hettinger77e8bf12004-10-01 15:25:53 +000010/* The block length may be set to any number over 1. Larger numbers
11 * reduce the number of calls to the memory allocator but take more
12 * memory. Ideally, BLOCKLEN should be set with an eye to the
13 * length of a cache line.
14 */
15
Raymond Hettinger7d112df2004-11-02 02:11:35 +000016#define BLOCKLEN 62
Raymond Hettinger61f05fb2004-10-01 06:24:12 +000017#define CENTER ((BLOCKLEN - 1) / 2)
Raymond Hettinger756b3f32004-01-29 06:37:52 +000018
Tim Petersd8768d32004-10-01 01:32:53 +000019/* A `dequeobject` is composed of a doubly-linked list of `block` nodes.
20 * This list is not circular (the leftmost block has leftlink==NULL,
21 * and the rightmost block has rightlink==NULL). A deque d's first
22 * element is at d.leftblock[leftindex] and its last element is at
23 * d.rightblock[rightindex]; note that, unlike as for Python slice
Raymond Hettinger61f05fb2004-10-01 06:24:12 +000024 * indices, these indices are inclusive on both ends. By being inclusive
25 * on both ends, algorithms for left and right operations become
26 * symmetrical which simplifies the design.
27 *
28 * The list of blocks is never empty, so d.leftblock and d.rightblock
29 * are never equal to NULL.
30 *
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 *
40 * Whenever d.leftblock == d.rightblock,
Raymond Hettinger4ca4c7c2004-10-01 15:14:39 +000041 * d.leftindex + d.len - 1 == d.rightindex.
Raymond Hettinger61f05fb2004-10-01 06:24:12 +000042 *
Raymond Hettinger4ca4c7c2004-10-01 15:14:39 +000043 * However, when d.leftblock != d.rightblock, d.leftindex and d.rightindex
44 * become indices into distinct blocks and either may be larger than the
45 * other.
Tim Petersd8768d32004-10-01 01:32:53 +000046 */
47
Raymond Hettinger756b3f32004-01-29 06:37:52 +000048typedef struct BLOCK {
49 struct BLOCK *leftlink;
50 struct BLOCK *rightlink;
51 PyObject *data[BLOCKLEN];
52} block;
53
Tim Peters6f853562004-10-01 01:04:50 +000054static block *
Raymond Hettingerc5fa9922004-10-06 17:51:54 +000055newblock(block *leftlink, block *rightlink, int len) {
56 block *b;
57 /* To prevent len from overflowing INT_MAX on 64-bit machines, we
58 * refuse to allocate new blocks if the current len is dangerously
59 * close. There is some extra margin to prevent spurious arithmetic
60 * overflows at various places. The following check ensures that
61 * the blocks allocated to the deque, in the worst case, can only
62 * have INT_MAX-2 entries in total.
63 */
64 if (len >= INT_MAX - 2*BLOCKLEN) {
65 PyErr_SetString(PyExc_OverflowError,
66 "cannot add more blocks to the deque");
67 return NULL;
68 }
69 b = PyMem_Malloc(sizeof(block));
Raymond Hettinger756b3f32004-01-29 06:37:52 +000070 if (b == NULL) {
71 PyErr_NoMemory();
72 return NULL;
73 }
74 b->leftlink = leftlink;
75 b->rightlink = rightlink;
76 return b;
77}
78
79typedef struct {
80 PyObject_HEAD
81 block *leftblock;
82 block *rightblock;
Tim Petersd8768d32004-10-01 01:32:53 +000083 int leftindex; /* in range(BLOCKLEN) */
84 int rightindex; /* in range(BLOCKLEN) */
Raymond Hettinger756b3f32004-01-29 06:37:52 +000085 int len;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +000086 long state; /* incremented whenever the indices move */
Raymond Hettinger691d8052004-05-30 07:26:47 +000087 PyObject *weakreflist; /* List of weak references */
Raymond Hettinger756b3f32004-01-29 06:37:52 +000088} dequeobject;
89
Neal Norwitz87f10132004-02-29 15:40:53 +000090static PyTypeObject deque_type;
Raymond Hettinger738ec902004-02-29 02:15:56 +000091
Raymond Hettinger756b3f32004-01-29 06:37:52 +000092static PyObject *
93deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
94{
95 dequeobject *deque;
96 block *b;
97
98 /* create dequeobject structure */
99 deque = (dequeobject *)type->tp_alloc(type, 0);
100 if (deque == NULL)
101 return NULL;
Tim Peters1065f752004-10-01 01:03:29 +0000102
Raymond Hettingerc5fa9922004-10-06 17:51:54 +0000103 b = newblock(NULL, NULL, 0);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000104 if (b == NULL) {
105 Py_DECREF(deque);
106 return NULL;
107 }
108
Raymond Hettinger61f05fb2004-10-01 06:24:12 +0000109 assert(BLOCKLEN >= 2);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000110 deque->leftblock = b;
111 deque->rightblock = b;
Raymond Hettinger61f05fb2004-10-01 06:24:12 +0000112 deque->leftindex = CENTER + 1;
113 deque->rightindex = CENTER;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000114 deque->len = 0;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000115 deque->state = 0;
Raymond Hettinger691d8052004-05-30 07:26:47 +0000116 deque->weakreflist = NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000117
118 return (PyObject *)deque;
119}
120
121static PyObject *
122deque_append(dequeobject *deque, PyObject *item)
123{
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000124 deque->state++;
Armin Rigo974d7572004-10-02 13:59:34 +0000125 if (deque->rightindex == BLOCKLEN-1) {
Raymond Hettingerc5fa9922004-10-06 17:51:54 +0000126 block *b = newblock(deque->rightblock, NULL, deque->len);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000127 if (b == NULL)
128 return NULL;
129 assert(deque->rightblock->rightlink == NULL);
130 deque->rightblock->rightlink = b;
131 deque->rightblock = b;
Armin Rigo974d7572004-10-02 13:59:34 +0000132 deque->rightindex = -1;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000133 }
134 Py_INCREF(item);
Armin Rigo974d7572004-10-02 13:59:34 +0000135 deque->len++;
136 deque->rightindex++;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000137 deque->rightblock->data[deque->rightindex] = item;
138 Py_RETURN_NONE;
139}
140
141PyDoc_STRVAR(append_doc, "Add an element to the right side of the deque.");
142
143static PyObject *
144deque_appendleft(dequeobject *deque, PyObject *item)
145{
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000146 deque->state++;
Armin Rigo974d7572004-10-02 13:59:34 +0000147 if (deque->leftindex == 0) {
Raymond Hettingerc5fa9922004-10-06 17:51:54 +0000148 block *b = newblock(NULL, deque->leftblock, deque->len);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000149 if (b == NULL)
150 return NULL;
151 assert(deque->leftblock->leftlink == NULL);
152 deque->leftblock->leftlink = b;
153 deque->leftblock = b;
Armin Rigo974d7572004-10-02 13:59:34 +0000154 deque->leftindex = BLOCKLEN;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000155 }
156 Py_INCREF(item);
Armin Rigo974d7572004-10-02 13:59:34 +0000157 deque->len++;
158 deque->leftindex--;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000159 deque->leftblock->data[deque->leftindex] = item;
160 Py_RETURN_NONE;
161}
162
163PyDoc_STRVAR(appendleft_doc, "Add an element to the left side of the deque.");
164
165static PyObject *
166deque_pop(dequeobject *deque, PyObject *unused)
167{
168 PyObject *item;
169 block *prevblock;
170
171 if (deque->len == 0) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000172 PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000173 return NULL;
174 }
175 item = deque->rightblock->data[deque->rightindex];
176 deque->rightindex--;
177 deque->len--;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000178 deque->state++;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000179
180 if (deque->rightindex == -1) {
181 if (deque->len == 0) {
182 assert(deque->leftblock == deque->rightblock);
183 assert(deque->leftindex == deque->rightindex+1);
184 /* re-center instead of freeing a block */
Raymond Hettinger61f05fb2004-10-01 06:24:12 +0000185 deque->leftindex = CENTER + 1;
186 deque->rightindex = CENTER;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000187 } else {
188 prevblock = deque->rightblock->leftlink;
189 assert(deque->leftblock != deque->rightblock);
190 PyMem_Free(deque->rightblock);
191 prevblock->rightlink = NULL;
192 deque->rightblock = prevblock;
193 deque->rightindex = BLOCKLEN - 1;
194 }
195 }
196 return item;
197}
198
199PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element.");
200
201static PyObject *
202deque_popleft(dequeobject *deque, PyObject *unused)
203{
204 PyObject *item;
205 block *prevblock;
206
207 if (deque->len == 0) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000208 PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000209 return NULL;
210 }
211 item = deque->leftblock->data[deque->leftindex];
212 deque->leftindex++;
213 deque->len--;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000214 deque->state++;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000215
216 if (deque->leftindex == BLOCKLEN) {
217 if (deque->len == 0) {
218 assert(deque->leftblock == deque->rightblock);
219 assert(deque->leftindex == deque->rightindex+1);
220 /* re-center instead of freeing a block */
Raymond Hettinger61f05fb2004-10-01 06:24:12 +0000221 deque->leftindex = CENTER + 1;
222 deque->rightindex = CENTER;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000223 } else {
224 assert(deque->leftblock != deque->rightblock);
225 prevblock = deque->leftblock->rightlink;
226 assert(deque->leftblock != NULL);
227 PyMem_Free(deque->leftblock);
228 assert(prevblock != NULL);
229 prevblock->leftlink = NULL;
230 deque->leftblock = prevblock;
231 deque->leftindex = 0;
232 }
233 }
234 return item;
235}
236
237PyDoc_STRVAR(popleft_doc, "Remove and return the leftmost element.");
238
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000239static PyObject *
240deque_extend(dequeobject *deque, PyObject *iterable)
241{
242 PyObject *it, *item;
243
244 it = PyObject_GetIter(iterable);
245 if (it == NULL)
246 return NULL;
247
248 while ((item = PyIter_Next(it)) != NULL) {
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000249 deque->state++;
Armin Rigo974d7572004-10-02 13:59:34 +0000250 if (deque->rightindex == BLOCKLEN-1) {
Raymond Hettingerc5fa9922004-10-06 17:51:54 +0000251 block *b = newblock(deque->rightblock, NULL,
252 deque->len);
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000253 if (b == NULL) {
254 Py_DECREF(item);
255 Py_DECREF(it);
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000256 return NULL;
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000257 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000258 assert(deque->rightblock->rightlink == NULL);
259 deque->rightblock->rightlink = b;
260 deque->rightblock = b;
Armin Rigo974d7572004-10-02 13:59:34 +0000261 deque->rightindex = -1;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000262 }
Armin Rigo974d7572004-10-02 13:59:34 +0000263 deque->len++;
264 deque->rightindex++;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000265 deque->rightblock->data[deque->rightindex] = item;
266 }
267 Py_DECREF(it);
Tim Peters1065f752004-10-01 01:03:29 +0000268 if (PyErr_Occurred())
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000269 return NULL;
270 Py_RETURN_NONE;
271}
272
Tim Peters1065f752004-10-01 01:03:29 +0000273PyDoc_STRVAR(extend_doc,
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000274"Extend the right side of the deque with elements from the iterable");
275
276static PyObject *
277deque_extendleft(dequeobject *deque, PyObject *iterable)
278{
279 PyObject *it, *item;
280
281 it = PyObject_GetIter(iterable);
282 if (it == NULL)
283 return NULL;
284
285 while ((item = PyIter_Next(it)) != NULL) {
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000286 deque->state++;
Armin Rigo974d7572004-10-02 13:59:34 +0000287 if (deque->leftindex == 0) {
Raymond Hettingerc5fa9922004-10-06 17:51:54 +0000288 block *b = newblock(NULL, deque->leftblock,
289 deque->len);
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000290 if (b == NULL) {
291 Py_DECREF(item);
292 Py_DECREF(it);
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000293 return NULL;
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000294 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000295 assert(deque->leftblock->leftlink == NULL);
296 deque->leftblock->leftlink = b;
297 deque->leftblock = b;
Armin Rigo974d7572004-10-02 13:59:34 +0000298 deque->leftindex = BLOCKLEN;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000299 }
Armin Rigo974d7572004-10-02 13:59:34 +0000300 deque->len++;
301 deque->leftindex--;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000302 deque->leftblock->data[deque->leftindex] = item;
303 }
304 Py_DECREF(it);
Raymond Hettingera435c532004-07-09 04:10:20 +0000305 if (PyErr_Occurred())
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000306 return NULL;
307 Py_RETURN_NONE;
308}
309
Tim Peters1065f752004-10-01 01:03:29 +0000310PyDoc_STRVAR(extendleft_doc,
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000311"Extend the left side of the deque with elements from the iterable");
312
Raymond Hettingerdcb9d942004-10-09 16:02:18 +0000313static int
314_deque_rotate(dequeobject *deque, int n)
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000315{
Raymond Hettingerdcb9d942004-10-09 16:02:18 +0000316 int i, len=deque->len, halflen=(len+1)>>1;
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000317 PyObject *item, *rv;
318
Raymond Hettingeree33b272004-02-08 04:05:26 +0000319 if (len == 0)
Raymond Hettingerdcb9d942004-10-09 16:02:18 +0000320 return 0;
Raymond Hettingeree33b272004-02-08 04:05:26 +0000321 if (n > halflen || n < -halflen) {
322 n %= len;
323 if (n > halflen)
324 n -= len;
325 else if (n < -halflen)
326 n += len;
327 }
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000328
329 for (i=0 ; i<n ; i++) {
330 item = deque_pop(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000331 assert (item != NULL);
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000332 rv = deque_appendleft(deque, item);
333 Py_DECREF(item);
334 if (rv == NULL)
Raymond Hettingerdcb9d942004-10-09 16:02:18 +0000335 return -1;
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000336 Py_DECREF(rv);
337 }
338 for (i=0 ; i>n ; i--) {
339 item = deque_popleft(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000340 assert (item != NULL);
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000341 rv = deque_append(deque, item);
342 Py_DECREF(item);
343 if (rv == NULL)
Raymond Hettingerdcb9d942004-10-09 16:02:18 +0000344 return -1;
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000345 Py_DECREF(rv);
346 }
Raymond Hettingerdcb9d942004-10-09 16:02:18 +0000347 return 0;
348}
349
350static PyObject *
351deque_rotate(dequeobject *deque, PyObject *args)
352{
353 int n=1;
354
355 if (!PyArg_ParseTuple(args, "|i:rotate", &n))
356 return NULL;
357 if (_deque_rotate(deque, n) == 0)
358 Py_RETURN_NONE;
359 return NULL;
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000360}
361
Tim Peters1065f752004-10-01 01:03:29 +0000362PyDoc_STRVAR(rotate_doc,
Raymond Hettingeree33b272004-02-08 04:05:26 +0000363"Rotate the deque n steps to the right (default n=1). If n is negative, rotates left.");
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000364
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000365static int
366deque_len(dequeobject *deque)
367{
368 return deque->len;
369}
370
371static int
372deque_clear(dequeobject *deque)
373{
374 PyObject *item;
375
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000376 while (deque->len) {
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000377 item = deque_pop(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000378 assert (item != NULL);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000379 Py_DECREF(item);
380 }
381 assert(deque->leftblock == deque->rightblock &&
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000382 deque->leftindex - 1 == deque->rightindex &&
383 deque->len == 0);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000384 return 0;
385}
386
387static PyObject *
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000388deque_item(dequeobject *deque, int i)
389{
390 block *b;
391 PyObject *item;
Armin Rigo974d7572004-10-02 13:59:34 +0000392 int n, index=i;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000393
394 if (i < 0 || i >= deque->len) {
395 PyErr_SetString(PyExc_IndexError,
396 "deque index out of range");
397 return NULL;
398 }
399
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000400 if (i == 0) {
401 i = deque->leftindex;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000402 b = deque->leftblock;
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000403 } else if (i == deque->len - 1) {
404 i = deque->rightindex;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000405 b = deque->rightblock;
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000406 } else {
407 i += deque->leftindex;
408 n = i / BLOCKLEN;
409 i %= BLOCKLEN;
Armin Rigo974d7572004-10-02 13:59:34 +0000410 if (index < (deque->len >> 1)) {
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000411 b = deque->leftblock;
412 while (n--)
413 b = b->rightlink;
414 } else {
415 n = (deque->leftindex + deque->len - 1) / BLOCKLEN - n;
416 b = deque->rightblock;
417 while (n--)
418 b = b->leftlink;
419 }
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000420 }
421 item = b->data[i];
422 Py_INCREF(item);
423 return item;
424}
425
Raymond Hettinger616f4f62004-06-26 04:42:06 +0000426/* delitem() implemented in terms of rotate for simplicity and reasonable
427 performance near the end points. If for some reason this method becomes
Tim Peters1065f752004-10-01 01:03:29 +0000428 popular, it is not hard to re-implement this using direct data movement
Raymond Hettinger616f4f62004-06-26 04:42:06 +0000429 (similar to code in list slice assignment) and achieve a two or threefold
430 performance boost.
431*/
432
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000433static int
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000434deque_del_item(dequeobject *deque, int i)
435{
Raymond Hettingerdcb9d942004-10-09 16:02:18 +0000436 PyObject *item;
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000437
Tim Peters1065f752004-10-01 01:03:29 +0000438 assert (i >= 0 && i < deque->len);
Raymond Hettingerdcb9d942004-10-09 16:02:18 +0000439 if (_deque_rotate(deque, -i) == -1)
440 return -1;
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000441
442 item = deque_popleft(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000443 assert (item != NULL);
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000444 Py_DECREF(item);
445
Raymond Hettingerdcb9d942004-10-09 16:02:18 +0000446 return _deque_rotate(deque, i);
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000447}
448
449static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000450deque_ass_item(dequeobject *deque, int i, PyObject *v)
451{
452 PyObject *old_value;
453 block *b;
Raymond Hettingera435c532004-07-09 04:10:20 +0000454 int n, len=deque->len, halflen=(len+1)>>1, index=i;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000455
Raymond Hettingera435c532004-07-09 04:10:20 +0000456 if (i < 0 || i >= len) {
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000457 PyErr_SetString(PyExc_IndexError,
458 "deque index out of range");
459 return -1;
460 }
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000461 if (v == NULL)
462 return deque_del_item(deque, i);
463
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000464 i += deque->leftindex;
465 n = i / BLOCKLEN;
466 i %= BLOCKLEN;
Raymond Hettingera435c532004-07-09 04:10:20 +0000467 if (index <= halflen) {
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000468 b = deque->leftblock;
469 while (n--)
470 b = b->rightlink;
471 } else {
Raymond Hettingera435c532004-07-09 04:10:20 +0000472 n = (deque->leftindex + len - 1) / BLOCKLEN - n;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000473 b = deque->rightblock;
474 while (n--)
475 b = b->leftlink;
476 }
477 Py_INCREF(v);
478 old_value = b->data[i];
479 b->data[i] = v;
480 Py_DECREF(old_value);
481 return 0;
482}
483
484static PyObject *
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000485deque_clearmethod(dequeobject *deque)
486{
Raymond Hettingera435c532004-07-09 04:10:20 +0000487 int rv;
488
489 rv = deque_clear(deque);
490 assert (rv != -1);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000491 Py_RETURN_NONE;
492}
493
494PyDoc_STRVAR(clear_doc, "Remove all elements from the deque.");
495
496static void
497deque_dealloc(dequeobject *deque)
498{
499 PyObject_GC_UnTrack(deque);
Raymond Hettinger691d8052004-05-30 07:26:47 +0000500 if (deque->weakreflist != NULL)
501 PyObject_ClearWeakRefs((PyObject *) deque);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000502 if (deque->leftblock != NULL) {
Raymond Hettingere9c89e82004-07-19 00:10:24 +0000503 deque_clear(deque);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000504 assert(deque->leftblock != NULL);
505 PyMem_Free(deque->leftblock);
506 }
507 deque->leftblock = NULL;
508 deque->rightblock = NULL;
509 deque->ob_type->tp_free(deque);
510}
511
512static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000513deque_traverse(dequeobject *deque, visitproc visit, void *arg)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000514{
Tim Peters10c7e862004-10-01 02:01:04 +0000515 block *b;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000516 PyObject *item;
Tim Peters10c7e862004-10-01 02:01:04 +0000517 int index;
518 int indexlo = deque->leftindex;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000519
Tim Peters10c7e862004-10-01 02:01:04 +0000520 for (b = deque->leftblock; b != NULL; b = b->rightlink) {
521 const int indexhi = b == deque->rightblock ?
522 deque->rightindex :
523 BLOCKLEN - 1;
524
525 for (index = indexlo; index <= indexhi; ++index) {
526 item = b->data[index];
527 Py_VISIT(item);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000528 }
Tim Peters10c7e862004-10-01 02:01:04 +0000529 indexlo = 0;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000530 }
531 return 0;
532}
533
534static long
535deque_nohash(PyObject *self)
536{
537 PyErr_SetString(PyExc_TypeError, "deque objects are unhashable");
538 return -1;
539}
540
541static PyObject *
542deque_copy(PyObject *deque)
543{
Tim Peters1065f752004-10-01 01:03:29 +0000544 return PyObject_CallFunctionObjArgs((PyObject *)(deque->ob_type),
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000545 deque, NULL);
546}
547
548PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque.");
549
550static PyObject *
551deque_reduce(dequeobject *deque)
552{
553 PyObject *seq, *args, *result;
554
555 seq = PySequence_Tuple((PyObject *)deque);
556 if (seq == NULL)
557 return NULL;
558 args = PyTuple_Pack(1, seq);
559 if (args == NULL) {
560 Py_DECREF(seq);
561 return NULL;
562 }
563 result = PyTuple_Pack(2, deque->ob_type, args);
564 Py_DECREF(seq);
565 Py_DECREF(args);
566 return result;
567}
568
569PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
570
571static PyObject *
572deque_repr(PyObject *deque)
573{
574 PyObject *aslist, *result, *fmt;
575 int i;
576
577 i = Py_ReprEnter(deque);
578 if (i != 0) {
579 if (i < 0)
580 return NULL;
581 return PyString_FromString("[...]");
582 }
583
584 aslist = PySequence_List(deque);
585 if (aslist == NULL) {
586 Py_ReprLeave(deque);
587 return NULL;
588 }
589
590 fmt = PyString_FromString("deque(%r)");
591 if (fmt == NULL) {
592 Py_DECREF(aslist);
593 Py_ReprLeave(deque);
594 return NULL;
595 }
596 result = PyString_Format(fmt, aslist);
597 Py_DECREF(fmt);
598 Py_DECREF(aslist);
599 Py_ReprLeave(deque);
600 return result;
601}
602
603static int
604deque_tp_print(PyObject *deque, FILE *fp, int flags)
605{
606 PyObject *it, *item;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000607 char *emit = ""; /* No separator emitted on first pass */
608 char *separator = ", ";
609 int i;
610
611 i = Py_ReprEnter(deque);
612 if (i != 0) {
613 if (i < 0)
614 return i;
615 fputs("[...]", fp);
616 return 0;
617 }
618
619 it = PyObject_GetIter(deque);
620 if (it == NULL)
621 return -1;
622
623 fputs("deque([", fp);
624 while ((item = PyIter_Next(it)) != NULL) {
625 fputs(emit, fp);
626 emit = separator;
627 if (PyObject_Print(item, fp, 0) != 0) {
628 Py_DECREF(item);
629 Py_DECREF(it);
630 Py_ReprLeave(deque);
631 return -1;
632 }
633 Py_DECREF(item);
634 }
635 Py_ReprLeave(deque);
636 Py_DECREF(it);
Tim Peters1065f752004-10-01 01:03:29 +0000637 if (PyErr_Occurred())
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000638 return -1;
639 fputs("])", fp);
640 return 0;
641}
642
Raymond Hettinger738ec902004-02-29 02:15:56 +0000643static PyObject *
644deque_richcompare(PyObject *v, PyObject *w, int op)
645{
646 PyObject *it1=NULL, *it2=NULL, *x, *y;
Armin Rigo974d7572004-10-02 13:59:34 +0000647 int b, vs, ws, cmp=-1;
Raymond Hettinger738ec902004-02-29 02:15:56 +0000648
Tim Peters1065f752004-10-01 01:03:29 +0000649 if (!PyObject_TypeCheck(v, &deque_type) ||
Raymond Hettinger285cfcc2004-05-18 18:15:03 +0000650 !PyObject_TypeCheck(w, &deque_type)) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000651 Py_INCREF(Py_NotImplemented);
652 return Py_NotImplemented;
653 }
654
655 /* Shortcuts */
656 vs = ((dequeobject *)v)->len;
657 ws = ((dequeobject *)w)->len;
658 if (op == Py_EQ) {
659 if (v == w)
660 Py_RETURN_TRUE;
661 if (vs != ws)
662 Py_RETURN_FALSE;
663 }
664 if (op == Py_NE) {
665 if (v == w)
666 Py_RETURN_FALSE;
667 if (vs != ws)
668 Py_RETURN_TRUE;
669 }
670
671 /* Search for the first index where items are different */
672 it1 = PyObject_GetIter(v);
673 if (it1 == NULL)
674 goto done;
675 it2 = PyObject_GetIter(w);
676 if (it2 == NULL)
677 goto done;
Armin Rigo974d7572004-10-02 13:59:34 +0000678 for (;;) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000679 x = PyIter_Next(it1);
Armin Rigo974d7572004-10-02 13:59:34 +0000680 if (x == NULL && PyErr_Occurred())
Raymond Hettinger738ec902004-02-29 02:15:56 +0000681 goto done;
682 y = PyIter_Next(it2);
Armin Rigo974d7572004-10-02 13:59:34 +0000683 if (x == NULL || y == NULL)
684 break;
Raymond Hettinger738ec902004-02-29 02:15:56 +0000685 b = PyObject_RichCompareBool(x, y, Py_EQ);
686 if (b == 0) {
687 cmp = PyObject_RichCompareBool(x, y, op);
688 Py_DECREF(x);
689 Py_DECREF(y);
690 goto done;
691 }
692 Py_DECREF(x);
693 Py_DECREF(y);
694 if (b == -1)
695 goto done;
696 }
Armin Rigo974d7572004-10-02 13:59:34 +0000697 /* We reached the end of one deque or both */
698 Py_XDECREF(x);
699 Py_XDECREF(y);
700 if (PyErr_Occurred())
701 goto done;
Raymond Hettinger738ec902004-02-29 02:15:56 +0000702 switch (op) {
Armin Rigo974d7572004-10-02 13:59:34 +0000703 case Py_LT: cmp = y != NULL; break; /* if w was longer */
704 case Py_LE: cmp = x == NULL; break; /* if v was not longer */
705 case Py_EQ: cmp = x == y; break; /* if we reached the end of both */
706 case Py_NE: cmp = x != y; break; /* if one deque continues */
707 case Py_GT: cmp = x != NULL; break; /* if v was longer */
708 case Py_GE: cmp = y == NULL; break; /* if w was not longer */
Raymond Hettinger738ec902004-02-29 02:15:56 +0000709 }
Tim Peters1065f752004-10-01 01:03:29 +0000710
Raymond Hettinger738ec902004-02-29 02:15:56 +0000711done:
712 Py_XDECREF(it1);
713 Py_XDECREF(it2);
714 if (cmp == 1)
715 Py_RETURN_TRUE;
716 if (cmp == 0)
717 Py_RETURN_FALSE;
718 return NULL;
719}
720
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000721static int
722deque_init(dequeobject *deque, PyObject *args, PyObject *kwds)
723{
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000724 PyObject *iterable = NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000725
726 if (!PyArg_UnpackTuple(args, "deque", 0, 1, &iterable))
727 return -1;
728
729 if (iterable != NULL) {
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000730 PyObject *rv = deque_extend(deque, iterable);
731 if (rv == NULL)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000732 return -1;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000733 Py_DECREF(rv);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000734 }
735 return 0;
736}
737
738static PySequenceMethods deque_as_sequence = {
739 (inquiry)deque_len, /* sq_length */
740 0, /* sq_concat */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000741 0, /* sq_repeat */
742 (intargfunc)deque_item, /* sq_item */
743 0, /* sq_slice */
744 (intobjargproc)deque_ass_item, /* sq_ass_item */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000745};
746
747/* deque object ********************************************************/
748
749static PyObject *deque_iter(dequeobject *deque);
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000750static PyObject *deque_reviter(dequeobject *deque);
Tim Peters1065f752004-10-01 01:03:29 +0000751PyDoc_STRVAR(reversed_doc,
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000752 "D.__reversed__() -- return a reverse iterator over the deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000753
754static PyMethodDef deque_methods[] = {
Tim Peters1065f752004-10-01 01:03:29 +0000755 {"append", (PyCFunction)deque_append,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000756 METH_O, append_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000757 {"appendleft", (PyCFunction)deque_appendleft,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000758 METH_O, appendleft_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000759 {"clear", (PyCFunction)deque_clearmethod,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000760 METH_NOARGS, clear_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000761 {"__copy__", (PyCFunction)deque_copy,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000762 METH_NOARGS, copy_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000763 {"extend", (PyCFunction)deque_extend,
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000764 METH_O, extend_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000765 {"extendleft", (PyCFunction)deque_extendleft,
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000766 METH_O, extendleft_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000767 {"pop", (PyCFunction)deque_pop,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000768 METH_NOARGS, pop_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000769 {"popleft", (PyCFunction)deque_popleft,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000770 METH_NOARGS, popleft_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000771 {"__reduce__", (PyCFunction)deque_reduce,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000772 METH_NOARGS, reduce_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000773 {"__reversed__", (PyCFunction)deque_reviter,
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000774 METH_NOARGS, reversed_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000775 {"rotate", (PyCFunction)deque_rotate,
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000776 METH_VARARGS, rotate_doc},
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000777 {NULL, NULL} /* sentinel */
778};
779
780PyDoc_STRVAR(deque_doc,
781"deque(iterable) --> deque object\n\
782\n\
783Build an ordered collection accessible from endpoints only.");
784
Neal Norwitz87f10132004-02-29 15:40:53 +0000785static PyTypeObject deque_type = {
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000786 PyObject_HEAD_INIT(NULL)
787 0, /* ob_size */
788 "collections.deque", /* tp_name */
789 sizeof(dequeobject), /* tp_basicsize */
790 0, /* tp_itemsize */
791 /* methods */
792 (destructor)deque_dealloc, /* tp_dealloc */
793 (printfunc)deque_tp_print, /* tp_print */
794 0, /* tp_getattr */
795 0, /* tp_setattr */
796 0, /* tp_compare */
797 (reprfunc)deque_repr, /* tp_repr */
798 0, /* tp_as_number */
799 &deque_as_sequence, /* tp_as_sequence */
800 0, /* tp_as_mapping */
801 deque_nohash, /* tp_hash */
802 0, /* tp_call */
803 0, /* tp_str */
804 PyObject_GenericGetAttr, /* tp_getattro */
805 0, /* tp_setattro */
806 0, /* tp_as_buffer */
Raymond Hettinger691d8052004-05-30 07:26:47 +0000807 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
808 Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000809 deque_doc, /* tp_doc */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000810 (traverseproc)deque_traverse, /* tp_traverse */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000811 (inquiry)deque_clear, /* tp_clear */
Raymond Hettinger738ec902004-02-29 02:15:56 +0000812 (richcmpfunc)deque_richcompare, /* tp_richcompare */
Raymond Hettinger691d8052004-05-30 07:26:47 +0000813 offsetof(dequeobject, weakreflist), /* tp_weaklistoffset*/
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000814 (getiterfunc)deque_iter, /* tp_iter */
815 0, /* tp_iternext */
816 deque_methods, /* tp_methods */
817 0, /* tp_members */
818 0, /* tp_getset */
819 0, /* tp_base */
820 0, /* tp_dict */
821 0, /* tp_descr_get */
822 0, /* tp_descr_set */
823 0, /* tp_dictoffset */
824 (initproc)deque_init, /* tp_init */
825 PyType_GenericAlloc, /* tp_alloc */
826 deque_new, /* tp_new */
827 PyObject_GC_Del, /* tp_free */
828};
829
830/*********************** Deque Iterator **************************/
831
832typedef struct {
833 PyObject_HEAD
834 int index;
835 block *b;
836 dequeobject *deque;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000837 long state; /* state when the iterator is created */
838 int counter; /* number of items remaining for iteration */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000839} dequeiterobject;
840
841PyTypeObject dequeiter_type;
842
843static PyObject *
844deque_iter(dequeobject *deque)
845{
846 dequeiterobject *it;
847
848 it = PyObject_New(dequeiterobject, &dequeiter_type);
849 if (it == NULL)
850 return NULL;
851 it->b = deque->leftblock;
852 it->index = deque->leftindex;
853 Py_INCREF(deque);
854 it->deque = deque;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000855 it->state = deque->state;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000856 it->counter = deque->len;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000857 return (PyObject *)it;
858}
859
860static void
861dequeiter_dealloc(dequeiterobject *dio)
862{
863 Py_XDECREF(dio->deque);
864 dio->ob_type->tp_free(dio);
865}
866
867static PyObject *
868dequeiter_next(dequeiterobject *it)
869{
870 PyObject *item;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000871
872 if (it->counter == 0)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000873 return NULL;
874
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000875 if (it->deque->state != it->state) {
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000876 it->counter = 0;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000877 PyErr_SetString(PyExc_RuntimeError,
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000878 "deque mutated during iteration");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000879 return NULL;
880 }
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000881 assert (!(it->b == it->deque->rightblock &&
882 it->index > it->deque->rightindex));
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000883
884 item = it->b->data[it->index];
885 it->index++;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000886 it->counter--;
887 if (it->index == BLOCKLEN && it->counter > 0) {
888 assert (it->b->rightlink != NULL);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000889 it->b = it->b->rightlink;
890 it->index = 0;
891 }
892 Py_INCREF(item);
893 return item;
894}
895
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000896static int
897dequeiter_len(dequeiterobject *it)
898{
899 return it->counter;
900}
901
902static PySequenceMethods dequeiter_as_sequence = {
903 (inquiry)dequeiter_len, /* sq_length */
904 0, /* sq_concat */
905};
906
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000907PyTypeObject dequeiter_type = {
908 PyObject_HEAD_INIT(NULL)
909 0, /* ob_size */
910 "deque_iterator", /* tp_name */
911 sizeof(dequeiterobject), /* tp_basicsize */
912 0, /* tp_itemsize */
913 /* methods */
914 (destructor)dequeiter_dealloc, /* tp_dealloc */
915 0, /* tp_print */
916 0, /* tp_getattr */
917 0, /* tp_setattr */
918 0, /* tp_compare */
919 0, /* tp_repr */
920 0, /* tp_as_number */
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000921 &dequeiter_as_sequence, /* tp_as_sequence */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000922 0, /* tp_as_mapping */
923 0, /* tp_hash */
924 0, /* tp_call */
925 0, /* tp_str */
926 PyObject_GenericGetAttr, /* tp_getattro */
927 0, /* tp_setattro */
928 0, /* tp_as_buffer */
929 Py_TPFLAGS_DEFAULT, /* tp_flags */
930 0, /* tp_doc */
931 0, /* tp_traverse */
932 0, /* tp_clear */
933 0, /* tp_richcompare */
934 0, /* tp_weaklistoffset */
935 PyObject_SelfIter, /* tp_iter */
936 (iternextfunc)dequeiter_next, /* tp_iternext */
937 0,
938};
939
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000940/*********************** Deque Reverse Iterator **************************/
941
942PyTypeObject dequereviter_type;
943
944static PyObject *
945deque_reviter(dequeobject *deque)
946{
947 dequeiterobject *it;
948
949 it = PyObject_New(dequeiterobject, &dequereviter_type);
950 if (it == NULL)
951 return NULL;
952 it->b = deque->rightblock;
953 it->index = deque->rightindex;
954 Py_INCREF(deque);
955 it->deque = deque;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000956 it->state = deque->state;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000957 it->counter = deque->len;
958 return (PyObject *)it;
959}
960
961static PyObject *
962dequereviter_next(dequeiterobject *it)
963{
964 PyObject *item;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000965 if (it->counter == 0)
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000966 return NULL;
967
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000968 if (it->deque->state != it->state) {
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000969 it->counter = 0;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000970 PyErr_SetString(PyExc_RuntimeError,
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000971 "deque mutated during iteration");
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000972 return NULL;
973 }
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000974 assert (!(it->b == it->deque->leftblock &&
975 it->index < it->deque->leftindex));
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000976
977 item = it->b->data[it->index];
978 it->index--;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000979 it->counter--;
980 if (it->index == -1 && it->counter > 0) {
981 assert (it->b->leftlink != NULL);
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000982 it->b = it->b->leftlink;
983 it->index = BLOCKLEN - 1;
984 }
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000985 Py_INCREF(item);
986 return item;
987}
988
989PyTypeObject dequereviter_type = {
990 PyObject_HEAD_INIT(NULL)
991 0, /* ob_size */
992 "deque_reverse_iterator", /* tp_name */
993 sizeof(dequeiterobject), /* tp_basicsize */
994 0, /* tp_itemsize */
995 /* methods */
996 (destructor)dequeiter_dealloc, /* tp_dealloc */
997 0, /* tp_print */
998 0, /* tp_getattr */
999 0, /* tp_setattr */
1000 0, /* tp_compare */
1001 0, /* tp_repr */
1002 0, /* tp_as_number */
1003 &dequeiter_as_sequence, /* tp_as_sequence */
1004 0, /* tp_as_mapping */
1005 0, /* tp_hash */
1006 0, /* tp_call */
1007 0, /* tp_str */
1008 PyObject_GenericGetAttr, /* tp_getattro */
1009 0, /* tp_setattro */
1010 0, /* tp_as_buffer */
1011 Py_TPFLAGS_DEFAULT, /* tp_flags */
1012 0, /* tp_doc */
1013 0, /* tp_traverse */
1014 0, /* tp_clear */
1015 0, /* tp_richcompare */
1016 0, /* tp_weaklistoffset */
1017 PyObject_SelfIter, /* tp_iter */
1018 (iternextfunc)dequereviter_next, /* tp_iternext */
1019 0,
1020};
1021
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001022/* module level code ********************************************************/
1023
1024PyDoc_STRVAR(module_doc,
1025"High performance data structures\n\
1026");
1027
1028PyMODINIT_FUNC
1029initcollections(void)
1030{
1031 PyObject *m;
1032
1033 m = Py_InitModule3("collections", NULL, module_doc);
1034
1035 if (PyType_Ready(&deque_type) < 0)
1036 return;
1037 Py_INCREF(&deque_type);
1038 PyModule_AddObject(m, "deque", (PyObject *)&deque_type);
1039
1040 if (PyType_Ready(&dequeiter_type) < 0)
Tim Peters1065f752004-10-01 01:03:29 +00001041 return;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001042
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001043 if (PyType_Ready(&dequereviter_type) < 0)
1044 return;
1045
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001046 return;
1047}