blob: 62b43aa90e45bbbd2e9763b7dfc134c845521286 [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);
244 if (PyErr_Occurred())
245 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);
273 if (item == NULL)
274 return NULL;
275 rv = deque_appendleft(deque, item);
276 Py_DECREF(item);
277 if (rv == NULL)
278 return NULL;
279 Py_DECREF(rv);
280 }
281 for (i=0 ; i>n ; i--) {
282 item = deque_popleft(deque, NULL);
283 if (item == NULL)
284 return NULL;
285 rv = deque_append(deque, item);
286 Py_DECREF(item);
287 if (rv == NULL)
288 return NULL;
289 Py_DECREF(rv);
290 }
291 Py_RETURN_NONE;
292}
293
294PyDoc_STRVAR(rotate_doc,
Raymond Hettingeree33b272004-02-08 04:05:26 +0000295"Rotate the deque n steps to the right (default n=1). If n is negative, rotates left.");
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000296
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000297static int
298deque_len(dequeobject *deque)
299{
300 return deque->len;
301}
302
303static int
304deque_clear(dequeobject *deque)
305{
306 PyObject *item;
307
308 while (deque_len(deque)) {
309 item = deque_pop(deque, NULL);
310 if (item == NULL)
311 return -1;
312 Py_DECREF(item);
313 }
314 assert(deque->leftblock == deque->rightblock &&
315 deque->leftindex > deque->rightindex);
316 return 0;
317}
318
319static PyObject *
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000320deque_item(dequeobject *deque, int i)
321{
322 block *b;
323 PyObject *item;
324 int n;
325
326 if (i < 0 || i >= deque->len) {
327 PyErr_SetString(PyExc_IndexError,
328 "deque index out of range");
329 return NULL;
330 }
331
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000332 if (i == 0) {
333 i = deque->leftindex;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000334 b = deque->leftblock;
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000335 } else if (i == deque->len - 1) {
336 i = deque->rightindex;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000337 b = deque->rightblock;
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000338 } else {
339 i += deque->leftindex;
340 n = i / BLOCKLEN;
341 i %= BLOCKLEN;
342 if (i < (deque->len >> 1)) {
343 b = deque->leftblock;
344 while (n--)
345 b = b->rightlink;
346 } else {
347 n = (deque->leftindex + deque->len - 1) / BLOCKLEN - n;
348 b = deque->rightblock;
349 while (n--)
350 b = b->leftlink;
351 }
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000352 }
353 item = b->data[i];
354 Py_INCREF(item);
355 return item;
356}
357
358static int
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000359deque_del_item(dequeobject *deque, int i)
360{
361 PyObject *item=NULL, *minus_i=NULL, *plus_i=NULL;
362 int rv = -1;
363
364 assert (i >= 0 && i < deque->len);
365
366 minus_i = Py_BuildValue("(i)", -i);
367 if (minus_i == NULL)
368 goto fail;
369
370 plus_i = Py_BuildValue("(i)", i);
371 if (plus_i == NULL)
372 goto fail;
373
374 item = deque_rotate(deque, minus_i);
375 if (item == NULL)
376 goto fail;
377 Py_DECREF(item);
378
379 item = deque_popleft(deque, NULL);
380 if (item == NULL)
381 goto fail;
382 Py_DECREF(item);
383
384 item = deque_rotate(deque, plus_i);
385 if (item == NULL)
386 goto fail;
387
388 rv = 0;
389fail:
390 Py_XDECREF(item);
391 Py_XDECREF(minus_i);
392 Py_XDECREF(plus_i);
393 return rv;
394}
395
396static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000397deque_ass_item(dequeobject *deque, int i, PyObject *v)
398{
399 PyObject *old_value;
400 block *b;
401 int n;
402
403 if (i < 0 || i >= deque->len) {
404 PyErr_SetString(PyExc_IndexError,
405 "deque index out of range");
406 return -1;
407 }
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000408 if (v == NULL)
409 return deque_del_item(deque, i);
410
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000411 i += deque->leftindex;
412 n = i / BLOCKLEN;
413 i %= BLOCKLEN;
414 if (i < (deque->len >> 1)) {
415 b = deque->leftblock;
416 while (n--)
417 b = b->rightlink;
418 } else {
419 n = (deque->leftindex + deque->len - 1) / BLOCKLEN - n;
420 b = deque->rightblock;
421 while (n--)
422 b = b->leftlink;
423 }
424 Py_INCREF(v);
425 old_value = b->data[i];
426 b->data[i] = v;
427 Py_DECREF(old_value);
428 return 0;
429}
430
431static PyObject *
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000432deque_clearmethod(dequeobject *deque)
433{
434 if (deque_clear(deque) == -1)
435 return NULL;
436 Py_RETURN_NONE;
437}
438
439PyDoc_STRVAR(clear_doc, "Remove all elements from the deque.");
440
441static void
442deque_dealloc(dequeobject *deque)
443{
444 PyObject_GC_UnTrack(deque);
Raymond Hettinger691d8052004-05-30 07:26:47 +0000445 if (deque->weakreflist != NULL)
446 PyObject_ClearWeakRefs((PyObject *) deque);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000447 if (deque->leftblock != NULL) {
448 int err = deque_clear(deque);
449 assert(err == 0);
450 assert(deque->leftblock != NULL);
451 PyMem_Free(deque->leftblock);
452 }
453 deque->leftblock = NULL;
454 deque->rightblock = NULL;
455 deque->ob_type->tp_free(deque);
456}
457
458static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000459deque_traverse(dequeobject *deque, visitproc visit, void *arg)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000460{
461 block * b = deque->leftblock;
462 int index = deque->leftindex;
463 int err;
464 PyObject *item;
465
466 while (b != deque->rightblock || index <= deque->rightindex) {
467 item = b->data[index];
468 index++;
469 if (index == BLOCKLEN && b->rightlink != NULL) {
470 b = b->rightlink;
471 index = 0;
472 }
473 err = visit(item, arg);
474 if (err)
475 return err;
476 }
477 return 0;
478}
479
480static long
481deque_nohash(PyObject *self)
482{
483 PyErr_SetString(PyExc_TypeError, "deque objects are unhashable");
484 return -1;
485}
486
487static PyObject *
488deque_copy(PyObject *deque)
489{
490 return PyObject_CallFunctionObjArgs((PyObject *)(deque->ob_type),
491 deque, NULL);
492}
493
494PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque.");
495
496static PyObject *
497deque_reduce(dequeobject *deque)
498{
499 PyObject *seq, *args, *result;
500
501 seq = PySequence_Tuple((PyObject *)deque);
502 if (seq == NULL)
503 return NULL;
504 args = PyTuple_Pack(1, seq);
505 if (args == NULL) {
506 Py_DECREF(seq);
507 return NULL;
508 }
509 result = PyTuple_Pack(2, deque->ob_type, args);
510 Py_DECREF(seq);
511 Py_DECREF(args);
512 return result;
513}
514
515PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
516
517static PyObject *
518deque_repr(PyObject *deque)
519{
520 PyObject *aslist, *result, *fmt;
521 int i;
522
523 i = Py_ReprEnter(deque);
524 if (i != 0) {
525 if (i < 0)
526 return NULL;
527 return PyString_FromString("[...]");
528 }
529
530 aslist = PySequence_List(deque);
531 if (aslist == NULL) {
532 Py_ReprLeave(deque);
533 return NULL;
534 }
535
536 fmt = PyString_FromString("deque(%r)");
537 if (fmt == NULL) {
538 Py_DECREF(aslist);
539 Py_ReprLeave(deque);
540 return NULL;
541 }
542 result = PyString_Format(fmt, aslist);
543 Py_DECREF(fmt);
544 Py_DECREF(aslist);
545 Py_ReprLeave(deque);
546 return result;
547}
548
549static int
550deque_tp_print(PyObject *deque, FILE *fp, int flags)
551{
552 PyObject *it, *item;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000553 char *emit = ""; /* No separator emitted on first pass */
554 char *separator = ", ";
555 int i;
556
557 i = Py_ReprEnter(deque);
558 if (i != 0) {
559 if (i < 0)
560 return i;
561 fputs("[...]", fp);
562 return 0;
563 }
564
565 it = PyObject_GetIter(deque);
566 if (it == NULL)
567 return -1;
568
569 fputs("deque([", fp);
570 while ((item = PyIter_Next(it)) != NULL) {
571 fputs(emit, fp);
572 emit = separator;
573 if (PyObject_Print(item, fp, 0) != 0) {
574 Py_DECREF(item);
575 Py_DECREF(it);
576 Py_ReprLeave(deque);
577 return -1;
578 }
579 Py_DECREF(item);
580 }
581 Py_ReprLeave(deque);
582 Py_DECREF(it);
583 if (PyErr_Occurred())
584 return -1;
585 fputs("])", fp);
586 return 0;
587}
588
Raymond Hettinger738ec902004-02-29 02:15:56 +0000589static PyObject *
590deque_richcompare(PyObject *v, PyObject *w, int op)
591{
592 PyObject *it1=NULL, *it2=NULL, *x, *y;
593 int i, b, vs, ws, minlen, cmp=-1;
594
Raymond Hettinger285cfcc2004-05-18 18:15:03 +0000595 if (!PyObject_TypeCheck(v, &deque_type) ||
596 !PyObject_TypeCheck(w, &deque_type)) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000597 Py_INCREF(Py_NotImplemented);
598 return Py_NotImplemented;
599 }
600
601 /* Shortcuts */
602 vs = ((dequeobject *)v)->len;
603 ws = ((dequeobject *)w)->len;
604 if (op == Py_EQ) {
605 if (v == w)
606 Py_RETURN_TRUE;
607 if (vs != ws)
608 Py_RETURN_FALSE;
609 }
610 if (op == Py_NE) {
611 if (v == w)
612 Py_RETURN_FALSE;
613 if (vs != ws)
614 Py_RETURN_TRUE;
615 }
616
617 /* Search for the first index where items are different */
618 it1 = PyObject_GetIter(v);
619 if (it1 == NULL)
620 goto done;
621 it2 = PyObject_GetIter(w);
622 if (it2 == NULL)
623 goto done;
624 minlen = (vs < ws) ? vs : ws;
625 for (i=0 ; i < minlen ; i++) {
626 x = PyIter_Next(it1);
627 if (x == NULL)
628 goto done;
629 y = PyIter_Next(it2);
630 if (y == NULL) {
631 Py_DECREF(x);
632 goto done;
633 }
634 b = PyObject_RichCompareBool(x, y, Py_EQ);
635 if (b == 0) {
636 cmp = PyObject_RichCompareBool(x, y, op);
637 Py_DECREF(x);
638 Py_DECREF(y);
639 goto done;
640 }
641 Py_DECREF(x);
642 Py_DECREF(y);
643 if (b == -1)
644 goto done;
645 }
646 /* Elements are equal through minlen. The longest input is the greatest */
647 switch (op) {
648 case Py_LT: cmp = vs < ws; break;
649 case Py_LE: cmp = vs <= ws; break;
650 case Py_EQ: cmp = vs == ws; break;
651 case Py_NE: cmp = vs != ws; break;
652 case Py_GT: cmp = vs > ws; break;
653 case Py_GE: cmp = vs >= ws; break;
654 }
655
656done:
657 Py_XDECREF(it1);
658 Py_XDECREF(it2);
659 if (cmp == 1)
660 Py_RETURN_TRUE;
661 if (cmp == 0)
662 Py_RETURN_FALSE;
663 return NULL;
664}
665
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000666static int
667deque_init(dequeobject *deque, PyObject *args, PyObject *kwds)
668{
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000669 PyObject *iterable = NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000670
671 if (!PyArg_UnpackTuple(args, "deque", 0, 1, &iterable))
672 return -1;
673
674 if (iterable != NULL) {
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000675 PyObject *rv = deque_extend(deque, iterable);
676 if (rv == NULL)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000677 return -1;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000678 Py_DECREF(rv);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000679 }
680 return 0;
681}
682
683static PySequenceMethods deque_as_sequence = {
684 (inquiry)deque_len, /* sq_length */
685 0, /* sq_concat */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000686 0, /* sq_repeat */
687 (intargfunc)deque_item, /* sq_item */
688 0, /* sq_slice */
689 (intobjargproc)deque_ass_item, /* sq_ass_item */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000690};
691
692/* deque object ********************************************************/
693
694static PyObject *deque_iter(dequeobject *deque);
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000695static PyObject *deque_reviter(dequeobject *deque);
696PyDoc_STRVAR(reversed_doc,
697 "D.__reversed__() -- return a reverse iterator over the deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000698
699static PyMethodDef deque_methods[] = {
700 {"append", (PyCFunction)deque_append,
701 METH_O, append_doc},
702 {"appendleft", (PyCFunction)deque_appendleft,
703 METH_O, appendleft_doc},
704 {"clear", (PyCFunction)deque_clearmethod,
705 METH_NOARGS, clear_doc},
706 {"__copy__", (PyCFunction)deque_copy,
707 METH_NOARGS, copy_doc},
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000708 {"extend", (PyCFunction)deque_extend,
709 METH_O, extend_doc},
710 {"extendleft", (PyCFunction)deque_extendleft,
711 METH_O, extendleft_doc},
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000712 {"pop", (PyCFunction)deque_pop,
713 METH_NOARGS, pop_doc},
714 {"popleft", (PyCFunction)deque_popleft,
715 METH_NOARGS, popleft_doc},
716 {"__reduce__", (PyCFunction)deque_reduce,
717 METH_NOARGS, reduce_doc},
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000718 {"__reversed__", (PyCFunction)deque_reviter,
719 METH_NOARGS, reversed_doc},
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000720 {"rotate", (PyCFunction)deque_rotate,
721 METH_VARARGS, rotate_doc},
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000722 {NULL, NULL} /* sentinel */
723};
724
725PyDoc_STRVAR(deque_doc,
726"deque(iterable) --> deque object\n\
727\n\
728Build an ordered collection accessible from endpoints only.");
729
Neal Norwitz87f10132004-02-29 15:40:53 +0000730static PyTypeObject deque_type = {
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000731 PyObject_HEAD_INIT(NULL)
732 0, /* ob_size */
733 "collections.deque", /* tp_name */
734 sizeof(dequeobject), /* tp_basicsize */
735 0, /* tp_itemsize */
736 /* methods */
737 (destructor)deque_dealloc, /* tp_dealloc */
738 (printfunc)deque_tp_print, /* tp_print */
739 0, /* tp_getattr */
740 0, /* tp_setattr */
741 0, /* tp_compare */
742 (reprfunc)deque_repr, /* tp_repr */
743 0, /* tp_as_number */
744 &deque_as_sequence, /* tp_as_sequence */
745 0, /* tp_as_mapping */
746 deque_nohash, /* tp_hash */
747 0, /* tp_call */
748 0, /* tp_str */
749 PyObject_GenericGetAttr, /* tp_getattro */
750 0, /* tp_setattro */
751 0, /* tp_as_buffer */
Raymond Hettinger691d8052004-05-30 07:26:47 +0000752 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
753 Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000754 deque_doc, /* tp_doc */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000755 (traverseproc)deque_traverse, /* tp_traverse */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000756 (inquiry)deque_clear, /* tp_clear */
Raymond Hettinger738ec902004-02-29 02:15:56 +0000757 (richcmpfunc)deque_richcompare, /* tp_richcompare */
Raymond Hettinger691d8052004-05-30 07:26:47 +0000758 offsetof(dequeobject, weakreflist), /* tp_weaklistoffset*/
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000759 (getiterfunc)deque_iter, /* tp_iter */
760 0, /* tp_iternext */
761 deque_methods, /* tp_methods */
762 0, /* tp_members */
763 0, /* tp_getset */
764 0, /* tp_base */
765 0, /* tp_dict */
766 0, /* tp_descr_get */
767 0, /* tp_descr_set */
768 0, /* tp_dictoffset */
769 (initproc)deque_init, /* tp_init */
770 PyType_GenericAlloc, /* tp_alloc */
771 deque_new, /* tp_new */
772 PyObject_GC_Del, /* tp_free */
773};
774
775/*********************** Deque Iterator **************************/
776
777typedef struct {
778 PyObject_HEAD
779 int index;
780 block *b;
781 dequeobject *deque;
782 int len;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000783 int counter;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000784} dequeiterobject;
785
786PyTypeObject dequeiter_type;
787
788static PyObject *
789deque_iter(dequeobject *deque)
790{
791 dequeiterobject *it;
792
793 it = PyObject_New(dequeiterobject, &dequeiter_type);
794 if (it == NULL)
795 return NULL;
796 it->b = deque->leftblock;
797 it->index = deque->leftindex;
798 Py_INCREF(deque);
799 it->deque = deque;
800 it->len = deque->len;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000801 it->counter = deque->len;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000802 return (PyObject *)it;
803}
804
805static void
806dequeiter_dealloc(dequeiterobject *dio)
807{
808 Py_XDECREF(dio->deque);
809 dio->ob_type->tp_free(dio);
810}
811
812static PyObject *
813dequeiter_next(dequeiterobject *it)
814{
815 PyObject *item;
816 if (it->b == it->deque->rightblock && it->index > it->deque->rightindex)
817 return NULL;
818
819 if (it->len != it->deque->len) {
820 it->len = -1; /* Make this state sticky */
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000821 it->counter = 0;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000822 PyErr_SetString(PyExc_RuntimeError,
823 "deque changed size during iteration");
824 return NULL;
825 }
826
827 item = it->b->data[it->index];
828 it->index++;
829 if (it->index == BLOCKLEN && it->b->rightlink != NULL) {
830 it->b = it->b->rightlink;
831 it->index = 0;
832 }
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000833 it->counter--;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000834 Py_INCREF(item);
835 return item;
836}
837
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000838static int
839dequeiter_len(dequeiterobject *it)
840{
841 return it->counter;
842}
843
844static PySequenceMethods dequeiter_as_sequence = {
845 (inquiry)dequeiter_len, /* sq_length */
846 0, /* sq_concat */
847};
848
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000849PyTypeObject dequeiter_type = {
850 PyObject_HEAD_INIT(NULL)
851 0, /* ob_size */
852 "deque_iterator", /* tp_name */
853 sizeof(dequeiterobject), /* tp_basicsize */
854 0, /* tp_itemsize */
855 /* methods */
856 (destructor)dequeiter_dealloc, /* tp_dealloc */
857 0, /* tp_print */
858 0, /* tp_getattr */
859 0, /* tp_setattr */
860 0, /* tp_compare */
861 0, /* tp_repr */
862 0, /* tp_as_number */
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000863 &dequeiter_as_sequence, /* tp_as_sequence */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000864 0, /* tp_as_mapping */
865 0, /* tp_hash */
866 0, /* tp_call */
867 0, /* tp_str */
868 PyObject_GenericGetAttr, /* tp_getattro */
869 0, /* tp_setattro */
870 0, /* tp_as_buffer */
871 Py_TPFLAGS_DEFAULT, /* tp_flags */
872 0, /* tp_doc */
873 0, /* tp_traverse */
874 0, /* tp_clear */
875 0, /* tp_richcompare */
876 0, /* tp_weaklistoffset */
877 PyObject_SelfIter, /* tp_iter */
878 (iternextfunc)dequeiter_next, /* tp_iternext */
879 0,
880};
881
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000882/*********************** Deque Reverse Iterator **************************/
883
884PyTypeObject dequereviter_type;
885
886static PyObject *
887deque_reviter(dequeobject *deque)
888{
889 dequeiterobject *it;
890
891 it = PyObject_New(dequeiterobject, &dequereviter_type);
892 if (it == NULL)
893 return NULL;
894 it->b = deque->rightblock;
895 it->index = deque->rightindex;
896 Py_INCREF(deque);
897 it->deque = deque;
898 it->len = deque->len;
899 it->counter = deque->len;
900 return (PyObject *)it;
901}
902
903static PyObject *
904dequereviter_next(dequeiterobject *it)
905{
906 PyObject *item;
907 if (it->b == it->deque->leftblock && it->index < it->deque->leftindex)
908 return NULL;
909
910 if (it->len != it->deque->len) {
911 it->len = -1; /* Make this state sticky */
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000912 it->counter = 0;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000913 PyErr_SetString(PyExc_RuntimeError,
914 "deque changed size during iteration");
915 return NULL;
916 }
917
918 item = it->b->data[it->index];
919 it->index--;
920 if (it->index == -1 && it->b->leftlink != NULL) {
921 it->b = it->b->leftlink;
922 it->index = BLOCKLEN - 1;
923 }
924 it->counter--;
925 Py_INCREF(item);
926 return item;
927}
928
929PyTypeObject dequereviter_type = {
930 PyObject_HEAD_INIT(NULL)
931 0, /* ob_size */
932 "deque_reverse_iterator", /* tp_name */
933 sizeof(dequeiterobject), /* tp_basicsize */
934 0, /* tp_itemsize */
935 /* methods */
936 (destructor)dequeiter_dealloc, /* tp_dealloc */
937 0, /* tp_print */
938 0, /* tp_getattr */
939 0, /* tp_setattr */
940 0, /* tp_compare */
941 0, /* tp_repr */
942 0, /* tp_as_number */
943 &dequeiter_as_sequence, /* tp_as_sequence */
944 0, /* tp_as_mapping */
945 0, /* tp_hash */
946 0, /* tp_call */
947 0, /* tp_str */
948 PyObject_GenericGetAttr, /* tp_getattro */
949 0, /* tp_setattro */
950 0, /* tp_as_buffer */
951 Py_TPFLAGS_DEFAULT, /* tp_flags */
952 0, /* tp_doc */
953 0, /* tp_traverse */
954 0, /* tp_clear */
955 0, /* tp_richcompare */
956 0, /* tp_weaklistoffset */
957 PyObject_SelfIter, /* tp_iter */
958 (iternextfunc)dequereviter_next, /* tp_iternext */
959 0,
960};
961
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000962/* module level code ********************************************************/
963
964PyDoc_STRVAR(module_doc,
965"High performance data structures\n\
966");
967
968PyMODINIT_FUNC
969initcollections(void)
970{
971 PyObject *m;
972
973 m = Py_InitModule3("collections", NULL, module_doc);
974
975 if (PyType_Ready(&deque_type) < 0)
976 return;
977 Py_INCREF(&deque_type);
978 PyModule_AddObject(m, "deque", (PyObject *)&deque_type);
979
980 if (PyType_Ready(&dequeiter_type) < 0)
981 return;
982
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000983 if (PyType_Ready(&dequereviter_type) < 0)
984 return;
985
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000986 return;
987}