blob: da276ce3703cc3cef48415fb2ea4b2cecaaba30a [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
Nicholas Bastin1ce9e4c2004-06-17 18:27:18 +00004#ifdef __SUNPRO_C
5#pragma error_messages (off,E_END_OF_LOOP_CODE_NOT_REACHED)
6#endif
7
Raymond Hettinger756b3f32004-01-29 06:37:52 +00008/* collections module implementation of a deque() datatype
9 Written and maintained by Raymond D. Hettinger <python@rcn.com>
10 Copyright (c) 2004 Python Software Foundation.
11 All rights reserved.
12*/
13
14#define BLOCKLEN 46
15
16typedef struct BLOCK {
17 struct BLOCK *leftlink;
18 struct BLOCK *rightlink;
19 PyObject *data[BLOCKLEN];
20} block;
21
22static block *newblock(block *leftlink, block *rightlink) {
23 block *b = PyMem_Malloc(sizeof(block));
24 if (b == NULL) {
25 PyErr_NoMemory();
26 return NULL;
27 }
28 b->leftlink = leftlink;
29 b->rightlink = rightlink;
30 return b;
31}
32
33typedef struct {
34 PyObject_HEAD
35 block *leftblock;
36 block *rightblock;
37 int leftindex;
38 int rightindex;
39 int len;
Raymond Hettinger691d8052004-05-30 07:26:47 +000040 PyObject *weakreflist; /* List of weak references */
Raymond Hettinger756b3f32004-01-29 06:37:52 +000041} dequeobject;
42
Neal Norwitz87f10132004-02-29 15:40:53 +000043static PyTypeObject deque_type;
Raymond Hettinger738ec902004-02-29 02:15:56 +000044
Raymond Hettinger756b3f32004-01-29 06:37:52 +000045static PyObject *
46deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
47{
48 dequeobject *deque;
49 block *b;
50
51 /* create dequeobject structure */
52 deque = (dequeobject *)type->tp_alloc(type, 0);
53 if (deque == NULL)
54 return NULL;
55
56 b = newblock(NULL, NULL);
57 if (b == NULL) {
58 Py_DECREF(deque);
59 return NULL;
60 }
61
62 deque->leftblock = b;
63 deque->rightblock = b;
64 deque->leftindex = BLOCKLEN / 2 + 1;
65 deque->rightindex = BLOCKLEN / 2;
66 deque->len = 0;
Raymond Hettinger691d8052004-05-30 07:26:47 +000067 deque->weakreflist = NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +000068
69 return (PyObject *)deque;
70}
71
72static PyObject *
73deque_append(dequeobject *deque, PyObject *item)
74{
75 deque->rightindex++;
76 deque->len++;
77 if (deque->rightindex == BLOCKLEN) {
78 block *b = newblock(deque->rightblock, NULL);
79 if (b == NULL)
80 return NULL;
81 assert(deque->rightblock->rightlink == NULL);
82 deque->rightblock->rightlink = b;
83 deque->rightblock = b;
84 deque->rightindex = 0;
85 }
86 Py_INCREF(item);
87 deque->rightblock->data[deque->rightindex] = item;
88 Py_RETURN_NONE;
89}
90
91PyDoc_STRVAR(append_doc, "Add an element to the right side of the deque.");
92
93static PyObject *
94deque_appendleft(dequeobject *deque, PyObject *item)
95{
96 deque->leftindex--;
97 deque->len++;
98 if (deque->leftindex == -1) {
99 block *b = newblock(NULL, deque->leftblock);
100 if (b == NULL)
101 return NULL;
102 assert(deque->leftblock->leftlink == NULL);
103 deque->leftblock->leftlink = b;
104 deque->leftblock = b;
105 deque->leftindex = BLOCKLEN - 1;
106 }
107 Py_INCREF(item);
108 deque->leftblock->data[deque->leftindex] = item;
109 Py_RETURN_NONE;
110}
111
112PyDoc_STRVAR(appendleft_doc, "Add an element to the left side of the deque.");
113
114static PyObject *
115deque_pop(dequeobject *deque, PyObject *unused)
116{
117 PyObject *item;
118 block *prevblock;
119
120 if (deque->len == 0) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000121 PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000122 return NULL;
123 }
124 item = deque->rightblock->data[deque->rightindex];
125 deque->rightindex--;
126 deque->len--;
127
128 if (deque->rightindex == -1) {
129 if (deque->len == 0) {
130 assert(deque->leftblock == deque->rightblock);
131 assert(deque->leftindex == deque->rightindex+1);
132 /* re-center instead of freeing a block */
133 deque->leftindex = BLOCKLEN / 2 + 1;
134 deque->rightindex = BLOCKLEN / 2;
135 } else {
136 prevblock = deque->rightblock->leftlink;
137 assert(deque->leftblock != deque->rightblock);
138 PyMem_Free(deque->rightblock);
139 prevblock->rightlink = NULL;
140 deque->rightblock = prevblock;
141 deque->rightindex = BLOCKLEN - 1;
142 }
143 }
144 return item;
145}
146
147PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element.");
148
149static PyObject *
150deque_popleft(dequeobject *deque, PyObject *unused)
151{
152 PyObject *item;
153 block *prevblock;
154
155 if (deque->len == 0) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000156 PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000157 return NULL;
158 }
159 item = deque->leftblock->data[deque->leftindex];
160 deque->leftindex++;
161 deque->len--;
162
163 if (deque->leftindex == BLOCKLEN) {
164 if (deque->len == 0) {
165 assert(deque->leftblock == deque->rightblock);
166 assert(deque->leftindex == deque->rightindex+1);
167 /* re-center instead of freeing a block */
168 deque->leftindex = BLOCKLEN / 2 + 1;
169 deque->rightindex = BLOCKLEN / 2;
170 } else {
171 assert(deque->leftblock != deque->rightblock);
172 prevblock = deque->leftblock->rightlink;
173 assert(deque->leftblock != NULL);
174 PyMem_Free(deque->leftblock);
175 assert(prevblock != NULL);
176 prevblock->leftlink = NULL;
177 deque->leftblock = prevblock;
178 deque->leftindex = 0;
179 }
180 }
181 return item;
182}
183
184PyDoc_STRVAR(popleft_doc, "Remove and return the leftmost element.");
185
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000186static PyObject *
187deque_extend(dequeobject *deque, PyObject *iterable)
188{
189 PyObject *it, *item;
190
191 it = PyObject_GetIter(iterable);
192 if (it == NULL)
193 return NULL;
194
195 while ((item = PyIter_Next(it)) != NULL) {
196 deque->rightindex++;
197 deque->len++;
198 if (deque->rightindex == BLOCKLEN) {
199 block *b = newblock(deque->rightblock, NULL);
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000200 if (b == NULL) {
201 Py_DECREF(item);
202 Py_DECREF(it);
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000203 return NULL;
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000204 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000205 assert(deque->rightblock->rightlink == NULL);
206 deque->rightblock->rightlink = b;
207 deque->rightblock = b;
208 deque->rightindex = 0;
209 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000210 deque->rightblock->data[deque->rightindex] = item;
211 }
212 Py_DECREF(it);
213 if (PyErr_Occurred())
214 return NULL;
215 Py_RETURN_NONE;
216}
217
218PyDoc_STRVAR(extend_doc,
219"Extend the right side of the deque with elements from the iterable");
220
221static PyObject *
222deque_extendleft(dequeobject *deque, PyObject *iterable)
223{
224 PyObject *it, *item;
225
226 it = PyObject_GetIter(iterable);
227 if (it == NULL)
228 return NULL;
229
230 while ((item = PyIter_Next(it)) != NULL) {
231 deque->leftindex--;
232 deque->len++;
233 if (deque->leftindex == -1) {
234 block *b = newblock(NULL, deque->leftblock);
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000235 if (b == NULL) {
236 Py_DECREF(item);
237 Py_DECREF(it);
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000238 return NULL;
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000239 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000240 assert(deque->leftblock->leftlink == NULL);
241 deque->leftblock->leftlink = b;
242 deque->leftblock = b;
243 deque->leftindex = BLOCKLEN - 1;
244 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000245 deque->leftblock->data[deque->leftindex] = item;
246 }
247 Py_DECREF(it);
248 if (PyErr_Occurred())
249 return NULL;
250 Py_RETURN_NONE;
251}
252
253PyDoc_STRVAR(extendleft_doc,
254"Extend the left side of the deque with elements from the iterable");
255
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000256static PyObject *
257deque_rotate(dequeobject *deque, PyObject *args)
258{
Raymond Hettingeree33b272004-02-08 04:05:26 +0000259 int i, n=1, len=deque->len, halflen=(len+1)>>1;
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000260 PyObject *item, *rv;
261
Raymond Hettingeree33b272004-02-08 04:05:26 +0000262 if (!PyArg_ParseTuple(args, "|i:rotate", &n))
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000263 return NULL;
264
Raymond Hettingeree33b272004-02-08 04:05:26 +0000265 if (len == 0)
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000266 Py_RETURN_NONE;
Raymond Hettingeree33b272004-02-08 04:05:26 +0000267 if (n > halflen || n < -halflen) {
268 n %= len;
269 if (n > halflen)
270 n -= len;
271 else if (n < -halflen)
272 n += len;
273 }
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000274
275 for (i=0 ; i<n ; i++) {
276 item = deque_pop(deque, NULL);
277 if (item == NULL)
278 return NULL;
279 rv = deque_appendleft(deque, item);
280 Py_DECREF(item);
281 if (rv == NULL)
282 return NULL;
283 Py_DECREF(rv);
284 }
285 for (i=0 ; i>n ; i--) {
286 item = deque_popleft(deque, NULL);
287 if (item == NULL)
288 return NULL;
289 rv = deque_append(deque, item);
290 Py_DECREF(item);
291 if (rv == NULL)
292 return NULL;
293 Py_DECREF(rv);
294 }
295 Py_RETURN_NONE;
296}
297
298PyDoc_STRVAR(rotate_doc,
Raymond Hettingeree33b272004-02-08 04:05:26 +0000299"Rotate the deque n steps to the right (default n=1). If n is negative, rotates left.");
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000300
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000301static int
302deque_len(dequeobject *deque)
303{
304 return deque->len;
305}
306
307static int
308deque_clear(dequeobject *deque)
309{
310 PyObject *item;
311
312 while (deque_len(deque)) {
313 item = deque_pop(deque, NULL);
314 if (item == NULL)
315 return -1;
316 Py_DECREF(item);
317 }
318 assert(deque->leftblock == deque->rightblock &&
319 deque->leftindex > deque->rightindex);
320 return 0;
321}
322
323static PyObject *
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000324deque_item(dequeobject *deque, int i)
325{
326 block *b;
327 PyObject *item;
328 int n;
329
330 if (i < 0 || i >= deque->len) {
331 PyErr_SetString(PyExc_IndexError,
332 "deque index out of range");
333 return NULL;
334 }
335
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000336 if (i == 0) {
337 i = deque->leftindex;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000338 b = deque->leftblock;
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000339 } else if (i == deque->len - 1) {
340 i = deque->rightindex;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000341 b = deque->rightblock;
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000342 } else {
343 i += deque->leftindex;
344 n = i / BLOCKLEN;
345 i %= BLOCKLEN;
346 if (i < (deque->len >> 1)) {
347 b = deque->leftblock;
348 while (n--)
349 b = b->rightlink;
350 } else {
351 n = (deque->leftindex + deque->len - 1) / BLOCKLEN - n;
352 b = deque->rightblock;
353 while (n--)
354 b = b->leftlink;
355 }
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000356 }
357 item = b->data[i];
358 Py_INCREF(item);
359 return item;
360}
361
Raymond Hettinger616f4f62004-06-26 04:42:06 +0000362/* delitem() implemented in terms of rotate for simplicity and reasonable
363 performance near the end points. If for some reason this method becomes
364 popular, it is not hard to re-implement this using direct data movement
365 (similar to code in list slice assignment) and achieve a two or threefold
366 performance boost.
367*/
368
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000369static int
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000370deque_del_item(dequeobject *deque, int i)
371{
372 PyObject *item=NULL, *minus_i=NULL, *plus_i=NULL;
373 int rv = -1;
374
375 assert (i >= 0 && i < deque->len);
376
377 minus_i = Py_BuildValue("(i)", -i);
378 if (minus_i == NULL)
379 goto fail;
380
381 plus_i = Py_BuildValue("(i)", i);
382 if (plus_i == NULL)
383 goto fail;
384
385 item = deque_rotate(deque, minus_i);
386 if (item == NULL)
387 goto fail;
388 Py_DECREF(item);
389
390 item = deque_popleft(deque, NULL);
391 if (item == NULL)
392 goto fail;
393 Py_DECREF(item);
394
395 item = deque_rotate(deque, plus_i);
396 if (item == NULL)
397 goto fail;
398
399 rv = 0;
400fail:
401 Py_XDECREF(item);
402 Py_XDECREF(minus_i);
403 Py_XDECREF(plus_i);
404 return rv;
405}
406
407static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000408deque_ass_item(dequeobject *deque, int i, PyObject *v)
409{
410 PyObject *old_value;
411 block *b;
412 int n;
413
414 if (i < 0 || i >= deque->len) {
415 PyErr_SetString(PyExc_IndexError,
416 "deque index out of range");
417 return -1;
418 }
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000419 if (v == NULL)
420 return deque_del_item(deque, i);
421
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000422 i += deque->leftindex;
423 n = i / BLOCKLEN;
424 i %= BLOCKLEN;
425 if (i < (deque->len >> 1)) {
426 b = deque->leftblock;
427 while (n--)
428 b = b->rightlink;
429 } else {
430 n = (deque->leftindex + deque->len - 1) / BLOCKLEN - n;
431 b = deque->rightblock;
432 while (n--)
433 b = b->leftlink;
434 }
435 Py_INCREF(v);
436 old_value = b->data[i];
437 b->data[i] = v;
438 Py_DECREF(old_value);
439 return 0;
440}
441
442static PyObject *
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000443deque_clearmethod(dequeobject *deque)
444{
445 if (deque_clear(deque) == -1)
446 return NULL;
447 Py_RETURN_NONE;
448}
449
450PyDoc_STRVAR(clear_doc, "Remove all elements from the deque.");
451
452static void
453deque_dealloc(dequeobject *deque)
454{
455 PyObject_GC_UnTrack(deque);
Raymond Hettinger691d8052004-05-30 07:26:47 +0000456 if (deque->weakreflist != NULL)
457 PyObject_ClearWeakRefs((PyObject *) deque);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000458 if (deque->leftblock != NULL) {
459 int err = deque_clear(deque);
460 assert(err == 0);
461 assert(deque->leftblock != NULL);
462 PyMem_Free(deque->leftblock);
463 }
464 deque->leftblock = NULL;
465 deque->rightblock = NULL;
466 deque->ob_type->tp_free(deque);
467}
468
469static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000470deque_traverse(dequeobject *deque, visitproc visit, void *arg)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000471{
472 block * b = deque->leftblock;
473 int index = deque->leftindex;
474 int err;
475 PyObject *item;
476
477 while (b != deque->rightblock || index <= deque->rightindex) {
478 item = b->data[index];
479 index++;
480 if (index == BLOCKLEN && b->rightlink != NULL) {
481 b = b->rightlink;
482 index = 0;
483 }
484 err = visit(item, arg);
485 if (err)
486 return err;
487 }
488 return 0;
489}
490
491static long
492deque_nohash(PyObject *self)
493{
494 PyErr_SetString(PyExc_TypeError, "deque objects are unhashable");
495 return -1;
496}
497
498static PyObject *
499deque_copy(PyObject *deque)
500{
501 return PyObject_CallFunctionObjArgs((PyObject *)(deque->ob_type),
502 deque, NULL);
503}
504
505PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque.");
506
507static PyObject *
508deque_reduce(dequeobject *deque)
509{
510 PyObject *seq, *args, *result;
511
512 seq = PySequence_Tuple((PyObject *)deque);
513 if (seq == NULL)
514 return NULL;
515 args = PyTuple_Pack(1, seq);
516 if (args == NULL) {
517 Py_DECREF(seq);
518 return NULL;
519 }
520 result = PyTuple_Pack(2, deque->ob_type, args);
521 Py_DECREF(seq);
522 Py_DECREF(args);
523 return result;
524}
525
526PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
527
528static PyObject *
529deque_repr(PyObject *deque)
530{
531 PyObject *aslist, *result, *fmt;
532 int i;
533
534 i = Py_ReprEnter(deque);
535 if (i != 0) {
536 if (i < 0)
537 return NULL;
538 return PyString_FromString("[...]");
539 }
540
541 aslist = PySequence_List(deque);
542 if (aslist == NULL) {
543 Py_ReprLeave(deque);
544 return NULL;
545 }
546
547 fmt = PyString_FromString("deque(%r)");
548 if (fmt == NULL) {
549 Py_DECREF(aslist);
550 Py_ReprLeave(deque);
551 return NULL;
552 }
553 result = PyString_Format(fmt, aslist);
554 Py_DECREF(fmt);
555 Py_DECREF(aslist);
556 Py_ReprLeave(deque);
557 return result;
558}
559
560static int
561deque_tp_print(PyObject *deque, FILE *fp, int flags)
562{
563 PyObject *it, *item;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000564 char *emit = ""; /* No separator emitted on first pass */
565 char *separator = ", ";
566 int i;
567
568 i = Py_ReprEnter(deque);
569 if (i != 0) {
570 if (i < 0)
571 return i;
572 fputs("[...]", fp);
573 return 0;
574 }
575
576 it = PyObject_GetIter(deque);
577 if (it == NULL)
578 return -1;
579
580 fputs("deque([", fp);
581 while ((item = PyIter_Next(it)) != NULL) {
582 fputs(emit, fp);
583 emit = separator;
584 if (PyObject_Print(item, fp, 0) != 0) {
585 Py_DECREF(item);
586 Py_DECREF(it);
587 Py_ReprLeave(deque);
588 return -1;
589 }
590 Py_DECREF(item);
591 }
592 Py_ReprLeave(deque);
593 Py_DECREF(it);
594 if (PyErr_Occurred())
595 return -1;
596 fputs("])", fp);
597 return 0;
598}
599
Raymond Hettinger738ec902004-02-29 02:15:56 +0000600static PyObject *
601deque_richcompare(PyObject *v, PyObject *w, int op)
602{
603 PyObject *it1=NULL, *it2=NULL, *x, *y;
604 int i, b, vs, ws, minlen, cmp=-1;
605
Raymond Hettinger285cfcc2004-05-18 18:15:03 +0000606 if (!PyObject_TypeCheck(v, &deque_type) ||
607 !PyObject_TypeCheck(w, &deque_type)) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000608 Py_INCREF(Py_NotImplemented);
609 return Py_NotImplemented;
610 }
611
612 /* Shortcuts */
613 vs = ((dequeobject *)v)->len;
614 ws = ((dequeobject *)w)->len;
615 if (op == Py_EQ) {
616 if (v == w)
617 Py_RETURN_TRUE;
618 if (vs != ws)
619 Py_RETURN_FALSE;
620 }
621 if (op == Py_NE) {
622 if (v == w)
623 Py_RETURN_FALSE;
624 if (vs != ws)
625 Py_RETURN_TRUE;
626 }
627
628 /* Search for the first index where items are different */
629 it1 = PyObject_GetIter(v);
630 if (it1 == NULL)
631 goto done;
632 it2 = PyObject_GetIter(w);
633 if (it2 == NULL)
634 goto done;
635 minlen = (vs < ws) ? vs : ws;
636 for (i=0 ; i < minlen ; i++) {
637 x = PyIter_Next(it1);
638 if (x == NULL)
639 goto done;
640 y = PyIter_Next(it2);
641 if (y == NULL) {
642 Py_DECREF(x);
643 goto done;
644 }
645 b = PyObject_RichCompareBool(x, y, Py_EQ);
646 if (b == 0) {
647 cmp = PyObject_RichCompareBool(x, y, op);
648 Py_DECREF(x);
649 Py_DECREF(y);
650 goto done;
651 }
652 Py_DECREF(x);
653 Py_DECREF(y);
654 if (b == -1)
655 goto done;
656 }
657 /* Elements are equal through minlen. The longest input is the greatest */
658 switch (op) {
659 case Py_LT: cmp = vs < ws; break;
660 case Py_LE: cmp = vs <= ws; break;
661 case Py_EQ: cmp = vs == ws; break;
662 case Py_NE: cmp = vs != ws; break;
663 case Py_GT: cmp = vs > ws; break;
664 case Py_GE: cmp = vs >= ws; break;
665 }
666
667done:
668 Py_XDECREF(it1);
669 Py_XDECREF(it2);
670 if (cmp == 1)
671 Py_RETURN_TRUE;
672 if (cmp == 0)
673 Py_RETURN_FALSE;
674 return NULL;
675}
676
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000677static int
678deque_init(dequeobject *deque, PyObject *args, PyObject *kwds)
679{
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000680 PyObject *iterable = NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000681
682 if (!PyArg_UnpackTuple(args, "deque", 0, 1, &iterable))
683 return -1;
684
685 if (iterable != NULL) {
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000686 PyObject *rv = deque_extend(deque, iterable);
687 if (rv == NULL)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000688 return -1;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000689 Py_DECREF(rv);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000690 }
691 return 0;
692}
693
694static PySequenceMethods deque_as_sequence = {
695 (inquiry)deque_len, /* sq_length */
696 0, /* sq_concat */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000697 0, /* sq_repeat */
698 (intargfunc)deque_item, /* sq_item */
699 0, /* sq_slice */
700 (intobjargproc)deque_ass_item, /* sq_ass_item */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000701};
702
703/* deque object ********************************************************/
704
705static PyObject *deque_iter(dequeobject *deque);
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000706static PyObject *deque_reviter(dequeobject *deque);
707PyDoc_STRVAR(reversed_doc,
708 "D.__reversed__() -- return a reverse iterator over the deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000709
710static PyMethodDef deque_methods[] = {
711 {"append", (PyCFunction)deque_append,
712 METH_O, append_doc},
713 {"appendleft", (PyCFunction)deque_appendleft,
714 METH_O, appendleft_doc},
715 {"clear", (PyCFunction)deque_clearmethod,
716 METH_NOARGS, clear_doc},
717 {"__copy__", (PyCFunction)deque_copy,
718 METH_NOARGS, copy_doc},
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000719 {"extend", (PyCFunction)deque_extend,
720 METH_O, extend_doc},
721 {"extendleft", (PyCFunction)deque_extendleft,
722 METH_O, extendleft_doc},
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000723 {"pop", (PyCFunction)deque_pop,
724 METH_NOARGS, pop_doc},
725 {"popleft", (PyCFunction)deque_popleft,
726 METH_NOARGS, popleft_doc},
727 {"__reduce__", (PyCFunction)deque_reduce,
728 METH_NOARGS, reduce_doc},
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000729 {"__reversed__", (PyCFunction)deque_reviter,
730 METH_NOARGS, reversed_doc},
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000731 {"rotate", (PyCFunction)deque_rotate,
732 METH_VARARGS, rotate_doc},
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000733 {NULL, NULL} /* sentinel */
734};
735
736PyDoc_STRVAR(deque_doc,
737"deque(iterable) --> deque object\n\
738\n\
739Build an ordered collection accessible from endpoints only.");
740
Neal Norwitz87f10132004-02-29 15:40:53 +0000741static PyTypeObject deque_type = {
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000742 PyObject_HEAD_INIT(NULL)
743 0, /* ob_size */
744 "collections.deque", /* tp_name */
745 sizeof(dequeobject), /* tp_basicsize */
746 0, /* tp_itemsize */
747 /* methods */
748 (destructor)deque_dealloc, /* tp_dealloc */
749 (printfunc)deque_tp_print, /* tp_print */
750 0, /* tp_getattr */
751 0, /* tp_setattr */
752 0, /* tp_compare */
753 (reprfunc)deque_repr, /* tp_repr */
754 0, /* tp_as_number */
755 &deque_as_sequence, /* tp_as_sequence */
756 0, /* tp_as_mapping */
757 deque_nohash, /* tp_hash */
758 0, /* tp_call */
759 0, /* tp_str */
760 PyObject_GenericGetAttr, /* tp_getattro */
761 0, /* tp_setattro */
762 0, /* tp_as_buffer */
Raymond Hettinger691d8052004-05-30 07:26:47 +0000763 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
764 Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000765 deque_doc, /* tp_doc */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000766 (traverseproc)deque_traverse, /* tp_traverse */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000767 (inquiry)deque_clear, /* tp_clear */
Raymond Hettinger738ec902004-02-29 02:15:56 +0000768 (richcmpfunc)deque_richcompare, /* tp_richcompare */
Raymond Hettinger691d8052004-05-30 07:26:47 +0000769 offsetof(dequeobject, weakreflist), /* tp_weaklistoffset*/
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000770 (getiterfunc)deque_iter, /* tp_iter */
771 0, /* tp_iternext */
772 deque_methods, /* tp_methods */
773 0, /* tp_members */
774 0, /* tp_getset */
775 0, /* tp_base */
776 0, /* tp_dict */
777 0, /* tp_descr_get */
778 0, /* tp_descr_set */
779 0, /* tp_dictoffset */
780 (initproc)deque_init, /* tp_init */
781 PyType_GenericAlloc, /* tp_alloc */
782 deque_new, /* tp_new */
783 PyObject_GC_Del, /* tp_free */
784};
785
786/*********************** Deque Iterator **************************/
787
788typedef struct {
789 PyObject_HEAD
790 int index;
791 block *b;
792 dequeobject *deque;
793 int len;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000794 int counter;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000795} dequeiterobject;
796
797PyTypeObject dequeiter_type;
798
799static PyObject *
800deque_iter(dequeobject *deque)
801{
802 dequeiterobject *it;
803
804 it = PyObject_New(dequeiterobject, &dequeiter_type);
805 if (it == NULL)
806 return NULL;
807 it->b = deque->leftblock;
808 it->index = deque->leftindex;
809 Py_INCREF(deque);
810 it->deque = deque;
811 it->len = deque->len;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000812 it->counter = deque->len;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000813 return (PyObject *)it;
814}
815
816static void
817dequeiter_dealloc(dequeiterobject *dio)
818{
819 Py_XDECREF(dio->deque);
820 dio->ob_type->tp_free(dio);
821}
822
823static PyObject *
824dequeiter_next(dequeiterobject *it)
825{
826 PyObject *item;
827 if (it->b == it->deque->rightblock && it->index > it->deque->rightindex)
828 return NULL;
829
830 if (it->len != it->deque->len) {
831 it->len = -1; /* Make this state sticky */
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000832 it->counter = 0;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000833 PyErr_SetString(PyExc_RuntimeError,
834 "deque changed size during iteration");
835 return NULL;
836 }
837
838 item = it->b->data[it->index];
839 it->index++;
840 if (it->index == BLOCKLEN && it->b->rightlink != NULL) {
841 it->b = it->b->rightlink;
842 it->index = 0;
843 }
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000844 it->counter--;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000845 Py_INCREF(item);
846 return item;
847}
848
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000849static int
850dequeiter_len(dequeiterobject *it)
851{
852 return it->counter;
853}
854
855static PySequenceMethods dequeiter_as_sequence = {
856 (inquiry)dequeiter_len, /* sq_length */
857 0, /* sq_concat */
858};
859
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000860PyTypeObject dequeiter_type = {
861 PyObject_HEAD_INIT(NULL)
862 0, /* ob_size */
863 "deque_iterator", /* tp_name */
864 sizeof(dequeiterobject), /* tp_basicsize */
865 0, /* tp_itemsize */
866 /* methods */
867 (destructor)dequeiter_dealloc, /* tp_dealloc */
868 0, /* tp_print */
869 0, /* tp_getattr */
870 0, /* tp_setattr */
871 0, /* tp_compare */
872 0, /* tp_repr */
873 0, /* tp_as_number */
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000874 &dequeiter_as_sequence, /* tp_as_sequence */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000875 0, /* tp_as_mapping */
876 0, /* tp_hash */
877 0, /* tp_call */
878 0, /* tp_str */
879 PyObject_GenericGetAttr, /* tp_getattro */
880 0, /* tp_setattro */
881 0, /* tp_as_buffer */
882 Py_TPFLAGS_DEFAULT, /* tp_flags */
883 0, /* tp_doc */
884 0, /* tp_traverse */
885 0, /* tp_clear */
886 0, /* tp_richcompare */
887 0, /* tp_weaklistoffset */
888 PyObject_SelfIter, /* tp_iter */
889 (iternextfunc)dequeiter_next, /* tp_iternext */
890 0,
891};
892
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000893/*********************** Deque Reverse Iterator **************************/
894
895PyTypeObject dequereviter_type;
896
897static PyObject *
898deque_reviter(dequeobject *deque)
899{
900 dequeiterobject *it;
901
902 it = PyObject_New(dequeiterobject, &dequereviter_type);
903 if (it == NULL)
904 return NULL;
905 it->b = deque->rightblock;
906 it->index = deque->rightindex;
907 Py_INCREF(deque);
908 it->deque = deque;
909 it->len = deque->len;
910 it->counter = deque->len;
911 return (PyObject *)it;
912}
913
914static PyObject *
915dequereviter_next(dequeiterobject *it)
916{
917 PyObject *item;
918 if (it->b == it->deque->leftblock && it->index < it->deque->leftindex)
919 return NULL;
920
921 if (it->len != it->deque->len) {
922 it->len = -1; /* Make this state sticky */
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000923 it->counter = 0;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000924 PyErr_SetString(PyExc_RuntimeError,
925 "deque changed size during iteration");
926 return NULL;
927 }
928
929 item = it->b->data[it->index];
930 it->index--;
931 if (it->index == -1 && it->b->leftlink != NULL) {
932 it->b = it->b->leftlink;
933 it->index = BLOCKLEN - 1;
934 }
935 it->counter--;
936 Py_INCREF(item);
937 return item;
938}
939
940PyTypeObject dequereviter_type = {
941 PyObject_HEAD_INIT(NULL)
942 0, /* ob_size */
943 "deque_reverse_iterator", /* tp_name */
944 sizeof(dequeiterobject), /* tp_basicsize */
945 0, /* tp_itemsize */
946 /* methods */
947 (destructor)dequeiter_dealloc, /* tp_dealloc */
948 0, /* tp_print */
949 0, /* tp_getattr */
950 0, /* tp_setattr */
951 0, /* tp_compare */
952 0, /* tp_repr */
953 0, /* tp_as_number */
954 &dequeiter_as_sequence, /* tp_as_sequence */
955 0, /* tp_as_mapping */
956 0, /* tp_hash */
957 0, /* tp_call */
958 0, /* tp_str */
959 PyObject_GenericGetAttr, /* tp_getattro */
960 0, /* tp_setattro */
961 0, /* tp_as_buffer */
962 Py_TPFLAGS_DEFAULT, /* tp_flags */
963 0, /* tp_doc */
964 0, /* tp_traverse */
965 0, /* tp_clear */
966 0, /* tp_richcompare */
967 0, /* tp_weaklistoffset */
968 PyObject_SelfIter, /* tp_iter */
969 (iternextfunc)dequereviter_next, /* tp_iternext */
970 0,
971};
972
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000973/* module level code ********************************************************/
974
975PyDoc_STRVAR(module_doc,
976"High performance data structures\n\
977");
978
979PyMODINIT_FUNC
980initcollections(void)
981{
982 PyObject *m;
983
984 m = Py_InitModule3("collections", NULL, module_doc);
985
986 if (PyType_Ready(&deque_type) < 0)
987 return;
988 Py_INCREF(&deque_type);
989 PyModule_AddObject(m, "deque", (PyObject *)&deque_type);
990
991 if (PyType_Ready(&dequeiter_type) < 0)
992 return;
993
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000994 if (PyType_Ready(&dequereviter_type) < 0)
995 return;
996
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000997 return;
998}