blob: 367b4441e28fc3df1f169f5fe266c222282d812e [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);
Raymond Hettingera435c532004-07-09 04:10:20 +0000248 if (PyErr_Occurred())
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000249 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);
Raymond Hettingera435c532004-07-09 04:10:20 +0000277 assert (item != NULL);
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000278 rv = deque_appendleft(deque, item);
279 Py_DECREF(item);
280 if (rv == NULL)
281 return NULL;
282 Py_DECREF(rv);
283 }
284 for (i=0 ; i>n ; i--) {
285 item = deque_popleft(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000286 assert (item != NULL);
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000287 rv = deque_append(deque, item);
288 Py_DECREF(item);
289 if (rv == NULL)
290 return NULL;
291 Py_DECREF(rv);
292 }
293 Py_RETURN_NONE;
294}
295
296PyDoc_STRVAR(rotate_doc,
Raymond Hettingeree33b272004-02-08 04:05:26 +0000297"Rotate the deque n steps to the right (default n=1). If n is negative, rotates left.");
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000298
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000299static int
300deque_len(dequeobject *deque)
301{
302 return deque->len;
303}
304
305static int
306deque_clear(dequeobject *deque)
307{
308 PyObject *item;
309
310 while (deque_len(deque)) {
311 item = deque_pop(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000312 assert (item != NULL);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000313 Py_DECREF(item);
314 }
315 assert(deque->leftblock == deque->rightblock &&
316 deque->leftindex > deque->rightindex);
317 return 0;
318}
319
320static PyObject *
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000321deque_item(dequeobject *deque, int i)
322{
323 block *b;
324 PyObject *item;
325 int n;
326
327 if (i < 0 || i >= deque->len) {
328 PyErr_SetString(PyExc_IndexError,
329 "deque index out of range");
330 return NULL;
331 }
332
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000333 if (i == 0) {
334 i = deque->leftindex;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000335 b = deque->leftblock;
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000336 } else if (i == deque->len - 1) {
337 i = deque->rightindex;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000338 b = deque->rightblock;
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000339 } else {
340 i += deque->leftindex;
341 n = i / BLOCKLEN;
342 i %= BLOCKLEN;
343 if (i < (deque->len >> 1)) {
344 b = deque->leftblock;
345 while (n--)
346 b = b->rightlink;
347 } else {
348 n = (deque->leftindex + deque->len - 1) / BLOCKLEN - n;
349 b = deque->rightblock;
350 while (n--)
351 b = b->leftlink;
352 }
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000353 }
354 item = b->data[i];
355 Py_INCREF(item);
356 return item;
357}
358
Raymond Hettinger616f4f62004-06-26 04:42:06 +0000359/* delitem() implemented in terms of rotate for simplicity and reasonable
360 performance near the end points. If for some reason this method becomes
361 popular, it is not hard to re-implement this using direct data movement
362 (similar to code in list slice assignment) and achieve a two or threefold
363 performance boost.
364*/
365
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000366static int
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000367deque_del_item(dequeobject *deque, int i)
368{
369 PyObject *item=NULL, *minus_i=NULL, *plus_i=NULL;
370 int rv = -1;
371
372 assert (i >= 0 && i < deque->len);
373
374 minus_i = Py_BuildValue("(i)", -i);
375 if (minus_i == NULL)
376 goto fail;
377
378 plus_i = Py_BuildValue("(i)", i);
379 if (plus_i == NULL)
380 goto fail;
381
382 item = deque_rotate(deque, minus_i);
383 if (item == NULL)
384 goto fail;
385 Py_DECREF(item);
386
387 item = deque_popleft(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000388 assert (item != NULL);
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000389 Py_DECREF(item);
390
391 item = deque_rotate(deque, plus_i);
392 if (item == NULL)
393 goto fail;
394
395 rv = 0;
396fail:
397 Py_XDECREF(item);
398 Py_XDECREF(minus_i);
399 Py_XDECREF(plus_i);
400 return rv;
401}
402
403static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000404deque_ass_item(dequeobject *deque, int i, PyObject *v)
405{
406 PyObject *old_value;
407 block *b;
Raymond Hettingera435c532004-07-09 04:10:20 +0000408 int n, len=deque->len, halflen=(len+1)>>1, index=i;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000409
Raymond Hettingera435c532004-07-09 04:10:20 +0000410 if (i < 0 || i >= len) {
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000411 PyErr_SetString(PyExc_IndexError,
412 "deque index out of range");
413 return -1;
414 }
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000415 if (v == NULL)
416 return deque_del_item(deque, i);
417
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000418 i += deque->leftindex;
419 n = i / BLOCKLEN;
420 i %= BLOCKLEN;
Raymond Hettingera435c532004-07-09 04:10:20 +0000421 if (index <= halflen) {
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000422 b = deque->leftblock;
423 while (n--)
424 b = b->rightlink;
425 } else {
Raymond Hettingera435c532004-07-09 04:10:20 +0000426 n = (deque->leftindex + len - 1) / BLOCKLEN - n;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000427 b = deque->rightblock;
428 while (n--)
429 b = b->leftlink;
430 }
431 Py_INCREF(v);
432 old_value = b->data[i];
433 b->data[i] = v;
434 Py_DECREF(old_value);
435 return 0;
436}
437
438static PyObject *
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000439deque_clearmethod(dequeobject *deque)
440{
Raymond Hettingera435c532004-07-09 04:10:20 +0000441 int rv;
442
443 rv = deque_clear(deque);
444 assert (rv != -1);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000445 Py_RETURN_NONE;
446}
447
448PyDoc_STRVAR(clear_doc, "Remove all elements from the deque.");
449
450static void
451deque_dealloc(dequeobject *deque)
452{
453 PyObject_GC_UnTrack(deque);
Raymond Hettinger691d8052004-05-30 07:26:47 +0000454 if (deque->weakreflist != NULL)
455 PyObject_ClearWeakRefs((PyObject *) deque);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000456 if (deque->leftblock != NULL) {
457 int err = deque_clear(deque);
458 assert(err == 0);
459 assert(deque->leftblock != NULL);
460 PyMem_Free(deque->leftblock);
461 }
462 deque->leftblock = NULL;
463 deque->rightblock = NULL;
464 deque->ob_type->tp_free(deque);
465}
466
467static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000468deque_traverse(dequeobject *deque, visitproc visit, void *arg)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000469{
470 block * b = deque->leftblock;
471 int index = deque->leftindex;
472 int err;
473 PyObject *item;
474
475 while (b != deque->rightblock || index <= deque->rightindex) {
476 item = b->data[index];
477 index++;
478 if (index == BLOCKLEN && b->rightlink != NULL) {
479 b = b->rightlink;
480 index = 0;
481 }
482 err = visit(item, arg);
483 if (err)
484 return err;
485 }
486 return 0;
487}
488
489static long
490deque_nohash(PyObject *self)
491{
492 PyErr_SetString(PyExc_TypeError, "deque objects are unhashable");
493 return -1;
494}
495
496static PyObject *
497deque_copy(PyObject *deque)
498{
499 return PyObject_CallFunctionObjArgs((PyObject *)(deque->ob_type),
500 deque, NULL);
501}
502
503PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque.");
504
505static PyObject *
506deque_reduce(dequeobject *deque)
507{
508 PyObject *seq, *args, *result;
509
510 seq = PySequence_Tuple((PyObject *)deque);
511 if (seq == NULL)
512 return NULL;
513 args = PyTuple_Pack(1, seq);
514 if (args == NULL) {
515 Py_DECREF(seq);
516 return NULL;
517 }
518 result = PyTuple_Pack(2, deque->ob_type, args);
519 Py_DECREF(seq);
520 Py_DECREF(args);
521 return result;
522}
523
524PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
525
526static PyObject *
527deque_repr(PyObject *deque)
528{
529 PyObject *aslist, *result, *fmt;
530 int i;
531
532 i = Py_ReprEnter(deque);
533 if (i != 0) {
534 if (i < 0)
535 return NULL;
536 return PyString_FromString("[...]");
537 }
538
539 aslist = PySequence_List(deque);
540 if (aslist == NULL) {
541 Py_ReprLeave(deque);
542 return NULL;
543 }
544
545 fmt = PyString_FromString("deque(%r)");
546 if (fmt == NULL) {
547 Py_DECREF(aslist);
548 Py_ReprLeave(deque);
549 return NULL;
550 }
551 result = PyString_Format(fmt, aslist);
552 Py_DECREF(fmt);
553 Py_DECREF(aslist);
554 Py_ReprLeave(deque);
555 return result;
556}
557
558static int
559deque_tp_print(PyObject *deque, FILE *fp, int flags)
560{
561 PyObject *it, *item;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000562 char *emit = ""; /* No separator emitted on first pass */
563 char *separator = ", ";
564 int i;
565
566 i = Py_ReprEnter(deque);
567 if (i != 0) {
568 if (i < 0)
569 return i;
570 fputs("[...]", fp);
571 return 0;
572 }
573
574 it = PyObject_GetIter(deque);
575 if (it == NULL)
576 return -1;
577
578 fputs("deque([", fp);
579 while ((item = PyIter_Next(it)) != NULL) {
580 fputs(emit, fp);
581 emit = separator;
582 if (PyObject_Print(item, fp, 0) != 0) {
583 Py_DECREF(item);
584 Py_DECREF(it);
585 Py_ReprLeave(deque);
586 return -1;
587 }
588 Py_DECREF(item);
589 }
590 Py_ReprLeave(deque);
591 Py_DECREF(it);
592 if (PyErr_Occurred())
593 return -1;
594 fputs("])", fp);
595 return 0;
596}
597
Raymond Hettinger738ec902004-02-29 02:15:56 +0000598static PyObject *
599deque_richcompare(PyObject *v, PyObject *w, int op)
600{
601 PyObject *it1=NULL, *it2=NULL, *x, *y;
602 int i, b, vs, ws, minlen, cmp=-1;
603
Raymond Hettinger285cfcc2004-05-18 18:15:03 +0000604 if (!PyObject_TypeCheck(v, &deque_type) ||
605 !PyObject_TypeCheck(w, &deque_type)) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000606 Py_INCREF(Py_NotImplemented);
607 return Py_NotImplemented;
608 }
609
610 /* Shortcuts */
611 vs = ((dequeobject *)v)->len;
612 ws = ((dequeobject *)w)->len;
613 if (op == Py_EQ) {
614 if (v == w)
615 Py_RETURN_TRUE;
616 if (vs != ws)
617 Py_RETURN_FALSE;
618 }
619 if (op == Py_NE) {
620 if (v == w)
621 Py_RETURN_FALSE;
622 if (vs != ws)
623 Py_RETURN_TRUE;
624 }
625
626 /* Search for the first index where items are different */
627 it1 = PyObject_GetIter(v);
628 if (it1 == NULL)
629 goto done;
630 it2 = PyObject_GetIter(w);
631 if (it2 == NULL)
632 goto done;
633 minlen = (vs < ws) ? vs : ws;
634 for (i=0 ; i < minlen ; i++) {
635 x = PyIter_Next(it1);
636 if (x == NULL)
637 goto done;
638 y = PyIter_Next(it2);
639 if (y == NULL) {
640 Py_DECREF(x);
641 goto done;
642 }
643 b = PyObject_RichCompareBool(x, y, Py_EQ);
644 if (b == 0) {
645 cmp = PyObject_RichCompareBool(x, y, op);
646 Py_DECREF(x);
647 Py_DECREF(y);
648 goto done;
649 }
650 Py_DECREF(x);
651 Py_DECREF(y);
652 if (b == -1)
653 goto done;
654 }
655 /* Elements are equal through minlen. The longest input is the greatest */
656 switch (op) {
657 case Py_LT: cmp = vs < ws; break;
658 case Py_LE: cmp = vs <= ws; break;
659 case Py_EQ: cmp = vs == ws; break;
660 case Py_NE: cmp = vs != ws; break;
661 case Py_GT: cmp = vs > ws; break;
662 case Py_GE: cmp = vs >= ws; break;
663 }
664
665done:
666 Py_XDECREF(it1);
667 Py_XDECREF(it2);
668 if (cmp == 1)
669 Py_RETURN_TRUE;
670 if (cmp == 0)
671 Py_RETURN_FALSE;
672 return NULL;
673}
674
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000675static int
676deque_init(dequeobject *deque, PyObject *args, PyObject *kwds)
677{
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000678 PyObject *iterable = NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000679
680 if (!PyArg_UnpackTuple(args, "deque", 0, 1, &iterable))
681 return -1;
682
683 if (iterable != NULL) {
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000684 PyObject *rv = deque_extend(deque, iterable);
685 if (rv == NULL)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000686 return -1;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000687 Py_DECREF(rv);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000688 }
689 return 0;
690}
691
692static PySequenceMethods deque_as_sequence = {
693 (inquiry)deque_len, /* sq_length */
694 0, /* sq_concat */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000695 0, /* sq_repeat */
696 (intargfunc)deque_item, /* sq_item */
697 0, /* sq_slice */
698 (intobjargproc)deque_ass_item, /* sq_ass_item */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000699};
700
701/* deque object ********************************************************/
702
703static PyObject *deque_iter(dequeobject *deque);
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000704static PyObject *deque_reviter(dequeobject *deque);
705PyDoc_STRVAR(reversed_doc,
706 "D.__reversed__() -- return a reverse iterator over the deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000707
708static PyMethodDef deque_methods[] = {
709 {"append", (PyCFunction)deque_append,
710 METH_O, append_doc},
711 {"appendleft", (PyCFunction)deque_appendleft,
712 METH_O, appendleft_doc},
713 {"clear", (PyCFunction)deque_clearmethod,
714 METH_NOARGS, clear_doc},
715 {"__copy__", (PyCFunction)deque_copy,
716 METH_NOARGS, copy_doc},
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000717 {"extend", (PyCFunction)deque_extend,
718 METH_O, extend_doc},
719 {"extendleft", (PyCFunction)deque_extendleft,
720 METH_O, extendleft_doc},
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000721 {"pop", (PyCFunction)deque_pop,
722 METH_NOARGS, pop_doc},
723 {"popleft", (PyCFunction)deque_popleft,
724 METH_NOARGS, popleft_doc},
725 {"__reduce__", (PyCFunction)deque_reduce,
726 METH_NOARGS, reduce_doc},
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000727 {"__reversed__", (PyCFunction)deque_reviter,
728 METH_NOARGS, reversed_doc},
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000729 {"rotate", (PyCFunction)deque_rotate,
730 METH_VARARGS, rotate_doc},
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000731 {NULL, NULL} /* sentinel */
732};
733
734PyDoc_STRVAR(deque_doc,
735"deque(iterable) --> deque object\n\
736\n\
737Build an ordered collection accessible from endpoints only.");
738
Neal Norwitz87f10132004-02-29 15:40:53 +0000739static PyTypeObject deque_type = {
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000740 PyObject_HEAD_INIT(NULL)
741 0, /* ob_size */
742 "collections.deque", /* tp_name */
743 sizeof(dequeobject), /* tp_basicsize */
744 0, /* tp_itemsize */
745 /* methods */
746 (destructor)deque_dealloc, /* tp_dealloc */
747 (printfunc)deque_tp_print, /* tp_print */
748 0, /* tp_getattr */
749 0, /* tp_setattr */
750 0, /* tp_compare */
751 (reprfunc)deque_repr, /* tp_repr */
752 0, /* tp_as_number */
753 &deque_as_sequence, /* tp_as_sequence */
754 0, /* tp_as_mapping */
755 deque_nohash, /* tp_hash */
756 0, /* tp_call */
757 0, /* tp_str */
758 PyObject_GenericGetAttr, /* tp_getattro */
759 0, /* tp_setattro */
760 0, /* tp_as_buffer */
Raymond Hettinger691d8052004-05-30 07:26:47 +0000761 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
762 Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000763 deque_doc, /* tp_doc */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000764 (traverseproc)deque_traverse, /* tp_traverse */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000765 (inquiry)deque_clear, /* tp_clear */
Raymond Hettinger738ec902004-02-29 02:15:56 +0000766 (richcmpfunc)deque_richcompare, /* tp_richcompare */
Raymond Hettinger691d8052004-05-30 07:26:47 +0000767 offsetof(dequeobject, weakreflist), /* tp_weaklistoffset*/
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000768 (getiterfunc)deque_iter, /* tp_iter */
769 0, /* tp_iternext */
770 deque_methods, /* tp_methods */
771 0, /* tp_members */
772 0, /* tp_getset */
773 0, /* tp_base */
774 0, /* tp_dict */
775 0, /* tp_descr_get */
776 0, /* tp_descr_set */
777 0, /* tp_dictoffset */
778 (initproc)deque_init, /* tp_init */
779 PyType_GenericAlloc, /* tp_alloc */
780 deque_new, /* tp_new */
781 PyObject_GC_Del, /* tp_free */
782};
783
784/*********************** Deque Iterator **************************/
785
786typedef struct {
787 PyObject_HEAD
788 int index;
789 block *b;
790 dequeobject *deque;
791 int len;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000792 int counter;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000793} dequeiterobject;
794
795PyTypeObject dequeiter_type;
796
797static PyObject *
798deque_iter(dequeobject *deque)
799{
800 dequeiterobject *it;
801
802 it = PyObject_New(dequeiterobject, &dequeiter_type);
803 if (it == NULL)
804 return NULL;
805 it->b = deque->leftblock;
806 it->index = deque->leftindex;
807 Py_INCREF(deque);
808 it->deque = deque;
809 it->len = deque->len;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000810 it->counter = deque->len;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000811 return (PyObject *)it;
812}
813
814static void
815dequeiter_dealloc(dequeiterobject *dio)
816{
817 Py_XDECREF(dio->deque);
818 dio->ob_type->tp_free(dio);
819}
820
821static PyObject *
822dequeiter_next(dequeiterobject *it)
823{
824 PyObject *item;
825 if (it->b == it->deque->rightblock && it->index > it->deque->rightindex)
826 return NULL;
827
828 if (it->len != it->deque->len) {
829 it->len = -1; /* Make this state sticky */
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000830 it->counter = 0;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000831 PyErr_SetString(PyExc_RuntimeError,
832 "deque changed size during iteration");
833 return NULL;
834 }
835
836 item = it->b->data[it->index];
837 it->index++;
838 if (it->index == BLOCKLEN && it->b->rightlink != NULL) {
839 it->b = it->b->rightlink;
840 it->index = 0;
841 }
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000842 it->counter--;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000843 Py_INCREF(item);
844 return item;
845}
846
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000847static int
848dequeiter_len(dequeiterobject *it)
849{
850 return it->counter;
851}
852
853static PySequenceMethods dequeiter_as_sequence = {
854 (inquiry)dequeiter_len, /* sq_length */
855 0, /* sq_concat */
856};
857
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000858PyTypeObject dequeiter_type = {
859 PyObject_HEAD_INIT(NULL)
860 0, /* ob_size */
861 "deque_iterator", /* tp_name */
862 sizeof(dequeiterobject), /* tp_basicsize */
863 0, /* tp_itemsize */
864 /* methods */
865 (destructor)dequeiter_dealloc, /* tp_dealloc */
866 0, /* tp_print */
867 0, /* tp_getattr */
868 0, /* tp_setattr */
869 0, /* tp_compare */
870 0, /* tp_repr */
871 0, /* tp_as_number */
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000872 &dequeiter_as_sequence, /* tp_as_sequence */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000873 0, /* tp_as_mapping */
874 0, /* tp_hash */
875 0, /* tp_call */
876 0, /* tp_str */
877 PyObject_GenericGetAttr, /* tp_getattro */
878 0, /* tp_setattro */
879 0, /* tp_as_buffer */
880 Py_TPFLAGS_DEFAULT, /* tp_flags */
881 0, /* tp_doc */
882 0, /* tp_traverse */
883 0, /* tp_clear */
884 0, /* tp_richcompare */
885 0, /* tp_weaklistoffset */
886 PyObject_SelfIter, /* tp_iter */
887 (iternextfunc)dequeiter_next, /* tp_iternext */
888 0,
889};
890
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000891/*********************** Deque Reverse Iterator **************************/
892
893PyTypeObject dequereviter_type;
894
895static PyObject *
896deque_reviter(dequeobject *deque)
897{
898 dequeiterobject *it;
899
900 it = PyObject_New(dequeiterobject, &dequereviter_type);
901 if (it == NULL)
902 return NULL;
903 it->b = deque->rightblock;
904 it->index = deque->rightindex;
905 Py_INCREF(deque);
906 it->deque = deque;
907 it->len = deque->len;
908 it->counter = deque->len;
909 return (PyObject *)it;
910}
911
912static PyObject *
913dequereviter_next(dequeiterobject *it)
914{
915 PyObject *item;
916 if (it->b == it->deque->leftblock && it->index < it->deque->leftindex)
917 return NULL;
918
919 if (it->len != it->deque->len) {
920 it->len = -1; /* Make this state sticky */
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000921 it->counter = 0;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000922 PyErr_SetString(PyExc_RuntimeError,
923 "deque changed size during iteration");
924 return NULL;
925 }
926
927 item = it->b->data[it->index];
928 it->index--;
929 if (it->index == -1 && it->b->leftlink != NULL) {
930 it->b = it->b->leftlink;
931 it->index = BLOCKLEN - 1;
932 }
933 it->counter--;
934 Py_INCREF(item);
935 return item;
936}
937
938PyTypeObject dequereviter_type = {
939 PyObject_HEAD_INIT(NULL)
940 0, /* ob_size */
941 "deque_reverse_iterator", /* tp_name */
942 sizeof(dequeiterobject), /* tp_basicsize */
943 0, /* tp_itemsize */
944 /* methods */
945 (destructor)dequeiter_dealloc, /* tp_dealloc */
946 0, /* tp_print */
947 0, /* tp_getattr */
948 0, /* tp_setattr */
949 0, /* tp_compare */
950 0, /* tp_repr */
951 0, /* tp_as_number */
952 &dequeiter_as_sequence, /* tp_as_sequence */
953 0, /* tp_as_mapping */
954 0, /* tp_hash */
955 0, /* tp_call */
956 0, /* tp_str */
957 PyObject_GenericGetAttr, /* tp_getattro */
958 0, /* tp_setattro */
959 0, /* tp_as_buffer */
960 Py_TPFLAGS_DEFAULT, /* tp_flags */
961 0, /* tp_doc */
962 0, /* tp_traverse */
963 0, /* tp_clear */
964 0, /* tp_richcompare */
965 0, /* tp_weaklistoffset */
966 PyObject_SelfIter, /* tp_iter */
967 (iternextfunc)dequereviter_next, /* tp_iternext */
968 0,
969};
970
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000971/* module level code ********************************************************/
972
973PyDoc_STRVAR(module_doc,
974"High performance data structures\n\
975");
976
977PyMODINIT_FUNC
978initcollections(void)
979{
980 PyObject *m;
981
982 m = Py_InitModule3("collections", NULL, module_doc);
983
984 if (PyType_Ready(&deque_type) < 0)
985 return;
986 Py_INCREF(&deque_type);
987 PyModule_AddObject(m, "deque", (PyObject *)&deque_type);
988
989 if (PyType_Ready(&dequeiter_type) < 0)
990 return;
991
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000992 if (PyType_Ready(&dequereviter_type) < 0)
993 return;
994
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000995 return;
996}