blob: c72c7a6d06c5365f7a3ba9b10c6369f73e3dd985 [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) {
453 int err = deque_clear(deque);
454 assert(err == 0);
455 assert(deque->leftblock != NULL);
456 PyMem_Free(deque->leftblock);
457 }
458 deque->leftblock = NULL;
459 deque->rightblock = NULL;
460 deque->ob_type->tp_free(deque);
461}
462
463static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000464deque_traverse(dequeobject *deque, visitproc visit, void *arg)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000465{
466 block * b = deque->leftblock;
467 int index = deque->leftindex;
468 int err;
469 PyObject *item;
470
471 while (b != deque->rightblock || index <= deque->rightindex) {
472 item = b->data[index];
473 index++;
474 if (index == BLOCKLEN && b->rightlink != NULL) {
475 b = b->rightlink;
476 index = 0;
477 }
478 err = visit(item, arg);
479 if (err)
480 return err;
481 }
482 return 0;
483}
484
485static long
486deque_nohash(PyObject *self)
487{
488 PyErr_SetString(PyExc_TypeError, "deque objects are unhashable");
489 return -1;
490}
491
492static PyObject *
493deque_copy(PyObject *deque)
494{
495 return PyObject_CallFunctionObjArgs((PyObject *)(deque->ob_type),
496 deque, NULL);
497}
498
499PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque.");
500
501static PyObject *
502deque_reduce(dequeobject *deque)
503{
504 PyObject *seq, *args, *result;
505
506 seq = PySequence_Tuple((PyObject *)deque);
507 if (seq == NULL)
508 return NULL;
509 args = PyTuple_Pack(1, seq);
510 if (args == NULL) {
511 Py_DECREF(seq);
512 return NULL;
513 }
514 result = PyTuple_Pack(2, deque->ob_type, args);
515 Py_DECREF(seq);
516 Py_DECREF(args);
517 return result;
518}
519
520PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
521
522static PyObject *
523deque_repr(PyObject *deque)
524{
525 PyObject *aslist, *result, *fmt;
526 int i;
527
528 i = Py_ReprEnter(deque);
529 if (i != 0) {
530 if (i < 0)
531 return NULL;
532 return PyString_FromString("[...]");
533 }
534
535 aslist = PySequence_List(deque);
536 if (aslist == NULL) {
537 Py_ReprLeave(deque);
538 return NULL;
539 }
540
541 fmt = PyString_FromString("deque(%r)");
542 if (fmt == NULL) {
543 Py_DECREF(aslist);
544 Py_ReprLeave(deque);
545 return NULL;
546 }
547 result = PyString_Format(fmt, aslist);
548 Py_DECREF(fmt);
549 Py_DECREF(aslist);
550 Py_ReprLeave(deque);
551 return result;
552}
553
554static int
555deque_tp_print(PyObject *deque, FILE *fp, int flags)
556{
557 PyObject *it, *item;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000558 char *emit = ""; /* No separator emitted on first pass */
559 char *separator = ", ";
560 int i;
561
562 i = Py_ReprEnter(deque);
563 if (i != 0) {
564 if (i < 0)
565 return i;
566 fputs("[...]", fp);
567 return 0;
568 }
569
570 it = PyObject_GetIter(deque);
571 if (it == NULL)
572 return -1;
573
574 fputs("deque([", fp);
575 while ((item = PyIter_Next(it)) != NULL) {
576 fputs(emit, fp);
577 emit = separator;
578 if (PyObject_Print(item, fp, 0) != 0) {
579 Py_DECREF(item);
580 Py_DECREF(it);
581 Py_ReprLeave(deque);
582 return -1;
583 }
584 Py_DECREF(item);
585 }
586 Py_ReprLeave(deque);
587 Py_DECREF(it);
588 if (PyErr_Occurred())
589 return -1;
590 fputs("])", fp);
591 return 0;
592}
593
Raymond Hettinger738ec902004-02-29 02:15:56 +0000594static PyObject *
595deque_richcompare(PyObject *v, PyObject *w, int op)
596{
597 PyObject *it1=NULL, *it2=NULL, *x, *y;
598 int i, b, vs, ws, minlen, cmp=-1;
599
Raymond Hettinger285cfcc2004-05-18 18:15:03 +0000600 if (!PyObject_TypeCheck(v, &deque_type) ||
601 !PyObject_TypeCheck(w, &deque_type)) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000602 Py_INCREF(Py_NotImplemented);
603 return Py_NotImplemented;
604 }
605
606 /* Shortcuts */
607 vs = ((dequeobject *)v)->len;
608 ws = ((dequeobject *)w)->len;
609 if (op == Py_EQ) {
610 if (v == w)
611 Py_RETURN_TRUE;
612 if (vs != ws)
613 Py_RETURN_FALSE;
614 }
615 if (op == Py_NE) {
616 if (v == w)
617 Py_RETURN_FALSE;
618 if (vs != ws)
619 Py_RETURN_TRUE;
620 }
621
622 /* Search for the first index where items are different */
623 it1 = PyObject_GetIter(v);
624 if (it1 == NULL)
625 goto done;
626 it2 = PyObject_GetIter(w);
627 if (it2 == NULL)
628 goto done;
629 minlen = (vs < ws) ? vs : ws;
630 for (i=0 ; i < minlen ; i++) {
631 x = PyIter_Next(it1);
632 if (x == NULL)
633 goto done;
634 y = PyIter_Next(it2);
635 if (y == NULL) {
636 Py_DECREF(x);
637 goto done;
638 }
639 b = PyObject_RichCompareBool(x, y, Py_EQ);
640 if (b == 0) {
641 cmp = PyObject_RichCompareBool(x, y, op);
642 Py_DECREF(x);
643 Py_DECREF(y);
644 goto done;
645 }
646 Py_DECREF(x);
647 Py_DECREF(y);
648 if (b == -1)
649 goto done;
650 }
651 /* Elements are equal through minlen. The longest input is the greatest */
652 switch (op) {
653 case Py_LT: cmp = vs < ws; break;
654 case Py_LE: cmp = vs <= ws; break;
655 case Py_EQ: cmp = vs == ws; break;
656 case Py_NE: cmp = vs != ws; break;
657 case Py_GT: cmp = vs > ws; break;
658 case Py_GE: cmp = vs >= ws; break;
659 }
660
661done:
662 Py_XDECREF(it1);
663 Py_XDECREF(it2);
664 if (cmp == 1)
665 Py_RETURN_TRUE;
666 if (cmp == 0)
667 Py_RETURN_FALSE;
668 return NULL;
669}
670
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000671static int
672deque_init(dequeobject *deque, PyObject *args, PyObject *kwds)
673{
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000674 PyObject *iterable = NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000675
676 if (!PyArg_UnpackTuple(args, "deque", 0, 1, &iterable))
677 return -1;
678
679 if (iterable != NULL) {
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000680 PyObject *rv = deque_extend(deque, iterable);
681 if (rv == NULL)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000682 return -1;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000683 Py_DECREF(rv);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000684 }
685 return 0;
686}
687
688static PySequenceMethods deque_as_sequence = {
689 (inquiry)deque_len, /* sq_length */
690 0, /* sq_concat */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000691 0, /* sq_repeat */
692 (intargfunc)deque_item, /* sq_item */
693 0, /* sq_slice */
694 (intobjargproc)deque_ass_item, /* sq_ass_item */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000695};
696
697/* deque object ********************************************************/
698
699static PyObject *deque_iter(dequeobject *deque);
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000700static PyObject *deque_reviter(dequeobject *deque);
701PyDoc_STRVAR(reversed_doc,
702 "D.__reversed__() -- return a reverse iterator over the deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000703
704static PyMethodDef deque_methods[] = {
705 {"append", (PyCFunction)deque_append,
706 METH_O, append_doc},
707 {"appendleft", (PyCFunction)deque_appendleft,
708 METH_O, appendleft_doc},
709 {"clear", (PyCFunction)deque_clearmethod,
710 METH_NOARGS, clear_doc},
711 {"__copy__", (PyCFunction)deque_copy,
712 METH_NOARGS, copy_doc},
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000713 {"extend", (PyCFunction)deque_extend,
714 METH_O, extend_doc},
715 {"extendleft", (PyCFunction)deque_extendleft,
716 METH_O, extendleft_doc},
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000717 {"pop", (PyCFunction)deque_pop,
718 METH_NOARGS, pop_doc},
719 {"popleft", (PyCFunction)deque_popleft,
720 METH_NOARGS, popleft_doc},
721 {"__reduce__", (PyCFunction)deque_reduce,
722 METH_NOARGS, reduce_doc},
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000723 {"__reversed__", (PyCFunction)deque_reviter,
724 METH_NOARGS, reversed_doc},
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000725 {"rotate", (PyCFunction)deque_rotate,
726 METH_VARARGS, rotate_doc},
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000727 {NULL, NULL} /* sentinel */
728};
729
730PyDoc_STRVAR(deque_doc,
731"deque(iterable) --> deque object\n\
732\n\
733Build an ordered collection accessible from endpoints only.");
734
Neal Norwitz87f10132004-02-29 15:40:53 +0000735static PyTypeObject deque_type = {
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000736 PyObject_HEAD_INIT(NULL)
737 0, /* ob_size */
738 "collections.deque", /* tp_name */
739 sizeof(dequeobject), /* tp_basicsize */
740 0, /* tp_itemsize */
741 /* methods */
742 (destructor)deque_dealloc, /* tp_dealloc */
743 (printfunc)deque_tp_print, /* tp_print */
744 0, /* tp_getattr */
745 0, /* tp_setattr */
746 0, /* tp_compare */
747 (reprfunc)deque_repr, /* tp_repr */
748 0, /* tp_as_number */
749 &deque_as_sequence, /* tp_as_sequence */
750 0, /* tp_as_mapping */
751 deque_nohash, /* tp_hash */
752 0, /* tp_call */
753 0, /* tp_str */
754 PyObject_GenericGetAttr, /* tp_getattro */
755 0, /* tp_setattro */
756 0, /* tp_as_buffer */
Raymond Hettinger691d8052004-05-30 07:26:47 +0000757 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
758 Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000759 deque_doc, /* tp_doc */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000760 (traverseproc)deque_traverse, /* tp_traverse */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000761 (inquiry)deque_clear, /* tp_clear */
Raymond Hettinger738ec902004-02-29 02:15:56 +0000762 (richcmpfunc)deque_richcompare, /* tp_richcompare */
Raymond Hettinger691d8052004-05-30 07:26:47 +0000763 offsetof(dequeobject, weakreflist), /* tp_weaklistoffset*/
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000764 (getiterfunc)deque_iter, /* tp_iter */
765 0, /* tp_iternext */
766 deque_methods, /* tp_methods */
767 0, /* tp_members */
768 0, /* tp_getset */
769 0, /* tp_base */
770 0, /* tp_dict */
771 0, /* tp_descr_get */
772 0, /* tp_descr_set */
773 0, /* tp_dictoffset */
774 (initproc)deque_init, /* tp_init */
775 PyType_GenericAlloc, /* tp_alloc */
776 deque_new, /* tp_new */
777 PyObject_GC_Del, /* tp_free */
778};
779
780/*********************** Deque Iterator **************************/
781
782typedef struct {
783 PyObject_HEAD
784 int index;
785 block *b;
786 dequeobject *deque;
787 int len;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000788 int counter;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000789} dequeiterobject;
790
791PyTypeObject dequeiter_type;
792
793static PyObject *
794deque_iter(dequeobject *deque)
795{
796 dequeiterobject *it;
797
798 it = PyObject_New(dequeiterobject, &dequeiter_type);
799 if (it == NULL)
800 return NULL;
801 it->b = deque->leftblock;
802 it->index = deque->leftindex;
803 Py_INCREF(deque);
804 it->deque = deque;
805 it->len = deque->len;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000806 it->counter = deque->len;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000807 return (PyObject *)it;
808}
809
810static void
811dequeiter_dealloc(dequeiterobject *dio)
812{
813 Py_XDECREF(dio->deque);
814 dio->ob_type->tp_free(dio);
815}
816
817static PyObject *
818dequeiter_next(dequeiterobject *it)
819{
820 PyObject *item;
821 if (it->b == it->deque->rightblock && it->index > it->deque->rightindex)
822 return NULL;
823
824 if (it->len != it->deque->len) {
825 it->len = -1; /* Make this state sticky */
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000826 it->counter = 0;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000827 PyErr_SetString(PyExc_RuntimeError,
828 "deque changed size during iteration");
829 return NULL;
830 }
831
832 item = it->b->data[it->index];
833 it->index++;
834 if (it->index == BLOCKLEN && it->b->rightlink != NULL) {
835 it->b = it->b->rightlink;
836 it->index = 0;
837 }
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000838 it->counter--;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000839 Py_INCREF(item);
840 return item;
841}
842
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000843static int
844dequeiter_len(dequeiterobject *it)
845{
846 return it->counter;
847}
848
849static PySequenceMethods dequeiter_as_sequence = {
850 (inquiry)dequeiter_len, /* sq_length */
851 0, /* sq_concat */
852};
853
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000854PyTypeObject dequeiter_type = {
855 PyObject_HEAD_INIT(NULL)
856 0, /* ob_size */
857 "deque_iterator", /* tp_name */
858 sizeof(dequeiterobject), /* tp_basicsize */
859 0, /* tp_itemsize */
860 /* methods */
861 (destructor)dequeiter_dealloc, /* tp_dealloc */
862 0, /* tp_print */
863 0, /* tp_getattr */
864 0, /* tp_setattr */
865 0, /* tp_compare */
866 0, /* tp_repr */
867 0, /* tp_as_number */
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000868 &dequeiter_as_sequence, /* tp_as_sequence */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000869 0, /* tp_as_mapping */
870 0, /* tp_hash */
871 0, /* tp_call */
872 0, /* tp_str */
873 PyObject_GenericGetAttr, /* tp_getattro */
874 0, /* tp_setattro */
875 0, /* tp_as_buffer */
876 Py_TPFLAGS_DEFAULT, /* tp_flags */
877 0, /* tp_doc */
878 0, /* tp_traverse */
879 0, /* tp_clear */
880 0, /* tp_richcompare */
881 0, /* tp_weaklistoffset */
882 PyObject_SelfIter, /* tp_iter */
883 (iternextfunc)dequeiter_next, /* tp_iternext */
884 0,
885};
886
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000887/*********************** Deque Reverse Iterator **************************/
888
889PyTypeObject dequereviter_type;
890
891static PyObject *
892deque_reviter(dequeobject *deque)
893{
894 dequeiterobject *it;
895
896 it = PyObject_New(dequeiterobject, &dequereviter_type);
897 if (it == NULL)
898 return NULL;
899 it->b = deque->rightblock;
900 it->index = deque->rightindex;
901 Py_INCREF(deque);
902 it->deque = deque;
903 it->len = deque->len;
904 it->counter = deque->len;
905 return (PyObject *)it;
906}
907
908static PyObject *
909dequereviter_next(dequeiterobject *it)
910{
911 PyObject *item;
912 if (it->b == it->deque->leftblock && it->index < it->deque->leftindex)
913 return NULL;
914
915 if (it->len != it->deque->len) {
916 it->len = -1; /* Make this state sticky */
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000917 it->counter = 0;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000918 PyErr_SetString(PyExc_RuntimeError,
919 "deque changed size during iteration");
920 return NULL;
921 }
922
923 item = it->b->data[it->index];
924 it->index--;
925 if (it->index == -1 && it->b->leftlink != NULL) {
926 it->b = it->b->leftlink;
927 it->index = BLOCKLEN - 1;
928 }
929 it->counter--;
930 Py_INCREF(item);
931 return item;
932}
933
934PyTypeObject dequereviter_type = {
935 PyObject_HEAD_INIT(NULL)
936 0, /* ob_size */
937 "deque_reverse_iterator", /* tp_name */
938 sizeof(dequeiterobject), /* tp_basicsize */
939 0, /* tp_itemsize */
940 /* methods */
941 (destructor)dequeiter_dealloc, /* tp_dealloc */
942 0, /* tp_print */
943 0, /* tp_getattr */
944 0, /* tp_setattr */
945 0, /* tp_compare */
946 0, /* tp_repr */
947 0, /* tp_as_number */
948 &dequeiter_as_sequence, /* tp_as_sequence */
949 0, /* tp_as_mapping */
950 0, /* tp_hash */
951 0, /* tp_call */
952 0, /* tp_str */
953 PyObject_GenericGetAttr, /* tp_getattro */
954 0, /* tp_setattro */
955 0, /* tp_as_buffer */
956 Py_TPFLAGS_DEFAULT, /* tp_flags */
957 0, /* tp_doc */
958 0, /* tp_traverse */
959 0, /* tp_clear */
960 0, /* tp_richcompare */
961 0, /* tp_weaklistoffset */
962 PyObject_SelfIter, /* tp_iter */
963 (iternextfunc)dequereviter_next, /* tp_iternext */
964 0,
965};
966
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000967/* module level code ********************************************************/
968
969PyDoc_STRVAR(module_doc,
970"High performance data structures\n\
971");
972
973PyMODINIT_FUNC
974initcollections(void)
975{
976 PyObject *m;
977
978 m = Py_InitModule3("collections", NULL, module_doc);
979
980 if (PyType_Ready(&deque_type) < 0)
981 return;
982 Py_INCREF(&deque_type);
983 PyModule_AddObject(m, "deque", (PyObject *)&deque_type);
984
985 if (PyType_Ready(&dequeiter_type) < 0)
986 return;
987
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000988 if (PyType_Ready(&dequereviter_type) < 0)
989 return;
990
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000991 return;
992}