blob: 8461acea851b2f0487749558c26ef2eb17548b7c [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
10#define BLOCKLEN 46
11
12typedef struct BLOCK {
13 struct BLOCK *leftlink;
14 struct BLOCK *rightlink;
15 PyObject *data[BLOCKLEN];
16} block;
17
18static block *newblock(block *leftlink, block *rightlink) {
19 block *b = PyMem_Malloc(sizeof(block));
20 if (b == NULL) {
21 PyErr_NoMemory();
22 return NULL;
23 }
24 b->leftlink = leftlink;
25 b->rightlink = rightlink;
26 return b;
27}
28
29typedef struct {
30 PyObject_HEAD
31 block *leftblock;
32 block *rightblock;
33 int leftindex;
34 int rightindex;
35 int len;
Raymond Hettinger691d8052004-05-30 07:26:47 +000036 PyObject *weakreflist; /* List of weak references */
Raymond Hettinger756b3f32004-01-29 06:37:52 +000037} dequeobject;
38
Neal Norwitz87f10132004-02-29 15:40:53 +000039static PyTypeObject deque_type;
Raymond Hettinger738ec902004-02-29 02:15:56 +000040
Raymond Hettinger756b3f32004-01-29 06:37:52 +000041static PyObject *
42deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
43{
44 dequeobject *deque;
45 block *b;
46
47 /* create dequeobject structure */
48 deque = (dequeobject *)type->tp_alloc(type, 0);
49 if (deque == NULL)
50 return NULL;
51
52 b = newblock(NULL, NULL);
53 if (b == NULL) {
54 Py_DECREF(deque);
55 return NULL;
56 }
57
58 deque->leftblock = b;
59 deque->rightblock = b;
60 deque->leftindex = BLOCKLEN / 2 + 1;
61 deque->rightindex = BLOCKLEN / 2;
62 deque->len = 0;
Raymond Hettinger691d8052004-05-30 07:26:47 +000063 deque->weakreflist = NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +000064
65 return (PyObject *)deque;
66}
67
68static PyObject *
69deque_append(dequeobject *deque, PyObject *item)
70{
71 deque->rightindex++;
72 deque->len++;
73 if (deque->rightindex == BLOCKLEN) {
74 block *b = newblock(deque->rightblock, NULL);
75 if (b == NULL)
76 return NULL;
77 assert(deque->rightblock->rightlink == NULL);
78 deque->rightblock->rightlink = b;
79 deque->rightblock = b;
80 deque->rightindex = 0;
81 }
82 Py_INCREF(item);
83 deque->rightblock->data[deque->rightindex] = item;
84 Py_RETURN_NONE;
85}
86
87PyDoc_STRVAR(append_doc, "Add an element to the right side of the deque.");
88
89static PyObject *
90deque_appendleft(dequeobject *deque, PyObject *item)
91{
92 deque->leftindex--;
93 deque->len++;
94 if (deque->leftindex == -1) {
95 block *b = newblock(NULL, deque->leftblock);
96 if (b == NULL)
97 return NULL;
98 assert(deque->leftblock->leftlink == NULL);
99 deque->leftblock->leftlink = b;
100 deque->leftblock = b;
101 deque->leftindex = BLOCKLEN - 1;
102 }
103 Py_INCREF(item);
104 deque->leftblock->data[deque->leftindex] = item;
105 Py_RETURN_NONE;
106}
107
108PyDoc_STRVAR(appendleft_doc, "Add an element to the left side of the deque.");
109
110static PyObject *
111deque_pop(dequeobject *deque, PyObject *unused)
112{
113 PyObject *item;
114 block *prevblock;
115
116 if (deque->len == 0) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000117 PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000118 return NULL;
119 }
120 item = deque->rightblock->data[deque->rightindex];
121 deque->rightindex--;
122 deque->len--;
123
124 if (deque->rightindex == -1) {
125 if (deque->len == 0) {
126 assert(deque->leftblock == deque->rightblock);
127 assert(deque->leftindex == deque->rightindex+1);
128 /* re-center instead of freeing a block */
129 deque->leftindex = BLOCKLEN / 2 + 1;
130 deque->rightindex = BLOCKLEN / 2;
131 } else {
132 prevblock = deque->rightblock->leftlink;
133 assert(deque->leftblock != deque->rightblock);
134 PyMem_Free(deque->rightblock);
135 prevblock->rightlink = NULL;
136 deque->rightblock = prevblock;
137 deque->rightindex = BLOCKLEN - 1;
138 }
139 }
140 return item;
141}
142
143PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element.");
144
145static PyObject *
146deque_popleft(dequeobject *deque, PyObject *unused)
147{
148 PyObject *item;
149 block *prevblock;
150
151 if (deque->len == 0) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000152 PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000153 return NULL;
154 }
155 item = deque->leftblock->data[deque->leftindex];
156 deque->leftindex++;
157 deque->len--;
158
159 if (deque->leftindex == BLOCKLEN) {
160 if (deque->len == 0) {
161 assert(deque->leftblock == deque->rightblock);
162 assert(deque->leftindex == deque->rightindex+1);
163 /* re-center instead of freeing a block */
164 deque->leftindex = BLOCKLEN / 2 + 1;
165 deque->rightindex = BLOCKLEN / 2;
166 } else {
167 assert(deque->leftblock != deque->rightblock);
168 prevblock = deque->leftblock->rightlink;
169 assert(deque->leftblock != NULL);
170 PyMem_Free(deque->leftblock);
171 assert(prevblock != NULL);
172 prevblock->leftlink = NULL;
173 deque->leftblock = prevblock;
174 deque->leftindex = 0;
175 }
176 }
177 return item;
178}
179
180PyDoc_STRVAR(popleft_doc, "Remove and return the leftmost element.");
181
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000182static PyObject *
183deque_extend(dequeobject *deque, PyObject *iterable)
184{
185 PyObject *it, *item;
186
187 it = PyObject_GetIter(iterable);
188 if (it == NULL)
189 return NULL;
190
191 while ((item = PyIter_Next(it)) != NULL) {
192 deque->rightindex++;
193 deque->len++;
194 if (deque->rightindex == BLOCKLEN) {
195 block *b = newblock(deque->rightblock, NULL);
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000196 if (b == NULL) {
197 Py_DECREF(item);
198 Py_DECREF(it);
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000199 return NULL;
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000200 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000201 assert(deque->rightblock->rightlink == NULL);
202 deque->rightblock->rightlink = b;
203 deque->rightblock = b;
204 deque->rightindex = 0;
205 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000206 deque->rightblock->data[deque->rightindex] = item;
207 }
208 Py_DECREF(it);
209 if (PyErr_Occurred())
210 return NULL;
211 Py_RETURN_NONE;
212}
213
214PyDoc_STRVAR(extend_doc,
215"Extend the right side of the deque with elements from the iterable");
216
217static PyObject *
218deque_extendleft(dequeobject *deque, PyObject *iterable)
219{
220 PyObject *it, *item;
221
222 it = PyObject_GetIter(iterable);
223 if (it == NULL)
224 return NULL;
225
226 while ((item = PyIter_Next(it)) != NULL) {
227 deque->leftindex--;
228 deque->len++;
229 if (deque->leftindex == -1) {
230 block *b = newblock(NULL, deque->leftblock);
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000231 if (b == NULL) {
232 Py_DECREF(item);
233 Py_DECREF(it);
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000234 return NULL;
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000235 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000236 assert(deque->leftblock->leftlink == NULL);
237 deque->leftblock->leftlink = b;
238 deque->leftblock = b;
239 deque->leftindex = BLOCKLEN - 1;
240 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000241 deque->leftblock->data[deque->leftindex] = item;
242 }
243 Py_DECREF(it);
Raymond Hettingera435c532004-07-09 04:10:20 +0000244 if (PyErr_Occurred())
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000245 return NULL;
246 Py_RETURN_NONE;
247}
248
249PyDoc_STRVAR(extendleft_doc,
250"Extend the left side of the deque with elements from the iterable");
251
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000252static PyObject *
253deque_rotate(dequeobject *deque, PyObject *args)
254{
Raymond Hettingeree33b272004-02-08 04:05:26 +0000255 int i, n=1, len=deque->len, halflen=(len+1)>>1;
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000256 PyObject *item, *rv;
257
Raymond Hettingeree33b272004-02-08 04:05:26 +0000258 if (!PyArg_ParseTuple(args, "|i:rotate", &n))
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000259 return NULL;
260
Raymond Hettingeree33b272004-02-08 04:05:26 +0000261 if (len == 0)
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000262 Py_RETURN_NONE;
Raymond Hettingeree33b272004-02-08 04:05:26 +0000263 if (n > halflen || n < -halflen) {
264 n %= len;
265 if (n > halflen)
266 n -= len;
267 else if (n < -halflen)
268 n += len;
269 }
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000270
271 for (i=0 ; i<n ; i++) {
272 item = deque_pop(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000273 assert (item != NULL);
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000274 rv = deque_appendleft(deque, item);
275 Py_DECREF(item);
276 if (rv == NULL)
277 return NULL;
278 Py_DECREF(rv);
279 }
280 for (i=0 ; i>n ; i--) {
281 item = deque_popleft(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000282 assert (item != NULL);
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000283 rv = deque_append(deque, item);
284 Py_DECREF(item);
285 if (rv == NULL)
286 return NULL;
287 Py_DECREF(rv);
288 }
289 Py_RETURN_NONE;
290}
291
292PyDoc_STRVAR(rotate_doc,
Raymond Hettingeree33b272004-02-08 04:05:26 +0000293"Rotate the deque n steps to the right (default n=1). If n is negative, rotates left.");
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000294
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000295static int
296deque_len(dequeobject *deque)
297{
298 return deque->len;
299}
300
301static int
302deque_clear(dequeobject *deque)
303{
304 PyObject *item;
305
306 while (deque_len(deque)) {
307 item = deque_pop(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000308 assert (item != NULL);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000309 Py_DECREF(item);
310 }
311 assert(deque->leftblock == deque->rightblock &&
312 deque->leftindex > deque->rightindex);
313 return 0;
314}
315
316static PyObject *
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000317deque_item(dequeobject *deque, int i)
318{
319 block *b;
320 PyObject *item;
321 int n;
322
323 if (i < 0 || i >= deque->len) {
324 PyErr_SetString(PyExc_IndexError,
325 "deque index out of range");
326 return NULL;
327 }
328
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000329 if (i == 0) {
330 i = deque->leftindex;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000331 b = deque->leftblock;
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000332 } else if (i == deque->len - 1) {
333 i = deque->rightindex;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000334 b = deque->rightblock;
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000335 } else {
336 i += deque->leftindex;
337 n = i / BLOCKLEN;
338 i %= BLOCKLEN;
339 if (i < (deque->len >> 1)) {
340 b = deque->leftblock;
341 while (n--)
342 b = b->rightlink;
343 } else {
344 n = (deque->leftindex + deque->len - 1) / BLOCKLEN - n;
345 b = deque->rightblock;
346 while (n--)
347 b = b->leftlink;
348 }
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000349 }
350 item = b->data[i];
351 Py_INCREF(item);
352 return item;
353}
354
Raymond Hettinger616f4f62004-06-26 04:42:06 +0000355/* delitem() implemented in terms of rotate for simplicity and reasonable
356 performance near the end points. If for some reason this method becomes
357 popular, it is not hard to re-implement this using direct data movement
358 (similar to code in list slice assignment) and achieve a two or threefold
359 performance boost.
360*/
361
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000362static int
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000363deque_del_item(dequeobject *deque, int i)
364{
365 PyObject *item=NULL, *minus_i=NULL, *plus_i=NULL;
366 int rv = -1;
367
368 assert (i >= 0 && i < deque->len);
369
370 minus_i = Py_BuildValue("(i)", -i);
371 if (minus_i == NULL)
372 goto fail;
373
374 plus_i = Py_BuildValue("(i)", i);
375 if (plus_i == NULL)
376 goto fail;
377
378 item = deque_rotate(deque, minus_i);
379 if (item == NULL)
380 goto fail;
381 Py_DECREF(item);
382
383 item = deque_popleft(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000384 assert (item != NULL);
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000385 Py_DECREF(item);
386
387 item = deque_rotate(deque, plus_i);
388 if (item == NULL)
389 goto fail;
390
391 rv = 0;
392fail:
393 Py_XDECREF(item);
394 Py_XDECREF(minus_i);
395 Py_XDECREF(plus_i);
396 return rv;
397}
398
399static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000400deque_ass_item(dequeobject *deque, int i, PyObject *v)
401{
402 PyObject *old_value;
403 block *b;
Raymond Hettingera435c532004-07-09 04:10:20 +0000404 int n, len=deque->len, halflen=(len+1)>>1, index=i;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000405
Raymond Hettingera435c532004-07-09 04:10:20 +0000406 if (i < 0 || i >= len) {
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000407 PyErr_SetString(PyExc_IndexError,
408 "deque index out of range");
409 return -1;
410 }
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000411 if (v == NULL)
412 return deque_del_item(deque, i);
413
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000414 i += deque->leftindex;
415 n = i / BLOCKLEN;
416 i %= BLOCKLEN;
Raymond Hettingera435c532004-07-09 04:10:20 +0000417 if (index <= halflen) {
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000418 b = deque->leftblock;
419 while (n--)
420 b = b->rightlink;
421 } else {
Raymond Hettingera435c532004-07-09 04:10:20 +0000422 n = (deque->leftindex + len - 1) / BLOCKLEN - n;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000423 b = deque->rightblock;
424 while (n--)
425 b = b->leftlink;
426 }
427 Py_INCREF(v);
428 old_value = b->data[i];
429 b->data[i] = v;
430 Py_DECREF(old_value);
431 return 0;
432}
433
434static PyObject *
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000435deque_clearmethod(dequeobject *deque)
436{
Raymond Hettingera435c532004-07-09 04:10:20 +0000437 int rv;
438
439 rv = deque_clear(deque);
440 assert (rv != -1);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000441 Py_RETURN_NONE;
442}
443
444PyDoc_STRVAR(clear_doc, "Remove all elements from the deque.");
445
446static void
447deque_dealloc(dequeobject *deque)
448{
449 PyObject_GC_UnTrack(deque);
Raymond Hettinger691d8052004-05-30 07:26:47 +0000450 if (deque->weakreflist != NULL)
451 PyObject_ClearWeakRefs((PyObject *) deque);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000452 if (deque->leftblock != NULL) {
Raymond Hettingere9c89e82004-07-19 00:10:24 +0000453 deque_clear(deque);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000454 assert(deque->leftblock != NULL);
455 PyMem_Free(deque->leftblock);
456 }
457 deque->leftblock = NULL;
458 deque->rightblock = NULL;
459 deque->ob_type->tp_free(deque);
460}
461
462static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000463deque_traverse(dequeobject *deque, visitproc visit, void *arg)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000464{
465 block * b = deque->leftblock;
466 int index = deque->leftindex;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000467 PyObject *item;
468
469 while (b != deque->rightblock || index <= deque->rightindex) {
470 item = b->data[index];
471 index++;
Raymond Hettinger67115a22004-07-15 21:32:18 +0000472 if (index == BLOCKLEN ) {
473 assert(b->rightlink != NULL);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000474 b = b->rightlink;
475 index = 0;
476 }
Raymond Hettinger67115a22004-07-15 21:32:18 +0000477 Py_VISIT(item);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000478 }
479 return 0;
480}
481
482static long
483deque_nohash(PyObject *self)
484{
485 PyErr_SetString(PyExc_TypeError, "deque objects are unhashable");
486 return -1;
487}
488
489static PyObject *
490deque_copy(PyObject *deque)
491{
492 return PyObject_CallFunctionObjArgs((PyObject *)(deque->ob_type),
493 deque, NULL);
494}
495
496PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque.");
497
498static PyObject *
499deque_reduce(dequeobject *deque)
500{
501 PyObject *seq, *args, *result;
502
503 seq = PySequence_Tuple((PyObject *)deque);
504 if (seq == NULL)
505 return NULL;
506 args = PyTuple_Pack(1, seq);
507 if (args == NULL) {
508 Py_DECREF(seq);
509 return NULL;
510 }
511 result = PyTuple_Pack(2, deque->ob_type, args);
512 Py_DECREF(seq);
513 Py_DECREF(args);
514 return result;
515}
516
517PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
518
519static PyObject *
520deque_repr(PyObject *deque)
521{
522 PyObject *aslist, *result, *fmt;
523 int i;
524
525 i = Py_ReprEnter(deque);
526 if (i != 0) {
527 if (i < 0)
528 return NULL;
529 return PyString_FromString("[...]");
530 }
531
532 aslist = PySequence_List(deque);
533 if (aslist == NULL) {
534 Py_ReprLeave(deque);
535 return NULL;
536 }
537
538 fmt = PyString_FromString("deque(%r)");
539 if (fmt == NULL) {
540 Py_DECREF(aslist);
541 Py_ReprLeave(deque);
542 return NULL;
543 }
544 result = PyString_Format(fmt, aslist);
545 Py_DECREF(fmt);
546 Py_DECREF(aslist);
547 Py_ReprLeave(deque);
548 return result;
549}
550
551static int
552deque_tp_print(PyObject *deque, FILE *fp, int flags)
553{
554 PyObject *it, *item;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000555 char *emit = ""; /* No separator emitted on first pass */
556 char *separator = ", ";
557 int i;
558
559 i = Py_ReprEnter(deque);
560 if (i != 0) {
561 if (i < 0)
562 return i;
563 fputs("[...]", fp);
564 return 0;
565 }
566
567 it = PyObject_GetIter(deque);
568 if (it == NULL)
569 return -1;
570
571 fputs("deque([", fp);
572 while ((item = PyIter_Next(it)) != NULL) {
573 fputs(emit, fp);
574 emit = separator;
575 if (PyObject_Print(item, fp, 0) != 0) {
576 Py_DECREF(item);
577 Py_DECREF(it);
578 Py_ReprLeave(deque);
579 return -1;
580 }
581 Py_DECREF(item);
582 }
583 Py_ReprLeave(deque);
584 Py_DECREF(it);
585 if (PyErr_Occurred())
586 return -1;
587 fputs("])", fp);
588 return 0;
589}
590
Raymond Hettinger738ec902004-02-29 02:15:56 +0000591static PyObject *
592deque_richcompare(PyObject *v, PyObject *w, int op)
593{
594 PyObject *it1=NULL, *it2=NULL, *x, *y;
595 int i, b, vs, ws, minlen, cmp=-1;
596
Raymond Hettinger285cfcc2004-05-18 18:15:03 +0000597 if (!PyObject_TypeCheck(v, &deque_type) ||
598 !PyObject_TypeCheck(w, &deque_type)) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000599 Py_INCREF(Py_NotImplemented);
600 return Py_NotImplemented;
601 }
602
603 /* Shortcuts */
604 vs = ((dequeobject *)v)->len;
605 ws = ((dequeobject *)w)->len;
606 if (op == Py_EQ) {
607 if (v == w)
608 Py_RETURN_TRUE;
609 if (vs != ws)
610 Py_RETURN_FALSE;
611 }
612 if (op == Py_NE) {
613 if (v == w)
614 Py_RETURN_FALSE;
615 if (vs != ws)
616 Py_RETURN_TRUE;
617 }
618
619 /* Search for the first index where items are different */
620 it1 = PyObject_GetIter(v);
621 if (it1 == NULL)
622 goto done;
623 it2 = PyObject_GetIter(w);
624 if (it2 == NULL)
625 goto done;
626 minlen = (vs < ws) ? vs : ws;
627 for (i=0 ; i < minlen ; i++) {
628 x = PyIter_Next(it1);
629 if (x == NULL)
630 goto done;
631 y = PyIter_Next(it2);
632 if (y == NULL) {
633 Py_DECREF(x);
634 goto done;
635 }
636 b = PyObject_RichCompareBool(x, y, Py_EQ);
637 if (b == 0) {
638 cmp = PyObject_RichCompareBool(x, y, op);
639 Py_DECREF(x);
640 Py_DECREF(y);
641 goto done;
642 }
643 Py_DECREF(x);
644 Py_DECREF(y);
645 if (b == -1)
646 goto done;
647 }
648 /* Elements are equal through minlen. The longest input is the greatest */
649 switch (op) {
650 case Py_LT: cmp = vs < ws; break;
651 case Py_LE: cmp = vs <= ws; break;
652 case Py_EQ: cmp = vs == ws; break;
653 case Py_NE: cmp = vs != ws; break;
654 case Py_GT: cmp = vs > ws; break;
655 case Py_GE: cmp = vs >= ws; break;
656 }
657
658done:
659 Py_XDECREF(it1);
660 Py_XDECREF(it2);
661 if (cmp == 1)
662 Py_RETURN_TRUE;
663 if (cmp == 0)
664 Py_RETURN_FALSE;
665 return NULL;
666}
667
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000668static int
669deque_init(dequeobject *deque, PyObject *args, PyObject *kwds)
670{
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000671 PyObject *iterable = NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000672
673 if (!PyArg_UnpackTuple(args, "deque", 0, 1, &iterable))
674 return -1;
675
676 if (iterable != NULL) {
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000677 PyObject *rv = deque_extend(deque, iterable);
678 if (rv == NULL)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000679 return -1;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000680 Py_DECREF(rv);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000681 }
682 return 0;
683}
684
685static PySequenceMethods deque_as_sequence = {
686 (inquiry)deque_len, /* sq_length */
687 0, /* sq_concat */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000688 0, /* sq_repeat */
689 (intargfunc)deque_item, /* sq_item */
690 0, /* sq_slice */
691 (intobjargproc)deque_ass_item, /* sq_ass_item */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000692};
693
694/* deque object ********************************************************/
695
696static PyObject *deque_iter(dequeobject *deque);
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000697static PyObject *deque_reviter(dequeobject *deque);
698PyDoc_STRVAR(reversed_doc,
699 "D.__reversed__() -- return a reverse iterator over the deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000700
701static PyMethodDef deque_methods[] = {
702 {"append", (PyCFunction)deque_append,
703 METH_O, append_doc},
704 {"appendleft", (PyCFunction)deque_appendleft,
705 METH_O, appendleft_doc},
706 {"clear", (PyCFunction)deque_clearmethod,
707 METH_NOARGS, clear_doc},
708 {"__copy__", (PyCFunction)deque_copy,
709 METH_NOARGS, copy_doc},
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000710 {"extend", (PyCFunction)deque_extend,
711 METH_O, extend_doc},
712 {"extendleft", (PyCFunction)deque_extendleft,
713 METH_O, extendleft_doc},
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000714 {"pop", (PyCFunction)deque_pop,
715 METH_NOARGS, pop_doc},
716 {"popleft", (PyCFunction)deque_popleft,
717 METH_NOARGS, popleft_doc},
718 {"__reduce__", (PyCFunction)deque_reduce,
719 METH_NOARGS, reduce_doc},
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000720 {"__reversed__", (PyCFunction)deque_reviter,
721 METH_NOARGS, reversed_doc},
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000722 {"rotate", (PyCFunction)deque_rotate,
723 METH_VARARGS, rotate_doc},
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000724 {NULL, NULL} /* sentinel */
725};
726
727PyDoc_STRVAR(deque_doc,
728"deque(iterable) --> deque object\n\
729\n\
730Build an ordered collection accessible from endpoints only.");
731
Neal Norwitz87f10132004-02-29 15:40:53 +0000732static PyTypeObject deque_type = {
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000733 PyObject_HEAD_INIT(NULL)
734 0, /* ob_size */
735 "collections.deque", /* tp_name */
736 sizeof(dequeobject), /* tp_basicsize */
737 0, /* tp_itemsize */
738 /* methods */
739 (destructor)deque_dealloc, /* tp_dealloc */
740 (printfunc)deque_tp_print, /* tp_print */
741 0, /* tp_getattr */
742 0, /* tp_setattr */
743 0, /* tp_compare */
744 (reprfunc)deque_repr, /* tp_repr */
745 0, /* tp_as_number */
746 &deque_as_sequence, /* tp_as_sequence */
747 0, /* tp_as_mapping */
748 deque_nohash, /* tp_hash */
749 0, /* tp_call */
750 0, /* tp_str */
751 PyObject_GenericGetAttr, /* tp_getattro */
752 0, /* tp_setattro */
753 0, /* tp_as_buffer */
Raymond Hettinger691d8052004-05-30 07:26:47 +0000754 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
755 Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000756 deque_doc, /* tp_doc */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000757 (traverseproc)deque_traverse, /* tp_traverse */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000758 (inquiry)deque_clear, /* tp_clear */
Raymond Hettinger738ec902004-02-29 02:15:56 +0000759 (richcmpfunc)deque_richcompare, /* tp_richcompare */
Raymond Hettinger691d8052004-05-30 07:26:47 +0000760 offsetof(dequeobject, weakreflist), /* tp_weaklistoffset*/
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000761 (getiterfunc)deque_iter, /* tp_iter */
762 0, /* tp_iternext */
763 deque_methods, /* tp_methods */
764 0, /* tp_members */
765 0, /* tp_getset */
766 0, /* tp_base */
767 0, /* tp_dict */
768 0, /* tp_descr_get */
769 0, /* tp_descr_set */
770 0, /* tp_dictoffset */
771 (initproc)deque_init, /* tp_init */
772 PyType_GenericAlloc, /* tp_alloc */
773 deque_new, /* tp_new */
774 PyObject_GC_Del, /* tp_free */
775};
776
777/*********************** Deque Iterator **************************/
778
779typedef struct {
780 PyObject_HEAD
781 int index;
782 block *b;
783 dequeobject *deque;
784 int len;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000785 int counter;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000786} dequeiterobject;
787
788PyTypeObject dequeiter_type;
789
790static PyObject *
791deque_iter(dequeobject *deque)
792{
793 dequeiterobject *it;
794
795 it = PyObject_New(dequeiterobject, &dequeiter_type);
796 if (it == NULL)
797 return NULL;
798 it->b = deque->leftblock;
799 it->index = deque->leftindex;
800 Py_INCREF(deque);
801 it->deque = deque;
802 it->len = deque->len;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000803 it->counter = deque->len;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000804 return (PyObject *)it;
805}
806
807static void
808dequeiter_dealloc(dequeiterobject *dio)
809{
810 Py_XDECREF(dio->deque);
811 dio->ob_type->tp_free(dio);
812}
813
814static PyObject *
815dequeiter_next(dequeiterobject *it)
816{
817 PyObject *item;
818 if (it->b == it->deque->rightblock && it->index > it->deque->rightindex)
819 return NULL;
820
821 if (it->len != it->deque->len) {
822 it->len = -1; /* Make this state sticky */
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000823 it->counter = 0;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000824 PyErr_SetString(PyExc_RuntimeError,
825 "deque changed size during iteration");
826 return NULL;
827 }
828
829 item = it->b->data[it->index];
830 it->index++;
831 if (it->index == BLOCKLEN && it->b->rightlink != NULL) {
832 it->b = it->b->rightlink;
833 it->index = 0;
834 }
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000835 it->counter--;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000836 Py_INCREF(item);
837 return item;
838}
839
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000840static int
841dequeiter_len(dequeiterobject *it)
842{
843 return it->counter;
844}
845
846static PySequenceMethods dequeiter_as_sequence = {
847 (inquiry)dequeiter_len, /* sq_length */
848 0, /* sq_concat */
849};
850
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000851PyTypeObject dequeiter_type = {
852 PyObject_HEAD_INIT(NULL)
853 0, /* ob_size */
854 "deque_iterator", /* tp_name */
855 sizeof(dequeiterobject), /* tp_basicsize */
856 0, /* tp_itemsize */
857 /* methods */
858 (destructor)dequeiter_dealloc, /* tp_dealloc */
859 0, /* tp_print */
860 0, /* tp_getattr */
861 0, /* tp_setattr */
862 0, /* tp_compare */
863 0, /* tp_repr */
864 0, /* tp_as_number */
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000865 &dequeiter_as_sequence, /* tp_as_sequence */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000866 0, /* tp_as_mapping */
867 0, /* tp_hash */
868 0, /* tp_call */
869 0, /* tp_str */
870 PyObject_GenericGetAttr, /* tp_getattro */
871 0, /* tp_setattro */
872 0, /* tp_as_buffer */
873 Py_TPFLAGS_DEFAULT, /* tp_flags */
874 0, /* tp_doc */
875 0, /* tp_traverse */
876 0, /* tp_clear */
877 0, /* tp_richcompare */
878 0, /* tp_weaklistoffset */
879 PyObject_SelfIter, /* tp_iter */
880 (iternextfunc)dequeiter_next, /* tp_iternext */
881 0,
882};
883
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000884/*********************** Deque Reverse Iterator **************************/
885
886PyTypeObject dequereviter_type;
887
888static PyObject *
889deque_reviter(dequeobject *deque)
890{
891 dequeiterobject *it;
892
893 it = PyObject_New(dequeiterobject, &dequereviter_type);
894 if (it == NULL)
895 return NULL;
896 it->b = deque->rightblock;
897 it->index = deque->rightindex;
898 Py_INCREF(deque);
899 it->deque = deque;
900 it->len = deque->len;
901 it->counter = deque->len;
902 return (PyObject *)it;
903}
904
905static PyObject *
906dequereviter_next(dequeiterobject *it)
907{
908 PyObject *item;
909 if (it->b == it->deque->leftblock && it->index < it->deque->leftindex)
910 return NULL;
911
912 if (it->len != it->deque->len) {
913 it->len = -1; /* Make this state sticky */
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000914 it->counter = 0;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000915 PyErr_SetString(PyExc_RuntimeError,
916 "deque changed size during iteration");
917 return NULL;
918 }
919
920 item = it->b->data[it->index];
921 it->index--;
922 if (it->index == -1 && it->b->leftlink != NULL) {
923 it->b = it->b->leftlink;
924 it->index = BLOCKLEN - 1;
925 }
926 it->counter--;
927 Py_INCREF(item);
928 return item;
929}
930
931PyTypeObject dequereviter_type = {
932 PyObject_HEAD_INIT(NULL)
933 0, /* ob_size */
934 "deque_reverse_iterator", /* tp_name */
935 sizeof(dequeiterobject), /* tp_basicsize */
936 0, /* tp_itemsize */
937 /* methods */
938 (destructor)dequeiter_dealloc, /* tp_dealloc */
939 0, /* tp_print */
940 0, /* tp_getattr */
941 0, /* tp_setattr */
942 0, /* tp_compare */
943 0, /* tp_repr */
944 0, /* tp_as_number */
945 &dequeiter_as_sequence, /* tp_as_sequence */
946 0, /* tp_as_mapping */
947 0, /* tp_hash */
948 0, /* tp_call */
949 0, /* tp_str */
950 PyObject_GenericGetAttr, /* tp_getattro */
951 0, /* tp_setattro */
952 0, /* tp_as_buffer */
953 Py_TPFLAGS_DEFAULT, /* tp_flags */
954 0, /* tp_doc */
955 0, /* tp_traverse */
956 0, /* tp_clear */
957 0, /* tp_richcompare */
958 0, /* tp_weaklistoffset */
959 PyObject_SelfIter, /* tp_iter */
960 (iternextfunc)dequereviter_next, /* tp_iternext */
961 0,
962};
963
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000964/* module level code ********************************************************/
965
966PyDoc_STRVAR(module_doc,
967"High performance data structures\n\
968");
969
970PyMODINIT_FUNC
971initcollections(void)
972{
973 PyObject *m;
974
975 m = Py_InitModule3("collections", NULL, module_doc);
976
977 if (PyType_Ready(&deque_type) < 0)
978 return;
979 Py_INCREF(&deque_type);
980 PyModule_AddObject(m, "deque", (PyObject *)&deque_type);
981
982 if (PyType_Ready(&dequeiter_type) < 0)
983 return;
984
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000985 if (PyType_Ready(&dequereviter_type) < 0)
986 return;
987
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000988 return;
989}