blob: a766eec0a5c5c1c50fe925910cfb08db3a868abb [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
16#define BLOCKLEN 46
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 Hettinger5c5eb862004-02-07 21:13:00 +0000313static PyObject *
314deque_rotate(dequeobject *deque, PyObject *args)
315{
Raymond Hettingeree33b272004-02-08 04:05:26 +0000316 int i, n=1, 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 (!PyArg_ParseTuple(args, "|i:rotate", &n))
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000320 return NULL;
321
Raymond Hettingeree33b272004-02-08 04:05:26 +0000322 if (len == 0)
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000323 Py_RETURN_NONE;
Raymond Hettingeree33b272004-02-08 04:05:26 +0000324 if (n > halflen || n < -halflen) {
325 n %= len;
326 if (n > halflen)
327 n -= len;
328 else if (n < -halflen)
329 n += len;
330 }
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000331
332 for (i=0 ; i<n ; i++) {
333 item = deque_pop(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000334 assert (item != NULL);
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000335 rv = deque_appendleft(deque, item);
336 Py_DECREF(item);
337 if (rv == NULL)
338 return NULL;
339 Py_DECREF(rv);
340 }
341 for (i=0 ; i>n ; i--) {
342 item = deque_popleft(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000343 assert (item != NULL);
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000344 rv = deque_append(deque, item);
345 Py_DECREF(item);
346 if (rv == NULL)
347 return NULL;
348 Py_DECREF(rv);
349 }
350 Py_RETURN_NONE;
351}
352
Tim Peters1065f752004-10-01 01:03:29 +0000353PyDoc_STRVAR(rotate_doc,
Raymond Hettingeree33b272004-02-08 04:05:26 +0000354"Rotate the deque n steps to the right (default n=1). If n is negative, rotates left.");
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000355
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000356static int
357deque_len(dequeobject *deque)
358{
359 return deque->len;
360}
361
362static int
363deque_clear(dequeobject *deque)
364{
365 PyObject *item;
366
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000367 while (deque->len) {
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000368 item = deque_pop(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000369 assert (item != NULL);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000370 Py_DECREF(item);
371 }
372 assert(deque->leftblock == deque->rightblock &&
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000373 deque->leftindex - 1 == deque->rightindex &&
374 deque->len == 0);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000375 return 0;
376}
377
378static PyObject *
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000379deque_item(dequeobject *deque, int i)
380{
381 block *b;
382 PyObject *item;
Armin Rigo974d7572004-10-02 13:59:34 +0000383 int n, index=i;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000384
385 if (i < 0 || i >= deque->len) {
386 PyErr_SetString(PyExc_IndexError,
387 "deque index out of range");
388 return NULL;
389 }
390
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000391 if (i == 0) {
392 i = deque->leftindex;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000393 b = deque->leftblock;
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000394 } else if (i == deque->len - 1) {
395 i = deque->rightindex;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000396 b = deque->rightblock;
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000397 } else {
398 i += deque->leftindex;
399 n = i / BLOCKLEN;
400 i %= BLOCKLEN;
Armin Rigo974d7572004-10-02 13:59:34 +0000401 if (index < (deque->len >> 1)) {
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000402 b = deque->leftblock;
403 while (n--)
404 b = b->rightlink;
405 } else {
406 n = (deque->leftindex + deque->len - 1) / BLOCKLEN - n;
407 b = deque->rightblock;
408 while (n--)
409 b = b->leftlink;
410 }
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000411 }
412 item = b->data[i];
413 Py_INCREF(item);
414 return item;
415}
416
Raymond Hettinger616f4f62004-06-26 04:42:06 +0000417/* delitem() implemented in terms of rotate for simplicity and reasonable
418 performance near the end points. If for some reason this method becomes
Tim Peters1065f752004-10-01 01:03:29 +0000419 popular, it is not hard to re-implement this using direct data movement
Raymond Hettinger616f4f62004-06-26 04:42:06 +0000420 (similar to code in list slice assignment) and achieve a two or threefold
421 performance boost.
422*/
423
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000424static int
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000425deque_del_item(dequeobject *deque, int i)
426{
427 PyObject *item=NULL, *minus_i=NULL, *plus_i=NULL;
428 int rv = -1;
429
Tim Peters1065f752004-10-01 01:03:29 +0000430 assert (i >= 0 && i < deque->len);
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000431
432 minus_i = Py_BuildValue("(i)", -i);
433 if (minus_i == NULL)
434 goto fail;
435
436 plus_i = Py_BuildValue("(i)", i);
437 if (plus_i == NULL)
438 goto fail;
439
440 item = deque_rotate(deque, minus_i);
Tim Peters1065f752004-10-01 01:03:29 +0000441 if (item == NULL)
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000442 goto fail;
443 Py_DECREF(item);
444
445 item = deque_popleft(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000446 assert (item != NULL);
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000447 Py_DECREF(item);
448
449 item = deque_rotate(deque, plus_i);
Tim Peters1065f752004-10-01 01:03:29 +0000450 if (item == NULL)
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000451 goto fail;
452
453 rv = 0;
454fail:
455 Py_XDECREF(item);
456 Py_XDECREF(minus_i);
457 Py_XDECREF(plus_i);
458 return rv;
459}
460
461static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000462deque_ass_item(dequeobject *deque, int i, PyObject *v)
463{
464 PyObject *old_value;
465 block *b;
Raymond Hettingera435c532004-07-09 04:10:20 +0000466 int n, len=deque->len, halflen=(len+1)>>1, index=i;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000467
Raymond Hettingera435c532004-07-09 04:10:20 +0000468 if (i < 0 || i >= len) {
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000469 PyErr_SetString(PyExc_IndexError,
470 "deque index out of range");
471 return -1;
472 }
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000473 if (v == NULL)
474 return deque_del_item(deque, i);
475
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000476 i += deque->leftindex;
477 n = i / BLOCKLEN;
478 i %= BLOCKLEN;
Raymond Hettingera435c532004-07-09 04:10:20 +0000479 if (index <= halflen) {
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000480 b = deque->leftblock;
481 while (n--)
482 b = b->rightlink;
483 } else {
Raymond Hettingera435c532004-07-09 04:10:20 +0000484 n = (deque->leftindex + len - 1) / BLOCKLEN - n;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000485 b = deque->rightblock;
486 while (n--)
487 b = b->leftlink;
488 }
489 Py_INCREF(v);
490 old_value = b->data[i];
491 b->data[i] = v;
492 Py_DECREF(old_value);
493 return 0;
494}
495
496static PyObject *
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000497deque_clearmethod(dequeobject *deque)
498{
Raymond Hettingera435c532004-07-09 04:10:20 +0000499 int rv;
500
501 rv = deque_clear(deque);
502 assert (rv != -1);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000503 Py_RETURN_NONE;
504}
505
506PyDoc_STRVAR(clear_doc, "Remove all elements from the deque.");
507
508static void
509deque_dealloc(dequeobject *deque)
510{
511 PyObject_GC_UnTrack(deque);
Raymond Hettinger691d8052004-05-30 07:26:47 +0000512 if (deque->weakreflist != NULL)
513 PyObject_ClearWeakRefs((PyObject *) deque);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000514 if (deque->leftblock != NULL) {
Raymond Hettingere9c89e82004-07-19 00:10:24 +0000515 deque_clear(deque);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000516 assert(deque->leftblock != NULL);
517 PyMem_Free(deque->leftblock);
518 }
519 deque->leftblock = NULL;
520 deque->rightblock = NULL;
521 deque->ob_type->tp_free(deque);
522}
523
524static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000525deque_traverse(dequeobject *deque, visitproc visit, void *arg)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000526{
Tim Peters10c7e862004-10-01 02:01:04 +0000527 block *b;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000528 PyObject *item;
Tim Peters10c7e862004-10-01 02:01:04 +0000529 int index;
530 int indexlo = deque->leftindex;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000531
Tim Peters10c7e862004-10-01 02:01:04 +0000532 for (b = deque->leftblock; b != NULL; b = b->rightlink) {
533 const int indexhi = b == deque->rightblock ?
534 deque->rightindex :
535 BLOCKLEN - 1;
536
537 for (index = indexlo; index <= indexhi; ++index) {
538 item = b->data[index];
539 Py_VISIT(item);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000540 }
Tim Peters10c7e862004-10-01 02:01:04 +0000541 indexlo = 0;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000542 }
543 return 0;
544}
545
546static long
547deque_nohash(PyObject *self)
548{
549 PyErr_SetString(PyExc_TypeError, "deque objects are unhashable");
550 return -1;
551}
552
553static PyObject *
554deque_copy(PyObject *deque)
555{
Tim Peters1065f752004-10-01 01:03:29 +0000556 return PyObject_CallFunctionObjArgs((PyObject *)(deque->ob_type),
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000557 deque, NULL);
558}
559
560PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque.");
561
562static PyObject *
563deque_reduce(dequeobject *deque)
564{
565 PyObject *seq, *args, *result;
566
567 seq = PySequence_Tuple((PyObject *)deque);
568 if (seq == NULL)
569 return NULL;
570 args = PyTuple_Pack(1, seq);
571 if (args == NULL) {
572 Py_DECREF(seq);
573 return NULL;
574 }
575 result = PyTuple_Pack(2, deque->ob_type, args);
576 Py_DECREF(seq);
577 Py_DECREF(args);
578 return result;
579}
580
581PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
582
583static PyObject *
584deque_repr(PyObject *deque)
585{
586 PyObject *aslist, *result, *fmt;
587 int i;
588
589 i = Py_ReprEnter(deque);
590 if (i != 0) {
591 if (i < 0)
592 return NULL;
593 return PyString_FromString("[...]");
594 }
595
596 aslist = PySequence_List(deque);
597 if (aslist == NULL) {
598 Py_ReprLeave(deque);
599 return NULL;
600 }
601
602 fmt = PyString_FromString("deque(%r)");
603 if (fmt == NULL) {
604 Py_DECREF(aslist);
605 Py_ReprLeave(deque);
606 return NULL;
607 }
608 result = PyString_Format(fmt, aslist);
609 Py_DECREF(fmt);
610 Py_DECREF(aslist);
611 Py_ReprLeave(deque);
612 return result;
613}
614
615static int
616deque_tp_print(PyObject *deque, FILE *fp, int flags)
617{
618 PyObject *it, *item;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000619 char *emit = ""; /* No separator emitted on first pass */
620 char *separator = ", ";
621 int i;
622
623 i = Py_ReprEnter(deque);
624 if (i != 0) {
625 if (i < 0)
626 return i;
627 fputs("[...]", fp);
628 return 0;
629 }
630
631 it = PyObject_GetIter(deque);
632 if (it == NULL)
633 return -1;
634
635 fputs("deque([", fp);
636 while ((item = PyIter_Next(it)) != NULL) {
637 fputs(emit, fp);
638 emit = separator;
639 if (PyObject_Print(item, fp, 0) != 0) {
640 Py_DECREF(item);
641 Py_DECREF(it);
642 Py_ReprLeave(deque);
643 return -1;
644 }
645 Py_DECREF(item);
646 }
647 Py_ReprLeave(deque);
648 Py_DECREF(it);
Tim Peters1065f752004-10-01 01:03:29 +0000649 if (PyErr_Occurred())
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000650 return -1;
651 fputs("])", fp);
652 return 0;
653}
654
Raymond Hettinger738ec902004-02-29 02:15:56 +0000655static PyObject *
656deque_richcompare(PyObject *v, PyObject *w, int op)
657{
658 PyObject *it1=NULL, *it2=NULL, *x, *y;
Armin Rigo974d7572004-10-02 13:59:34 +0000659 int b, vs, ws, cmp=-1;
Raymond Hettinger738ec902004-02-29 02:15:56 +0000660
Tim Peters1065f752004-10-01 01:03:29 +0000661 if (!PyObject_TypeCheck(v, &deque_type) ||
Raymond Hettinger285cfcc2004-05-18 18:15:03 +0000662 !PyObject_TypeCheck(w, &deque_type)) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000663 Py_INCREF(Py_NotImplemented);
664 return Py_NotImplemented;
665 }
666
667 /* Shortcuts */
668 vs = ((dequeobject *)v)->len;
669 ws = ((dequeobject *)w)->len;
670 if (op == Py_EQ) {
671 if (v == w)
672 Py_RETURN_TRUE;
673 if (vs != ws)
674 Py_RETURN_FALSE;
675 }
676 if (op == Py_NE) {
677 if (v == w)
678 Py_RETURN_FALSE;
679 if (vs != ws)
680 Py_RETURN_TRUE;
681 }
682
683 /* Search for the first index where items are different */
684 it1 = PyObject_GetIter(v);
685 if (it1 == NULL)
686 goto done;
687 it2 = PyObject_GetIter(w);
688 if (it2 == NULL)
689 goto done;
Armin Rigo974d7572004-10-02 13:59:34 +0000690 for (;;) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000691 x = PyIter_Next(it1);
Armin Rigo974d7572004-10-02 13:59:34 +0000692 if (x == NULL && PyErr_Occurred())
Raymond Hettinger738ec902004-02-29 02:15:56 +0000693 goto done;
694 y = PyIter_Next(it2);
Armin Rigo974d7572004-10-02 13:59:34 +0000695 if (x == NULL || y == NULL)
696 break;
Raymond Hettinger738ec902004-02-29 02:15:56 +0000697 b = PyObject_RichCompareBool(x, y, Py_EQ);
698 if (b == 0) {
699 cmp = PyObject_RichCompareBool(x, y, op);
700 Py_DECREF(x);
701 Py_DECREF(y);
702 goto done;
703 }
704 Py_DECREF(x);
705 Py_DECREF(y);
706 if (b == -1)
707 goto done;
708 }
Armin Rigo974d7572004-10-02 13:59:34 +0000709 /* We reached the end of one deque or both */
710 Py_XDECREF(x);
711 Py_XDECREF(y);
712 if (PyErr_Occurred())
713 goto done;
Raymond Hettinger738ec902004-02-29 02:15:56 +0000714 switch (op) {
Armin Rigo974d7572004-10-02 13:59:34 +0000715 case Py_LT: cmp = y != NULL; break; /* if w was longer */
716 case Py_LE: cmp = x == NULL; break; /* if v was not longer */
717 case Py_EQ: cmp = x == y; break; /* if we reached the end of both */
718 case Py_NE: cmp = x != y; break; /* if one deque continues */
719 case Py_GT: cmp = x != NULL; break; /* if v was longer */
720 case Py_GE: cmp = y == NULL; break; /* if w was not longer */
Raymond Hettinger738ec902004-02-29 02:15:56 +0000721 }
Tim Peters1065f752004-10-01 01:03:29 +0000722
Raymond Hettinger738ec902004-02-29 02:15:56 +0000723done:
724 Py_XDECREF(it1);
725 Py_XDECREF(it2);
726 if (cmp == 1)
727 Py_RETURN_TRUE;
728 if (cmp == 0)
729 Py_RETURN_FALSE;
730 return NULL;
731}
732
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000733static int
734deque_init(dequeobject *deque, PyObject *args, PyObject *kwds)
735{
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000736 PyObject *iterable = NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000737
738 if (!PyArg_UnpackTuple(args, "deque", 0, 1, &iterable))
739 return -1;
740
741 if (iterable != NULL) {
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000742 PyObject *rv = deque_extend(deque, iterable);
743 if (rv == NULL)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000744 return -1;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000745 Py_DECREF(rv);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000746 }
747 return 0;
748}
749
750static PySequenceMethods deque_as_sequence = {
751 (inquiry)deque_len, /* sq_length */
752 0, /* sq_concat */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000753 0, /* sq_repeat */
754 (intargfunc)deque_item, /* sq_item */
755 0, /* sq_slice */
756 (intobjargproc)deque_ass_item, /* sq_ass_item */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000757};
758
759/* deque object ********************************************************/
760
761static PyObject *deque_iter(dequeobject *deque);
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000762static PyObject *deque_reviter(dequeobject *deque);
Tim Peters1065f752004-10-01 01:03:29 +0000763PyDoc_STRVAR(reversed_doc,
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000764 "D.__reversed__() -- return a reverse iterator over the deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000765
766static PyMethodDef deque_methods[] = {
Tim Peters1065f752004-10-01 01:03:29 +0000767 {"append", (PyCFunction)deque_append,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000768 METH_O, append_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000769 {"appendleft", (PyCFunction)deque_appendleft,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000770 METH_O, appendleft_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000771 {"clear", (PyCFunction)deque_clearmethod,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000772 METH_NOARGS, clear_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000773 {"__copy__", (PyCFunction)deque_copy,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000774 METH_NOARGS, copy_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000775 {"extend", (PyCFunction)deque_extend,
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000776 METH_O, extend_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000777 {"extendleft", (PyCFunction)deque_extendleft,
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000778 METH_O, extendleft_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000779 {"pop", (PyCFunction)deque_pop,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000780 METH_NOARGS, pop_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000781 {"popleft", (PyCFunction)deque_popleft,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000782 METH_NOARGS, popleft_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000783 {"__reduce__", (PyCFunction)deque_reduce,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000784 METH_NOARGS, reduce_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000785 {"__reversed__", (PyCFunction)deque_reviter,
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000786 METH_NOARGS, reversed_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000787 {"rotate", (PyCFunction)deque_rotate,
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000788 METH_VARARGS, rotate_doc},
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000789 {NULL, NULL} /* sentinel */
790};
791
792PyDoc_STRVAR(deque_doc,
793"deque(iterable) --> deque object\n\
794\n\
795Build an ordered collection accessible from endpoints only.");
796
Neal Norwitz87f10132004-02-29 15:40:53 +0000797static PyTypeObject deque_type = {
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000798 PyObject_HEAD_INIT(NULL)
799 0, /* ob_size */
800 "collections.deque", /* tp_name */
801 sizeof(dequeobject), /* tp_basicsize */
802 0, /* tp_itemsize */
803 /* methods */
804 (destructor)deque_dealloc, /* tp_dealloc */
805 (printfunc)deque_tp_print, /* tp_print */
806 0, /* tp_getattr */
807 0, /* tp_setattr */
808 0, /* tp_compare */
809 (reprfunc)deque_repr, /* tp_repr */
810 0, /* tp_as_number */
811 &deque_as_sequence, /* tp_as_sequence */
812 0, /* tp_as_mapping */
813 deque_nohash, /* tp_hash */
814 0, /* tp_call */
815 0, /* tp_str */
816 PyObject_GenericGetAttr, /* tp_getattro */
817 0, /* tp_setattro */
818 0, /* tp_as_buffer */
Raymond Hettinger691d8052004-05-30 07:26:47 +0000819 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
820 Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000821 deque_doc, /* tp_doc */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000822 (traverseproc)deque_traverse, /* tp_traverse */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000823 (inquiry)deque_clear, /* tp_clear */
Raymond Hettinger738ec902004-02-29 02:15:56 +0000824 (richcmpfunc)deque_richcompare, /* tp_richcompare */
Raymond Hettinger691d8052004-05-30 07:26:47 +0000825 offsetof(dequeobject, weakreflist), /* tp_weaklistoffset*/
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000826 (getiterfunc)deque_iter, /* tp_iter */
827 0, /* tp_iternext */
828 deque_methods, /* tp_methods */
829 0, /* tp_members */
830 0, /* tp_getset */
831 0, /* tp_base */
832 0, /* tp_dict */
833 0, /* tp_descr_get */
834 0, /* tp_descr_set */
835 0, /* tp_dictoffset */
836 (initproc)deque_init, /* tp_init */
837 PyType_GenericAlloc, /* tp_alloc */
838 deque_new, /* tp_new */
839 PyObject_GC_Del, /* tp_free */
840};
841
842/*********************** Deque Iterator **************************/
843
844typedef struct {
845 PyObject_HEAD
846 int index;
847 block *b;
848 dequeobject *deque;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000849 long state; /* state when the iterator is created */
850 int counter; /* number of items remaining for iteration */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000851} dequeiterobject;
852
853PyTypeObject dequeiter_type;
854
855static PyObject *
856deque_iter(dequeobject *deque)
857{
858 dequeiterobject *it;
859
860 it = PyObject_New(dequeiterobject, &dequeiter_type);
861 if (it == NULL)
862 return NULL;
863 it->b = deque->leftblock;
864 it->index = deque->leftindex;
865 Py_INCREF(deque);
866 it->deque = deque;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000867 it->state = deque->state;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000868 it->counter = deque->len;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000869 return (PyObject *)it;
870}
871
872static void
873dequeiter_dealloc(dequeiterobject *dio)
874{
875 Py_XDECREF(dio->deque);
876 dio->ob_type->tp_free(dio);
877}
878
879static PyObject *
880dequeiter_next(dequeiterobject *it)
881{
882 PyObject *item;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000883
884 if (it->counter == 0)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000885 return NULL;
886
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000887 if (it->deque->state != it->state) {
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000888 it->counter = 0;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000889 PyErr_SetString(PyExc_RuntimeError,
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000890 "deque mutated during iteration");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000891 return NULL;
892 }
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000893 assert (!(it->b == it->deque->rightblock &&
894 it->index > it->deque->rightindex));
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000895
896 item = it->b->data[it->index];
897 it->index++;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000898 it->counter--;
899 if (it->index == BLOCKLEN && it->counter > 0) {
900 assert (it->b->rightlink != NULL);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000901 it->b = it->b->rightlink;
902 it->index = 0;
903 }
904 Py_INCREF(item);
905 return item;
906}
907
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000908static int
909dequeiter_len(dequeiterobject *it)
910{
911 return it->counter;
912}
913
914static PySequenceMethods dequeiter_as_sequence = {
915 (inquiry)dequeiter_len, /* sq_length */
916 0, /* sq_concat */
917};
918
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000919PyTypeObject dequeiter_type = {
920 PyObject_HEAD_INIT(NULL)
921 0, /* ob_size */
922 "deque_iterator", /* tp_name */
923 sizeof(dequeiterobject), /* tp_basicsize */
924 0, /* tp_itemsize */
925 /* methods */
926 (destructor)dequeiter_dealloc, /* tp_dealloc */
927 0, /* tp_print */
928 0, /* tp_getattr */
929 0, /* tp_setattr */
930 0, /* tp_compare */
931 0, /* tp_repr */
932 0, /* tp_as_number */
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000933 &dequeiter_as_sequence, /* tp_as_sequence */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000934 0, /* tp_as_mapping */
935 0, /* tp_hash */
936 0, /* tp_call */
937 0, /* tp_str */
938 PyObject_GenericGetAttr, /* tp_getattro */
939 0, /* tp_setattro */
940 0, /* tp_as_buffer */
941 Py_TPFLAGS_DEFAULT, /* tp_flags */
942 0, /* tp_doc */
943 0, /* tp_traverse */
944 0, /* tp_clear */
945 0, /* tp_richcompare */
946 0, /* tp_weaklistoffset */
947 PyObject_SelfIter, /* tp_iter */
948 (iternextfunc)dequeiter_next, /* tp_iternext */
949 0,
950};
951
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000952/*********************** Deque Reverse Iterator **************************/
953
954PyTypeObject dequereviter_type;
955
956static PyObject *
957deque_reviter(dequeobject *deque)
958{
959 dequeiterobject *it;
960
961 it = PyObject_New(dequeiterobject, &dequereviter_type);
962 if (it == NULL)
963 return NULL;
964 it->b = deque->rightblock;
965 it->index = deque->rightindex;
966 Py_INCREF(deque);
967 it->deque = deque;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000968 it->state = deque->state;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000969 it->counter = deque->len;
970 return (PyObject *)it;
971}
972
973static PyObject *
974dequereviter_next(dequeiterobject *it)
975{
976 PyObject *item;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000977 if (it->counter == 0)
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000978 return NULL;
979
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000980 if (it->deque->state != it->state) {
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000981 it->counter = 0;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000982 PyErr_SetString(PyExc_RuntimeError,
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000983 "deque mutated during iteration");
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000984 return NULL;
985 }
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000986 assert (!(it->b == it->deque->leftblock &&
987 it->index < it->deque->leftindex));
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000988
989 item = it->b->data[it->index];
990 it->index--;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000991 it->counter--;
992 if (it->index == -1 && it->counter > 0) {
993 assert (it->b->leftlink != NULL);
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000994 it->b = it->b->leftlink;
995 it->index = BLOCKLEN - 1;
996 }
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000997 Py_INCREF(item);
998 return item;
999}
1000
1001PyTypeObject dequereviter_type = {
1002 PyObject_HEAD_INIT(NULL)
1003 0, /* ob_size */
1004 "deque_reverse_iterator", /* tp_name */
1005 sizeof(dequeiterobject), /* tp_basicsize */
1006 0, /* tp_itemsize */
1007 /* methods */
1008 (destructor)dequeiter_dealloc, /* tp_dealloc */
1009 0, /* tp_print */
1010 0, /* tp_getattr */
1011 0, /* tp_setattr */
1012 0, /* tp_compare */
1013 0, /* tp_repr */
1014 0, /* tp_as_number */
1015 &dequeiter_as_sequence, /* tp_as_sequence */
1016 0, /* tp_as_mapping */
1017 0, /* tp_hash */
1018 0, /* tp_call */
1019 0, /* tp_str */
1020 PyObject_GenericGetAttr, /* tp_getattro */
1021 0, /* tp_setattro */
1022 0, /* tp_as_buffer */
1023 Py_TPFLAGS_DEFAULT, /* tp_flags */
1024 0, /* tp_doc */
1025 0, /* tp_traverse */
1026 0, /* tp_clear */
1027 0, /* tp_richcompare */
1028 0, /* tp_weaklistoffset */
1029 PyObject_SelfIter, /* tp_iter */
1030 (iternextfunc)dequereviter_next, /* tp_iternext */
1031 0,
1032};
1033
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001034/* module level code ********************************************************/
1035
1036PyDoc_STRVAR(module_doc,
1037"High performance data structures\n\
1038");
1039
1040PyMODINIT_FUNC
1041initcollections(void)
1042{
1043 PyObject *m;
1044
1045 m = Py_InitModule3("collections", NULL, module_doc);
1046
1047 if (PyType_Ready(&deque_type) < 0)
1048 return;
1049 Py_INCREF(&deque_type);
1050 PyModule_AddObject(m, "deque", (PyObject *)&deque_type);
1051
1052 if (PyType_Ready(&dequeiter_type) < 0)
Tim Peters1065f752004-10-01 01:03:29 +00001053 return;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001054
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001055 if (PyType_Ready(&dequereviter_type) < 0)
1056 return;
1057
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001058 return;
1059}