blob: 2fbd72990278d7e5f3f955da3e31b7b4ff9d7a8e [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
Raymond Hettinger4aec61e2005-03-18 21:20:23 +0000371static PyObject *
372deque_remove(dequeobject *deque, PyObject *value)
373{
374 int i, n=deque->len;
375
376 for (i=0 ; i<n ; i++) {
377 PyObject *item = deque->leftblock->data[deque->leftindex];
378 int cmp = PyObject_RichCompareBool(item, value, Py_EQ);
Raymond Hettingerd73202c2005-03-19 00:00:51 +0000379
380 if (deque->len != n) {
381 PyErr_SetString(PyExc_IndexError,
382 "deque mutated during remove().");
383 return NULL;
384 }
Raymond Hettinger4aec61e2005-03-18 21:20:23 +0000385 if (cmp > 0) {
Raymond Hettingerd73202c2005-03-19 00:00:51 +0000386 PyObject *tgt = deque_popleft(deque, NULL);
Raymond Hettinger4aec61e2005-03-18 21:20:23 +0000387 assert (tgt != NULL);
388 Py_DECREF(tgt);
389 if (_deque_rotate(deque, i) == -1)
390 return NULL;
391 Py_RETURN_NONE;
392 }
393 else if (cmp < 0) {
394 _deque_rotate(deque, i);
395 return NULL;
396 }
397 _deque_rotate(deque, -1);
398 }
399 PyErr_SetString(PyExc_ValueError, "deque.remove(x): x not in deque");
400 return NULL;
401}
402
403PyDoc_STRVAR(remove_doc,
404"D.remove(value) -- remove first occurrence of value.");
405
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000406static int
407deque_clear(dequeobject *deque)
408{
409 PyObject *item;
410
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000411 while (deque->len) {
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000412 item = deque_pop(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000413 assert (item != NULL);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000414 Py_DECREF(item);
415 }
416 assert(deque->leftblock == deque->rightblock &&
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000417 deque->leftindex - 1 == deque->rightindex &&
418 deque->len == 0);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000419 return 0;
420}
421
422static PyObject *
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000423deque_item(dequeobject *deque, int i)
424{
425 block *b;
426 PyObject *item;
Armin Rigo974d7572004-10-02 13:59:34 +0000427 int n, index=i;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000428
429 if (i < 0 || i >= deque->len) {
430 PyErr_SetString(PyExc_IndexError,
431 "deque index out of range");
432 return NULL;
433 }
434
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000435 if (i == 0) {
436 i = deque->leftindex;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000437 b = deque->leftblock;
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000438 } else if (i == deque->len - 1) {
439 i = deque->rightindex;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000440 b = deque->rightblock;
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000441 } else {
442 i += deque->leftindex;
443 n = i / BLOCKLEN;
444 i %= BLOCKLEN;
Armin Rigo974d7572004-10-02 13:59:34 +0000445 if (index < (deque->len >> 1)) {
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000446 b = deque->leftblock;
447 while (n--)
448 b = b->rightlink;
449 } else {
450 n = (deque->leftindex + deque->len - 1) / BLOCKLEN - n;
451 b = deque->rightblock;
452 while (n--)
453 b = b->leftlink;
454 }
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000455 }
456 item = b->data[i];
457 Py_INCREF(item);
458 return item;
459}
460
Raymond Hettinger616f4f62004-06-26 04:42:06 +0000461/* delitem() implemented in terms of rotate for simplicity and reasonable
462 performance near the end points. If for some reason this method becomes
Tim Peters1065f752004-10-01 01:03:29 +0000463 popular, it is not hard to re-implement this using direct data movement
Raymond Hettinger616f4f62004-06-26 04:42:06 +0000464 (similar to code in list slice assignment) and achieve a two or threefold
465 performance boost.
466*/
467
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000468static int
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000469deque_del_item(dequeobject *deque, int i)
470{
Raymond Hettingerdcb9d942004-10-09 16:02:18 +0000471 PyObject *item;
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000472
Tim Peters1065f752004-10-01 01:03:29 +0000473 assert (i >= 0 && i < deque->len);
Raymond Hettingerdcb9d942004-10-09 16:02:18 +0000474 if (_deque_rotate(deque, -i) == -1)
475 return -1;
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000476
477 item = deque_popleft(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000478 assert (item != NULL);
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000479 Py_DECREF(item);
480
Raymond Hettingerdcb9d942004-10-09 16:02:18 +0000481 return _deque_rotate(deque, i);
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000482}
483
484static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000485deque_ass_item(dequeobject *deque, int i, PyObject *v)
486{
487 PyObject *old_value;
488 block *b;
Raymond Hettingera435c532004-07-09 04:10:20 +0000489 int n, len=deque->len, halflen=(len+1)>>1, index=i;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000490
Raymond Hettingera435c532004-07-09 04:10:20 +0000491 if (i < 0 || i >= len) {
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000492 PyErr_SetString(PyExc_IndexError,
493 "deque index out of range");
494 return -1;
495 }
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000496 if (v == NULL)
497 return deque_del_item(deque, i);
498
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000499 i += deque->leftindex;
500 n = i / BLOCKLEN;
501 i %= BLOCKLEN;
Raymond Hettingera435c532004-07-09 04:10:20 +0000502 if (index <= halflen) {
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000503 b = deque->leftblock;
504 while (n--)
505 b = b->rightlink;
506 } else {
Raymond Hettingera435c532004-07-09 04:10:20 +0000507 n = (deque->leftindex + len - 1) / BLOCKLEN - n;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000508 b = deque->rightblock;
509 while (n--)
510 b = b->leftlink;
511 }
512 Py_INCREF(v);
513 old_value = b->data[i];
514 b->data[i] = v;
515 Py_DECREF(old_value);
516 return 0;
517}
518
519static PyObject *
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000520deque_clearmethod(dequeobject *deque)
521{
Raymond Hettingera435c532004-07-09 04:10:20 +0000522 int rv;
523
524 rv = deque_clear(deque);
525 assert (rv != -1);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000526 Py_RETURN_NONE;
527}
528
529PyDoc_STRVAR(clear_doc, "Remove all elements from the deque.");
530
531static void
532deque_dealloc(dequeobject *deque)
533{
534 PyObject_GC_UnTrack(deque);
Raymond Hettinger691d8052004-05-30 07:26:47 +0000535 if (deque->weakreflist != NULL)
536 PyObject_ClearWeakRefs((PyObject *) deque);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000537 if (deque->leftblock != NULL) {
Raymond Hettingere9c89e82004-07-19 00:10:24 +0000538 deque_clear(deque);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000539 assert(deque->leftblock != NULL);
540 PyMem_Free(deque->leftblock);
541 }
542 deque->leftblock = NULL;
543 deque->rightblock = NULL;
544 deque->ob_type->tp_free(deque);
545}
546
547static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000548deque_traverse(dequeobject *deque, visitproc visit, void *arg)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000549{
Tim Peters10c7e862004-10-01 02:01:04 +0000550 block *b;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000551 PyObject *item;
Tim Peters10c7e862004-10-01 02:01:04 +0000552 int index;
553 int indexlo = deque->leftindex;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000554
Tim Peters10c7e862004-10-01 02:01:04 +0000555 for (b = deque->leftblock; b != NULL; b = b->rightlink) {
556 const int indexhi = b == deque->rightblock ?
557 deque->rightindex :
558 BLOCKLEN - 1;
559
560 for (index = indexlo; index <= indexhi; ++index) {
561 item = b->data[index];
562 Py_VISIT(item);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000563 }
Tim Peters10c7e862004-10-01 02:01:04 +0000564 indexlo = 0;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000565 }
566 return 0;
567}
568
569static long
570deque_nohash(PyObject *self)
571{
572 PyErr_SetString(PyExc_TypeError, "deque objects are unhashable");
573 return -1;
574}
575
576static PyObject *
577deque_copy(PyObject *deque)
578{
Tim Peters1065f752004-10-01 01:03:29 +0000579 return PyObject_CallFunctionObjArgs((PyObject *)(deque->ob_type),
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000580 deque, NULL);
581}
582
583PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque.");
584
585static PyObject *
586deque_reduce(dequeobject *deque)
587{
Raymond Hettinger952f8802004-11-09 07:27:35 +0000588 PyObject *dict, *result, *it;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000589
Raymond Hettinger952f8802004-11-09 07:27:35 +0000590 dict = PyObject_GetAttrString((PyObject *)deque, "__dict__");
591 if (dict == NULL) {
592 PyErr_Clear();
593 dict = Py_None;
594 Py_INCREF(dict);
595 }
596 it = PyObject_GetIter((PyObject *)deque);
597 if (it == NULL) {
598 Py_DECREF(dict);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000599 return NULL;
600 }
Raymond Hettinger952f8802004-11-09 07:27:35 +0000601 result = Py_BuildValue("O()ON", deque->ob_type, dict, it);
602 Py_DECREF(dict);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000603 return result;
604}
605
606PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
607
608static PyObject *
609deque_repr(PyObject *deque)
610{
611 PyObject *aslist, *result, *fmt;
612 int i;
613
614 i = Py_ReprEnter(deque);
615 if (i != 0) {
616 if (i < 0)
617 return NULL;
618 return PyString_FromString("[...]");
619 }
620
621 aslist = PySequence_List(deque);
622 if (aslist == NULL) {
623 Py_ReprLeave(deque);
624 return NULL;
625 }
626
627 fmt = PyString_FromString("deque(%r)");
628 if (fmt == NULL) {
629 Py_DECREF(aslist);
630 Py_ReprLeave(deque);
631 return NULL;
632 }
633 result = PyString_Format(fmt, aslist);
634 Py_DECREF(fmt);
635 Py_DECREF(aslist);
636 Py_ReprLeave(deque);
637 return result;
638}
639
640static int
641deque_tp_print(PyObject *deque, FILE *fp, int flags)
642{
643 PyObject *it, *item;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000644 char *emit = ""; /* No separator emitted on first pass */
645 char *separator = ", ";
646 int i;
647
648 i = Py_ReprEnter(deque);
649 if (i != 0) {
650 if (i < 0)
651 return i;
652 fputs("[...]", fp);
653 return 0;
654 }
655
656 it = PyObject_GetIter(deque);
657 if (it == NULL)
658 return -1;
659
660 fputs("deque([", fp);
661 while ((item = PyIter_Next(it)) != NULL) {
662 fputs(emit, fp);
663 emit = separator;
664 if (PyObject_Print(item, fp, 0) != 0) {
665 Py_DECREF(item);
666 Py_DECREF(it);
667 Py_ReprLeave(deque);
668 return -1;
669 }
670 Py_DECREF(item);
671 }
672 Py_ReprLeave(deque);
673 Py_DECREF(it);
Tim Peters1065f752004-10-01 01:03:29 +0000674 if (PyErr_Occurred())
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000675 return -1;
676 fputs("])", fp);
677 return 0;
678}
679
Raymond Hettinger738ec902004-02-29 02:15:56 +0000680static PyObject *
681deque_richcompare(PyObject *v, PyObject *w, int op)
682{
683 PyObject *it1=NULL, *it2=NULL, *x, *y;
Armin Rigo974d7572004-10-02 13:59:34 +0000684 int b, vs, ws, cmp=-1;
Raymond Hettinger738ec902004-02-29 02:15:56 +0000685
Tim Peters1065f752004-10-01 01:03:29 +0000686 if (!PyObject_TypeCheck(v, &deque_type) ||
Raymond Hettinger285cfcc2004-05-18 18:15:03 +0000687 !PyObject_TypeCheck(w, &deque_type)) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000688 Py_INCREF(Py_NotImplemented);
689 return Py_NotImplemented;
690 }
691
692 /* Shortcuts */
693 vs = ((dequeobject *)v)->len;
694 ws = ((dequeobject *)w)->len;
695 if (op == Py_EQ) {
696 if (v == w)
697 Py_RETURN_TRUE;
698 if (vs != ws)
699 Py_RETURN_FALSE;
700 }
701 if (op == Py_NE) {
702 if (v == w)
703 Py_RETURN_FALSE;
704 if (vs != ws)
705 Py_RETURN_TRUE;
706 }
707
708 /* Search for the first index where items are different */
709 it1 = PyObject_GetIter(v);
710 if (it1 == NULL)
711 goto done;
712 it2 = PyObject_GetIter(w);
713 if (it2 == NULL)
714 goto done;
Armin Rigo974d7572004-10-02 13:59:34 +0000715 for (;;) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000716 x = PyIter_Next(it1);
Armin Rigo974d7572004-10-02 13:59:34 +0000717 if (x == NULL && PyErr_Occurred())
Raymond Hettinger738ec902004-02-29 02:15:56 +0000718 goto done;
719 y = PyIter_Next(it2);
Armin Rigo974d7572004-10-02 13:59:34 +0000720 if (x == NULL || y == NULL)
721 break;
Raymond Hettinger738ec902004-02-29 02:15:56 +0000722 b = PyObject_RichCompareBool(x, y, Py_EQ);
723 if (b == 0) {
724 cmp = PyObject_RichCompareBool(x, y, op);
725 Py_DECREF(x);
726 Py_DECREF(y);
727 goto done;
728 }
729 Py_DECREF(x);
730 Py_DECREF(y);
731 if (b == -1)
732 goto done;
733 }
Armin Rigo974d7572004-10-02 13:59:34 +0000734 /* We reached the end of one deque or both */
735 Py_XDECREF(x);
736 Py_XDECREF(y);
737 if (PyErr_Occurred())
738 goto done;
Raymond Hettinger738ec902004-02-29 02:15:56 +0000739 switch (op) {
Armin Rigo974d7572004-10-02 13:59:34 +0000740 case Py_LT: cmp = y != NULL; break; /* if w was longer */
741 case Py_LE: cmp = x == NULL; break; /* if v was not longer */
742 case Py_EQ: cmp = x == y; break; /* if we reached the end of both */
743 case Py_NE: cmp = x != y; break; /* if one deque continues */
744 case Py_GT: cmp = x != NULL; break; /* if v was longer */
745 case Py_GE: cmp = y == NULL; break; /* if w was not longer */
Raymond Hettinger738ec902004-02-29 02:15:56 +0000746 }
Tim Peters1065f752004-10-01 01:03:29 +0000747
Raymond Hettinger738ec902004-02-29 02:15:56 +0000748done:
749 Py_XDECREF(it1);
750 Py_XDECREF(it2);
751 if (cmp == 1)
752 Py_RETURN_TRUE;
753 if (cmp == 0)
754 Py_RETURN_FALSE;
755 return NULL;
756}
757
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000758static int
759deque_init(dequeobject *deque, PyObject *args, PyObject *kwds)
760{
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000761 PyObject *iterable = NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000762
763 if (!PyArg_UnpackTuple(args, "deque", 0, 1, &iterable))
764 return -1;
765
766 if (iterable != NULL) {
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000767 PyObject *rv = deque_extend(deque, iterable);
768 if (rv == NULL)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000769 return -1;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000770 Py_DECREF(rv);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000771 }
772 return 0;
773}
774
775static PySequenceMethods deque_as_sequence = {
776 (inquiry)deque_len, /* sq_length */
777 0, /* sq_concat */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000778 0, /* sq_repeat */
779 (intargfunc)deque_item, /* sq_item */
780 0, /* sq_slice */
781 (intobjargproc)deque_ass_item, /* sq_ass_item */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000782};
783
784/* deque object ********************************************************/
785
786static PyObject *deque_iter(dequeobject *deque);
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000787static PyObject *deque_reviter(dequeobject *deque);
Tim Peters1065f752004-10-01 01:03:29 +0000788PyDoc_STRVAR(reversed_doc,
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000789 "D.__reversed__() -- return a reverse iterator over the deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000790
791static PyMethodDef deque_methods[] = {
Tim Peters1065f752004-10-01 01:03:29 +0000792 {"append", (PyCFunction)deque_append,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000793 METH_O, append_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000794 {"appendleft", (PyCFunction)deque_appendleft,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000795 METH_O, appendleft_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000796 {"clear", (PyCFunction)deque_clearmethod,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000797 METH_NOARGS, clear_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000798 {"__copy__", (PyCFunction)deque_copy,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000799 METH_NOARGS, copy_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000800 {"extend", (PyCFunction)deque_extend,
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000801 METH_O, extend_doc},
Raymond Hettinger4aec61e2005-03-18 21:20:23 +0000802 {"extendleft", (PyCFunction)deque_extendleft,
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000803 METH_O, extendleft_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000804 {"pop", (PyCFunction)deque_pop,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000805 METH_NOARGS, pop_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000806 {"popleft", (PyCFunction)deque_popleft,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000807 METH_NOARGS, popleft_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000808 {"__reduce__", (PyCFunction)deque_reduce,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000809 METH_NOARGS, reduce_doc},
Raymond Hettinger4aec61e2005-03-18 21:20:23 +0000810 {"remove", (PyCFunction)deque_remove,
811 METH_O, remove_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000812 {"__reversed__", (PyCFunction)deque_reviter,
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000813 METH_NOARGS, reversed_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000814 {"rotate", (PyCFunction)deque_rotate,
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000815 METH_VARARGS, rotate_doc},
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000816 {NULL, NULL} /* sentinel */
817};
818
819PyDoc_STRVAR(deque_doc,
820"deque(iterable) --> deque object\n\
821\n\
822Build an ordered collection accessible from endpoints only.");
823
Neal Norwitz87f10132004-02-29 15:40:53 +0000824static PyTypeObject deque_type = {
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000825 PyObject_HEAD_INIT(NULL)
826 0, /* ob_size */
827 "collections.deque", /* tp_name */
828 sizeof(dequeobject), /* tp_basicsize */
829 0, /* tp_itemsize */
830 /* methods */
831 (destructor)deque_dealloc, /* tp_dealloc */
832 (printfunc)deque_tp_print, /* tp_print */
833 0, /* tp_getattr */
834 0, /* tp_setattr */
835 0, /* tp_compare */
836 (reprfunc)deque_repr, /* tp_repr */
837 0, /* tp_as_number */
838 &deque_as_sequence, /* tp_as_sequence */
839 0, /* tp_as_mapping */
840 deque_nohash, /* tp_hash */
841 0, /* tp_call */
842 0, /* tp_str */
843 PyObject_GenericGetAttr, /* tp_getattro */
844 0, /* tp_setattro */
845 0, /* tp_as_buffer */
Raymond Hettinger691d8052004-05-30 07:26:47 +0000846 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
847 Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000848 deque_doc, /* tp_doc */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000849 (traverseproc)deque_traverse, /* tp_traverse */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000850 (inquiry)deque_clear, /* tp_clear */
Raymond Hettinger738ec902004-02-29 02:15:56 +0000851 (richcmpfunc)deque_richcompare, /* tp_richcompare */
Raymond Hettinger691d8052004-05-30 07:26:47 +0000852 offsetof(dequeobject, weakreflist), /* tp_weaklistoffset*/
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000853 (getiterfunc)deque_iter, /* tp_iter */
854 0, /* tp_iternext */
855 deque_methods, /* tp_methods */
856 0, /* tp_members */
857 0, /* tp_getset */
858 0, /* tp_base */
859 0, /* tp_dict */
860 0, /* tp_descr_get */
861 0, /* tp_descr_set */
862 0, /* tp_dictoffset */
863 (initproc)deque_init, /* tp_init */
864 PyType_GenericAlloc, /* tp_alloc */
865 deque_new, /* tp_new */
866 PyObject_GC_Del, /* tp_free */
867};
868
869/*********************** Deque Iterator **************************/
870
871typedef struct {
872 PyObject_HEAD
873 int index;
874 block *b;
875 dequeobject *deque;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000876 long state; /* state when the iterator is created */
877 int counter; /* number of items remaining for iteration */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000878} dequeiterobject;
879
880PyTypeObject dequeiter_type;
881
882static PyObject *
883deque_iter(dequeobject *deque)
884{
885 dequeiterobject *it;
886
887 it = PyObject_New(dequeiterobject, &dequeiter_type);
888 if (it == NULL)
889 return NULL;
890 it->b = deque->leftblock;
891 it->index = deque->leftindex;
892 Py_INCREF(deque);
893 it->deque = deque;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000894 it->state = deque->state;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000895 it->counter = deque->len;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000896 return (PyObject *)it;
897}
898
899static void
900dequeiter_dealloc(dequeiterobject *dio)
901{
902 Py_XDECREF(dio->deque);
903 dio->ob_type->tp_free(dio);
904}
905
906static PyObject *
907dequeiter_next(dequeiterobject *it)
908{
909 PyObject *item;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000910
911 if (it->counter == 0)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000912 return NULL;
913
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000914 if (it->deque->state != it->state) {
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000915 it->counter = 0;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000916 PyErr_SetString(PyExc_RuntimeError,
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000917 "deque mutated during iteration");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000918 return NULL;
919 }
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000920 assert (!(it->b == it->deque->rightblock &&
921 it->index > it->deque->rightindex));
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000922
923 item = it->b->data[it->index];
924 it->index++;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000925 it->counter--;
926 if (it->index == BLOCKLEN && it->counter > 0) {
927 assert (it->b->rightlink != NULL);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000928 it->b = it->b->rightlink;
929 it->index = 0;
930 }
931 Py_INCREF(item);
932 return item;
933}
934
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000935static int
936dequeiter_len(dequeiterobject *it)
937{
938 return it->counter;
939}
940
941static PySequenceMethods dequeiter_as_sequence = {
942 (inquiry)dequeiter_len, /* sq_length */
943 0, /* sq_concat */
944};
945
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000946PyTypeObject dequeiter_type = {
947 PyObject_HEAD_INIT(NULL)
948 0, /* ob_size */
949 "deque_iterator", /* tp_name */
950 sizeof(dequeiterobject), /* tp_basicsize */
951 0, /* tp_itemsize */
952 /* methods */
953 (destructor)dequeiter_dealloc, /* tp_dealloc */
954 0, /* tp_print */
955 0, /* tp_getattr */
956 0, /* tp_setattr */
957 0, /* tp_compare */
958 0, /* tp_repr */
959 0, /* tp_as_number */
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000960 &dequeiter_as_sequence, /* tp_as_sequence */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000961 0, /* tp_as_mapping */
962 0, /* tp_hash */
963 0, /* tp_call */
964 0, /* tp_str */
965 PyObject_GenericGetAttr, /* tp_getattro */
966 0, /* tp_setattro */
967 0, /* tp_as_buffer */
968 Py_TPFLAGS_DEFAULT, /* tp_flags */
969 0, /* tp_doc */
970 0, /* tp_traverse */
971 0, /* tp_clear */
972 0, /* tp_richcompare */
973 0, /* tp_weaklistoffset */
974 PyObject_SelfIter, /* tp_iter */
975 (iternextfunc)dequeiter_next, /* tp_iternext */
976 0,
977};
978
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000979/*********************** Deque Reverse Iterator **************************/
980
981PyTypeObject dequereviter_type;
982
983static PyObject *
984deque_reviter(dequeobject *deque)
985{
986 dequeiterobject *it;
987
988 it = PyObject_New(dequeiterobject, &dequereviter_type);
989 if (it == NULL)
990 return NULL;
991 it->b = deque->rightblock;
992 it->index = deque->rightindex;
993 Py_INCREF(deque);
994 it->deque = deque;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +0000995 it->state = deque->state;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000996 it->counter = deque->len;
997 return (PyObject *)it;
998}
999
1000static PyObject *
1001dequereviter_next(dequeiterobject *it)
1002{
1003 PyObject *item;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +00001004 if (it->counter == 0)
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001005 return NULL;
1006
Raymond Hettingerd1b3d882004-10-02 00:43:13 +00001007 if (it->deque->state != it->state) {
Raymond Hettinger7892b1c2004-04-12 18:10:01 +00001008 it->counter = 0;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001009 PyErr_SetString(PyExc_RuntimeError,
Raymond Hettingerd1b3d882004-10-02 00:43:13 +00001010 "deque mutated during iteration");
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001011 return NULL;
1012 }
Raymond Hettingerd1b3d882004-10-02 00:43:13 +00001013 assert (!(it->b == it->deque->leftblock &&
1014 it->index < it->deque->leftindex));
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001015
1016 item = it->b->data[it->index];
1017 it->index--;
Raymond Hettingerd1b3d882004-10-02 00:43:13 +00001018 it->counter--;
1019 if (it->index == -1 && it->counter > 0) {
1020 assert (it->b->leftlink != NULL);
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001021 it->b = it->b->leftlink;
1022 it->index = BLOCKLEN - 1;
1023 }
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001024 Py_INCREF(item);
1025 return item;
1026}
1027
1028PyTypeObject dequereviter_type = {
1029 PyObject_HEAD_INIT(NULL)
1030 0, /* ob_size */
1031 "deque_reverse_iterator", /* tp_name */
1032 sizeof(dequeiterobject), /* tp_basicsize */
1033 0, /* tp_itemsize */
1034 /* methods */
1035 (destructor)dequeiter_dealloc, /* tp_dealloc */
1036 0, /* tp_print */
1037 0, /* tp_getattr */
1038 0, /* tp_setattr */
1039 0, /* tp_compare */
1040 0, /* tp_repr */
1041 0, /* tp_as_number */
1042 &dequeiter_as_sequence, /* tp_as_sequence */
1043 0, /* tp_as_mapping */
1044 0, /* tp_hash */
1045 0, /* tp_call */
1046 0, /* tp_str */
1047 PyObject_GenericGetAttr, /* tp_getattro */
1048 0, /* tp_setattro */
1049 0, /* tp_as_buffer */
1050 Py_TPFLAGS_DEFAULT, /* tp_flags */
1051 0, /* tp_doc */
1052 0, /* tp_traverse */
1053 0, /* tp_clear */
1054 0, /* tp_richcompare */
1055 0, /* tp_weaklistoffset */
1056 PyObject_SelfIter, /* tp_iter */
1057 (iternextfunc)dequereviter_next, /* tp_iternext */
1058 0,
1059};
1060
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001061/* module level code ********************************************************/
1062
1063PyDoc_STRVAR(module_doc,
1064"High performance data structures\n\
1065");
1066
1067PyMODINIT_FUNC
1068initcollections(void)
1069{
1070 PyObject *m;
1071
1072 m = Py_InitModule3("collections", NULL, module_doc);
1073
1074 if (PyType_Ready(&deque_type) < 0)
1075 return;
1076 Py_INCREF(&deque_type);
1077 PyModule_AddObject(m, "deque", (PyObject *)&deque_type);
1078
1079 if (PyType_Ready(&dequeiter_type) < 0)
Tim Peters1065f752004-10-01 01:03:29 +00001080 return;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001081
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001082 if (PyType_Ready(&dequereviter_type) < 0)
1083 return;
1084
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001085 return;
1086}