blob: 5856b11dd674b08ab96616ea7a2e6b976b34b1d4 [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
Tim Peters6f853562004-10-01 01:04:50 +000018static block *
19newblock(block *leftlink, block *rightlink) {
Raymond Hettinger756b3f32004-01-29 06:37:52 +000020 block *b = PyMem_Malloc(sizeof(block));
21 if (b == NULL) {
22 PyErr_NoMemory();
23 return NULL;
24 }
25 b->leftlink = leftlink;
26 b->rightlink = rightlink;
27 return b;
28}
29
30typedef struct {
31 PyObject_HEAD
32 block *leftblock;
33 block *rightblock;
34 int leftindex;
35 int rightindex;
36 int len;
Raymond Hettinger691d8052004-05-30 07:26:47 +000037 PyObject *weakreflist; /* List of weak references */
Raymond Hettinger756b3f32004-01-29 06:37:52 +000038} dequeobject;
39
Neal Norwitz87f10132004-02-29 15:40:53 +000040static PyTypeObject deque_type;
Raymond Hettinger738ec902004-02-29 02:15:56 +000041
Raymond Hettinger756b3f32004-01-29 06:37:52 +000042static PyObject *
43deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
44{
45 dequeobject *deque;
46 block *b;
47
48 /* create dequeobject structure */
49 deque = (dequeobject *)type->tp_alloc(type, 0);
50 if (deque == NULL)
51 return NULL;
Tim Peters1065f752004-10-01 01:03:29 +000052
Raymond Hettinger756b3f32004-01-29 06:37:52 +000053 b = newblock(NULL, NULL);
54 if (b == NULL) {
55 Py_DECREF(deque);
56 return NULL;
57 }
58
59 deque->leftblock = b;
60 deque->rightblock = b;
61 deque->leftindex = BLOCKLEN / 2 + 1;
62 deque->rightindex = BLOCKLEN / 2;
63 deque->len = 0;
Raymond Hettinger691d8052004-05-30 07:26:47 +000064 deque->weakreflist = NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +000065
66 return (PyObject *)deque;
67}
68
69static PyObject *
70deque_append(dequeobject *deque, PyObject *item)
71{
72 deque->rightindex++;
73 deque->len++;
74 if (deque->rightindex == BLOCKLEN) {
75 block *b = newblock(deque->rightblock, NULL);
76 if (b == NULL)
77 return NULL;
78 assert(deque->rightblock->rightlink == NULL);
79 deque->rightblock->rightlink = b;
80 deque->rightblock = b;
81 deque->rightindex = 0;
82 }
83 Py_INCREF(item);
84 deque->rightblock->data[deque->rightindex] = item;
85 Py_RETURN_NONE;
86}
87
88PyDoc_STRVAR(append_doc, "Add an element to the right side of the deque.");
89
90static PyObject *
91deque_appendleft(dequeobject *deque, PyObject *item)
92{
93 deque->leftindex--;
94 deque->len++;
95 if (deque->leftindex == -1) {
96 block *b = newblock(NULL, deque->leftblock);
97 if (b == NULL)
98 return NULL;
99 assert(deque->leftblock->leftlink == NULL);
100 deque->leftblock->leftlink = b;
101 deque->leftblock = b;
102 deque->leftindex = BLOCKLEN - 1;
103 }
104 Py_INCREF(item);
105 deque->leftblock->data[deque->leftindex] = item;
106 Py_RETURN_NONE;
107}
108
109PyDoc_STRVAR(appendleft_doc, "Add an element to the left side of the deque.");
110
111static PyObject *
112deque_pop(dequeobject *deque, PyObject *unused)
113{
114 PyObject *item;
115 block *prevblock;
116
117 if (deque->len == 0) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000118 PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000119 return NULL;
120 }
121 item = deque->rightblock->data[deque->rightindex];
122 deque->rightindex--;
123 deque->len--;
124
125 if (deque->rightindex == -1) {
126 if (deque->len == 0) {
127 assert(deque->leftblock == deque->rightblock);
128 assert(deque->leftindex == deque->rightindex+1);
129 /* re-center instead of freeing a block */
130 deque->leftindex = BLOCKLEN / 2 + 1;
131 deque->rightindex = BLOCKLEN / 2;
132 } else {
133 prevblock = deque->rightblock->leftlink;
134 assert(deque->leftblock != deque->rightblock);
135 PyMem_Free(deque->rightblock);
136 prevblock->rightlink = NULL;
137 deque->rightblock = prevblock;
138 deque->rightindex = BLOCKLEN - 1;
139 }
140 }
141 return item;
142}
143
144PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element.");
145
146static PyObject *
147deque_popleft(dequeobject *deque, PyObject *unused)
148{
149 PyObject *item;
150 block *prevblock;
151
152 if (deque->len == 0) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000153 PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000154 return NULL;
155 }
156 item = deque->leftblock->data[deque->leftindex];
157 deque->leftindex++;
158 deque->len--;
159
160 if (deque->leftindex == BLOCKLEN) {
161 if (deque->len == 0) {
162 assert(deque->leftblock == deque->rightblock);
163 assert(deque->leftindex == deque->rightindex+1);
164 /* re-center instead of freeing a block */
165 deque->leftindex = BLOCKLEN / 2 + 1;
166 deque->rightindex = BLOCKLEN / 2;
167 } else {
168 assert(deque->leftblock != deque->rightblock);
169 prevblock = deque->leftblock->rightlink;
170 assert(deque->leftblock != NULL);
171 PyMem_Free(deque->leftblock);
172 assert(prevblock != NULL);
173 prevblock->leftlink = NULL;
174 deque->leftblock = prevblock;
175 deque->leftindex = 0;
176 }
177 }
178 return item;
179}
180
181PyDoc_STRVAR(popleft_doc, "Remove and return the leftmost element.");
182
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000183static PyObject *
184deque_extend(dequeobject *deque, PyObject *iterable)
185{
186 PyObject *it, *item;
187
188 it = PyObject_GetIter(iterable);
189 if (it == NULL)
190 return NULL;
191
192 while ((item = PyIter_Next(it)) != NULL) {
193 deque->rightindex++;
194 deque->len++;
195 if (deque->rightindex == BLOCKLEN) {
196 block *b = newblock(deque->rightblock, NULL);
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000197 if (b == NULL) {
198 Py_DECREF(item);
199 Py_DECREF(it);
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000200 return NULL;
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000201 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000202 assert(deque->rightblock->rightlink == NULL);
203 deque->rightblock->rightlink = b;
204 deque->rightblock = b;
205 deque->rightindex = 0;
206 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000207 deque->rightblock->data[deque->rightindex] = item;
208 }
209 Py_DECREF(it);
Tim Peters1065f752004-10-01 01:03:29 +0000210 if (PyErr_Occurred())
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000211 return NULL;
212 Py_RETURN_NONE;
213}
214
Tim Peters1065f752004-10-01 01:03:29 +0000215PyDoc_STRVAR(extend_doc,
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000216"Extend the right side of the deque with elements from the iterable");
217
218static PyObject *
219deque_extendleft(dequeobject *deque, PyObject *iterable)
220{
221 PyObject *it, *item;
222
223 it = PyObject_GetIter(iterable);
224 if (it == NULL)
225 return NULL;
226
227 while ((item = PyIter_Next(it)) != NULL) {
228 deque->leftindex--;
229 deque->len++;
230 if (deque->leftindex == -1) {
231 block *b = newblock(NULL, deque->leftblock);
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000232 if (b == NULL) {
233 Py_DECREF(item);
234 Py_DECREF(it);
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000235 return NULL;
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000236 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000237 assert(deque->leftblock->leftlink == NULL);
238 deque->leftblock->leftlink = b;
239 deque->leftblock = b;
240 deque->leftindex = BLOCKLEN - 1;
241 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000242 deque->leftblock->data[deque->leftindex] = item;
243 }
244 Py_DECREF(it);
Raymond Hettingera435c532004-07-09 04:10:20 +0000245 if (PyErr_Occurred())
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000246 return NULL;
247 Py_RETURN_NONE;
248}
249
Tim Peters1065f752004-10-01 01:03:29 +0000250PyDoc_STRVAR(extendleft_doc,
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000251"Extend the left side of the deque with elements from the iterable");
252
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000253static PyObject *
254deque_rotate(dequeobject *deque, PyObject *args)
255{
Raymond Hettingeree33b272004-02-08 04:05:26 +0000256 int i, n=1, len=deque->len, halflen=(len+1)>>1;
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000257 PyObject *item, *rv;
258
Raymond Hettingeree33b272004-02-08 04:05:26 +0000259 if (!PyArg_ParseTuple(args, "|i:rotate", &n))
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000260 return NULL;
261
Raymond Hettingeree33b272004-02-08 04:05:26 +0000262 if (len == 0)
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000263 Py_RETURN_NONE;
Raymond Hettingeree33b272004-02-08 04:05:26 +0000264 if (n > halflen || n < -halflen) {
265 n %= len;
266 if (n > halflen)
267 n -= len;
268 else if (n < -halflen)
269 n += len;
270 }
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000271
272 for (i=0 ; i<n ; i++) {
273 item = deque_pop(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000274 assert (item != NULL);
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000275 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);
Raymond Hettingera435c532004-07-09 04:10:20 +0000283 assert (item != NULL);
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000284 rv = deque_append(deque, item);
285 Py_DECREF(item);
286 if (rv == NULL)
287 return NULL;
288 Py_DECREF(rv);
289 }
290 Py_RETURN_NONE;
291}
292
Tim Peters1065f752004-10-01 01:03:29 +0000293PyDoc_STRVAR(rotate_doc,
Raymond Hettingeree33b272004-02-08 04:05:26 +0000294"Rotate the deque n steps to the right (default n=1). If n is negative, rotates left.");
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000295
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000296static int
297deque_len(dequeobject *deque)
298{
299 return deque->len;
300}
301
302static int
303deque_clear(dequeobject *deque)
304{
305 PyObject *item;
306
307 while (deque_len(deque)) {
308 item = deque_pop(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000309 assert (item != NULL);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000310 Py_DECREF(item);
311 }
312 assert(deque->leftblock == deque->rightblock &&
313 deque->leftindex > deque->rightindex);
314 return 0;
315}
316
317static PyObject *
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000318deque_item(dequeobject *deque, int i)
319{
320 block *b;
321 PyObject *item;
322 int n;
323
324 if (i < 0 || i >= deque->len) {
325 PyErr_SetString(PyExc_IndexError,
326 "deque index out of range");
327 return NULL;
328 }
329
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000330 if (i == 0) {
331 i = deque->leftindex;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000332 b = deque->leftblock;
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000333 } else if (i == deque->len - 1) {
334 i = deque->rightindex;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000335 b = deque->rightblock;
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000336 } else {
337 i += deque->leftindex;
338 n = i / BLOCKLEN;
339 i %= BLOCKLEN;
340 if (i < (deque->len >> 1)) {
341 b = deque->leftblock;
342 while (n--)
343 b = b->rightlink;
344 } else {
345 n = (deque->leftindex + deque->len - 1) / BLOCKLEN - n;
346 b = deque->rightblock;
347 while (n--)
348 b = b->leftlink;
349 }
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000350 }
351 item = b->data[i];
352 Py_INCREF(item);
353 return item;
354}
355
Raymond Hettinger616f4f62004-06-26 04:42:06 +0000356/* delitem() implemented in terms of rotate for simplicity and reasonable
357 performance near the end points. If for some reason this method becomes
Tim Peters1065f752004-10-01 01:03:29 +0000358 popular, it is not hard to re-implement this using direct data movement
Raymond Hettinger616f4f62004-06-26 04:42:06 +0000359 (similar to code in list slice assignment) and achieve a two or threefold
360 performance boost.
361*/
362
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000363static int
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000364deque_del_item(dequeobject *deque, int i)
365{
366 PyObject *item=NULL, *minus_i=NULL, *plus_i=NULL;
367 int rv = -1;
368
Tim Peters1065f752004-10-01 01:03:29 +0000369 assert (i >= 0 && i < deque->len);
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000370
371 minus_i = Py_BuildValue("(i)", -i);
372 if (minus_i == NULL)
373 goto fail;
374
375 plus_i = Py_BuildValue("(i)", i);
376 if (plus_i == NULL)
377 goto fail;
378
379 item = deque_rotate(deque, minus_i);
Tim Peters1065f752004-10-01 01:03:29 +0000380 if (item == NULL)
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000381 goto fail;
382 Py_DECREF(item);
383
384 item = deque_popleft(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000385 assert (item != NULL);
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000386 Py_DECREF(item);
387
388 item = deque_rotate(deque, plus_i);
Tim Peters1065f752004-10-01 01:03:29 +0000389 if (item == NULL)
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000390 goto fail;
391
392 rv = 0;
393fail:
394 Py_XDECREF(item);
395 Py_XDECREF(minus_i);
396 Py_XDECREF(plus_i);
397 return rv;
398}
399
400static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000401deque_ass_item(dequeobject *deque, int i, PyObject *v)
402{
403 PyObject *old_value;
404 block *b;
Raymond Hettingera435c532004-07-09 04:10:20 +0000405 int n, len=deque->len, halflen=(len+1)>>1, index=i;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000406
Raymond Hettingera435c532004-07-09 04:10:20 +0000407 if (i < 0 || i >= len) {
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000408 PyErr_SetString(PyExc_IndexError,
409 "deque index out of range");
410 return -1;
411 }
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000412 if (v == NULL)
413 return deque_del_item(deque, i);
414
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000415 i += deque->leftindex;
416 n = i / BLOCKLEN;
417 i %= BLOCKLEN;
Raymond Hettingera435c532004-07-09 04:10:20 +0000418 if (index <= halflen) {
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000419 b = deque->leftblock;
420 while (n--)
421 b = b->rightlink;
422 } else {
Raymond Hettingera435c532004-07-09 04:10:20 +0000423 n = (deque->leftindex + len - 1) / BLOCKLEN - n;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000424 b = deque->rightblock;
425 while (n--)
426 b = b->leftlink;
427 }
428 Py_INCREF(v);
429 old_value = b->data[i];
430 b->data[i] = v;
431 Py_DECREF(old_value);
432 return 0;
433}
434
435static PyObject *
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000436deque_clearmethod(dequeobject *deque)
437{
Raymond Hettingera435c532004-07-09 04:10:20 +0000438 int rv;
439
440 rv = deque_clear(deque);
441 assert (rv != -1);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000442 Py_RETURN_NONE;
443}
444
445PyDoc_STRVAR(clear_doc, "Remove all elements from the deque.");
446
447static void
448deque_dealloc(dequeobject *deque)
449{
450 PyObject_GC_UnTrack(deque);
Raymond Hettinger691d8052004-05-30 07:26:47 +0000451 if (deque->weakreflist != NULL)
452 PyObject_ClearWeakRefs((PyObject *) deque);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000453 if (deque->leftblock != NULL) {
Raymond Hettingere9c89e82004-07-19 00:10:24 +0000454 deque_clear(deque);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000455 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;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000468 PyObject *item;
469
470 while (b != deque->rightblock || index <= deque->rightindex) {
471 item = b->data[index];
472 index++;
Raymond Hettinger67115a22004-07-15 21:32:18 +0000473 if (index == BLOCKLEN ) {
474 assert(b->rightlink != NULL);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000475 b = b->rightlink;
476 index = 0;
477 }
Raymond Hettinger67115a22004-07-15 21:32:18 +0000478 Py_VISIT(item);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000479 }
480 return 0;
481}
482
483static long
484deque_nohash(PyObject *self)
485{
486 PyErr_SetString(PyExc_TypeError, "deque objects are unhashable");
487 return -1;
488}
489
490static PyObject *
491deque_copy(PyObject *deque)
492{
Tim Peters1065f752004-10-01 01:03:29 +0000493 return PyObject_CallFunctionObjArgs((PyObject *)(deque->ob_type),
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000494 deque, NULL);
495}
496
497PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque.");
498
499static PyObject *
500deque_reduce(dequeobject *deque)
501{
502 PyObject *seq, *args, *result;
503
504 seq = PySequence_Tuple((PyObject *)deque);
505 if (seq == NULL)
506 return NULL;
507 args = PyTuple_Pack(1, seq);
508 if (args == NULL) {
509 Py_DECREF(seq);
510 return NULL;
511 }
512 result = PyTuple_Pack(2, deque->ob_type, args);
513 Py_DECREF(seq);
514 Py_DECREF(args);
515 return result;
516}
517
518PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
519
520static PyObject *
521deque_repr(PyObject *deque)
522{
523 PyObject *aslist, *result, *fmt;
524 int i;
525
526 i = Py_ReprEnter(deque);
527 if (i != 0) {
528 if (i < 0)
529 return NULL;
530 return PyString_FromString("[...]");
531 }
532
533 aslist = PySequence_List(deque);
534 if (aslist == NULL) {
535 Py_ReprLeave(deque);
536 return NULL;
537 }
538
539 fmt = PyString_FromString("deque(%r)");
540 if (fmt == NULL) {
541 Py_DECREF(aslist);
542 Py_ReprLeave(deque);
543 return NULL;
544 }
545 result = PyString_Format(fmt, aslist);
546 Py_DECREF(fmt);
547 Py_DECREF(aslist);
548 Py_ReprLeave(deque);
549 return result;
550}
551
552static int
553deque_tp_print(PyObject *deque, FILE *fp, int flags)
554{
555 PyObject *it, *item;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000556 char *emit = ""; /* No separator emitted on first pass */
557 char *separator = ", ";
558 int i;
559
560 i = Py_ReprEnter(deque);
561 if (i != 0) {
562 if (i < 0)
563 return i;
564 fputs("[...]", fp);
565 return 0;
566 }
567
568 it = PyObject_GetIter(deque);
569 if (it == NULL)
570 return -1;
571
572 fputs("deque([", fp);
573 while ((item = PyIter_Next(it)) != NULL) {
574 fputs(emit, fp);
575 emit = separator;
576 if (PyObject_Print(item, fp, 0) != 0) {
577 Py_DECREF(item);
578 Py_DECREF(it);
579 Py_ReprLeave(deque);
580 return -1;
581 }
582 Py_DECREF(item);
583 }
584 Py_ReprLeave(deque);
585 Py_DECREF(it);
Tim Peters1065f752004-10-01 01:03:29 +0000586 if (PyErr_Occurred())
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000587 return -1;
588 fputs("])", fp);
589 return 0;
590}
591
Raymond Hettinger738ec902004-02-29 02:15:56 +0000592static PyObject *
593deque_richcompare(PyObject *v, PyObject *w, int op)
594{
595 PyObject *it1=NULL, *it2=NULL, *x, *y;
596 int i, b, vs, ws, minlen, cmp=-1;
597
Tim Peters1065f752004-10-01 01:03:29 +0000598 if (!PyObject_TypeCheck(v, &deque_type) ||
Raymond Hettinger285cfcc2004-05-18 18:15:03 +0000599 !PyObject_TypeCheck(w, &deque_type)) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000600 Py_INCREF(Py_NotImplemented);
601 return Py_NotImplemented;
602 }
603
604 /* Shortcuts */
605 vs = ((dequeobject *)v)->len;
606 ws = ((dequeobject *)w)->len;
607 if (op == Py_EQ) {
608 if (v == w)
609 Py_RETURN_TRUE;
610 if (vs != ws)
611 Py_RETURN_FALSE;
612 }
613 if (op == Py_NE) {
614 if (v == w)
615 Py_RETURN_FALSE;
616 if (vs != ws)
617 Py_RETURN_TRUE;
618 }
619
620 /* Search for the first index where items are different */
621 it1 = PyObject_GetIter(v);
622 if (it1 == NULL)
623 goto done;
624 it2 = PyObject_GetIter(w);
625 if (it2 == NULL)
626 goto done;
627 minlen = (vs < ws) ? vs : ws;
628 for (i=0 ; i < minlen ; i++) {
629 x = PyIter_Next(it1);
630 if (x == NULL)
631 goto done;
632 y = PyIter_Next(it2);
633 if (y == NULL) {
634 Py_DECREF(x);
635 goto done;
636 }
637 b = PyObject_RichCompareBool(x, y, Py_EQ);
638 if (b == 0) {
639 cmp = PyObject_RichCompareBool(x, y, op);
640 Py_DECREF(x);
641 Py_DECREF(y);
642 goto done;
643 }
644 Py_DECREF(x);
645 Py_DECREF(y);
646 if (b == -1)
647 goto done;
648 }
649 /* Elements are equal through minlen. The longest input is the greatest */
650 switch (op) {
651 case Py_LT: cmp = vs < ws; break;
652 case Py_LE: cmp = vs <= ws; break;
653 case Py_EQ: cmp = vs == ws; break;
654 case Py_NE: cmp = vs != ws; break;
655 case Py_GT: cmp = vs > ws; break;
656 case Py_GE: cmp = vs >= ws; break;
657 }
Tim Peters1065f752004-10-01 01:03:29 +0000658
Raymond Hettinger738ec902004-02-29 02:15:56 +0000659done:
660 Py_XDECREF(it1);
661 Py_XDECREF(it2);
662 if (cmp == 1)
663 Py_RETURN_TRUE;
664 if (cmp == 0)
665 Py_RETURN_FALSE;
666 return NULL;
667}
668
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000669static int
670deque_init(dequeobject *deque, PyObject *args, PyObject *kwds)
671{
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000672 PyObject *iterable = NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000673
674 if (!PyArg_UnpackTuple(args, "deque", 0, 1, &iterable))
675 return -1;
676
677 if (iterable != NULL) {
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000678 PyObject *rv = deque_extend(deque, iterable);
679 if (rv == NULL)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000680 return -1;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000681 Py_DECREF(rv);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000682 }
683 return 0;
684}
685
686static PySequenceMethods deque_as_sequence = {
687 (inquiry)deque_len, /* sq_length */
688 0, /* sq_concat */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000689 0, /* sq_repeat */
690 (intargfunc)deque_item, /* sq_item */
691 0, /* sq_slice */
692 (intobjargproc)deque_ass_item, /* sq_ass_item */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000693};
694
695/* deque object ********************************************************/
696
697static PyObject *deque_iter(dequeobject *deque);
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000698static PyObject *deque_reviter(dequeobject *deque);
Tim Peters1065f752004-10-01 01:03:29 +0000699PyDoc_STRVAR(reversed_doc,
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000700 "D.__reversed__() -- return a reverse iterator over the deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000701
702static PyMethodDef deque_methods[] = {
Tim Peters1065f752004-10-01 01:03:29 +0000703 {"append", (PyCFunction)deque_append,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000704 METH_O, append_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000705 {"appendleft", (PyCFunction)deque_appendleft,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000706 METH_O, appendleft_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000707 {"clear", (PyCFunction)deque_clearmethod,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000708 METH_NOARGS, clear_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000709 {"__copy__", (PyCFunction)deque_copy,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000710 METH_NOARGS, copy_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000711 {"extend", (PyCFunction)deque_extend,
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000712 METH_O, extend_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000713 {"extendleft", (PyCFunction)deque_extendleft,
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000714 METH_O, extendleft_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000715 {"pop", (PyCFunction)deque_pop,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000716 METH_NOARGS, pop_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000717 {"popleft", (PyCFunction)deque_popleft,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000718 METH_NOARGS, popleft_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000719 {"__reduce__", (PyCFunction)deque_reduce,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000720 METH_NOARGS, reduce_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000721 {"__reversed__", (PyCFunction)deque_reviter,
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000722 METH_NOARGS, reversed_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000723 {"rotate", (PyCFunction)deque_rotate,
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000724 METH_VARARGS, rotate_doc},
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000725 {NULL, NULL} /* sentinel */
726};
727
728PyDoc_STRVAR(deque_doc,
729"deque(iterable) --> deque object\n\
730\n\
731Build an ordered collection accessible from endpoints only.");
732
Neal Norwitz87f10132004-02-29 15:40:53 +0000733static PyTypeObject deque_type = {
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000734 PyObject_HEAD_INIT(NULL)
735 0, /* ob_size */
736 "collections.deque", /* tp_name */
737 sizeof(dequeobject), /* tp_basicsize */
738 0, /* tp_itemsize */
739 /* methods */
740 (destructor)deque_dealloc, /* tp_dealloc */
741 (printfunc)deque_tp_print, /* tp_print */
742 0, /* tp_getattr */
743 0, /* tp_setattr */
744 0, /* tp_compare */
745 (reprfunc)deque_repr, /* tp_repr */
746 0, /* tp_as_number */
747 &deque_as_sequence, /* tp_as_sequence */
748 0, /* tp_as_mapping */
749 deque_nohash, /* tp_hash */
750 0, /* tp_call */
751 0, /* tp_str */
752 PyObject_GenericGetAttr, /* tp_getattro */
753 0, /* tp_setattro */
754 0, /* tp_as_buffer */
Raymond Hettinger691d8052004-05-30 07:26:47 +0000755 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
756 Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000757 deque_doc, /* tp_doc */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000758 (traverseproc)deque_traverse, /* tp_traverse */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000759 (inquiry)deque_clear, /* tp_clear */
Raymond Hettinger738ec902004-02-29 02:15:56 +0000760 (richcmpfunc)deque_richcompare, /* tp_richcompare */
Raymond Hettinger691d8052004-05-30 07:26:47 +0000761 offsetof(dequeobject, weakreflist), /* tp_weaklistoffset*/
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000762 (getiterfunc)deque_iter, /* tp_iter */
763 0, /* tp_iternext */
764 deque_methods, /* tp_methods */
765 0, /* tp_members */
766 0, /* tp_getset */
767 0, /* tp_base */
768 0, /* tp_dict */
769 0, /* tp_descr_get */
770 0, /* tp_descr_set */
771 0, /* tp_dictoffset */
772 (initproc)deque_init, /* tp_init */
773 PyType_GenericAlloc, /* tp_alloc */
774 deque_new, /* tp_new */
775 PyObject_GC_Del, /* tp_free */
776};
777
778/*********************** Deque Iterator **************************/
779
780typedef struct {
781 PyObject_HEAD
782 int index;
783 block *b;
784 dequeobject *deque;
785 int len;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000786 int counter;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000787} dequeiterobject;
788
789PyTypeObject dequeiter_type;
790
791static PyObject *
792deque_iter(dequeobject *deque)
793{
794 dequeiterobject *it;
795
796 it = PyObject_New(dequeiterobject, &dequeiter_type);
797 if (it == NULL)
798 return NULL;
799 it->b = deque->leftblock;
800 it->index = deque->leftindex;
801 Py_INCREF(deque);
802 it->deque = deque;
803 it->len = deque->len;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000804 it->counter = deque->len;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000805 return (PyObject *)it;
806}
807
808static void
809dequeiter_dealloc(dequeiterobject *dio)
810{
811 Py_XDECREF(dio->deque);
812 dio->ob_type->tp_free(dio);
813}
814
815static PyObject *
816dequeiter_next(dequeiterobject *it)
817{
818 PyObject *item;
819 if (it->b == it->deque->rightblock && it->index > it->deque->rightindex)
820 return NULL;
821
822 if (it->len != it->deque->len) {
823 it->len = -1; /* Make this state sticky */
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000824 it->counter = 0;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000825 PyErr_SetString(PyExc_RuntimeError,
826 "deque changed size during iteration");
827 return NULL;
828 }
829
830 item = it->b->data[it->index];
831 it->index++;
832 if (it->index == BLOCKLEN && it->b->rightlink != NULL) {
833 it->b = it->b->rightlink;
834 it->index = 0;
835 }
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000836 it->counter--;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000837 Py_INCREF(item);
838 return item;
839}
840
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000841static int
842dequeiter_len(dequeiterobject *it)
843{
844 return it->counter;
845}
846
847static PySequenceMethods dequeiter_as_sequence = {
848 (inquiry)dequeiter_len, /* sq_length */
849 0, /* sq_concat */
850};
851
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000852PyTypeObject dequeiter_type = {
853 PyObject_HEAD_INIT(NULL)
854 0, /* ob_size */
855 "deque_iterator", /* tp_name */
856 sizeof(dequeiterobject), /* tp_basicsize */
857 0, /* tp_itemsize */
858 /* methods */
859 (destructor)dequeiter_dealloc, /* tp_dealloc */
860 0, /* tp_print */
861 0, /* tp_getattr */
862 0, /* tp_setattr */
863 0, /* tp_compare */
864 0, /* tp_repr */
865 0, /* tp_as_number */
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000866 &dequeiter_as_sequence, /* tp_as_sequence */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000867 0, /* tp_as_mapping */
868 0, /* tp_hash */
869 0, /* tp_call */
870 0, /* tp_str */
871 PyObject_GenericGetAttr, /* tp_getattro */
872 0, /* tp_setattro */
873 0, /* tp_as_buffer */
874 Py_TPFLAGS_DEFAULT, /* tp_flags */
875 0, /* tp_doc */
876 0, /* tp_traverse */
877 0, /* tp_clear */
878 0, /* tp_richcompare */
879 0, /* tp_weaklistoffset */
880 PyObject_SelfIter, /* tp_iter */
881 (iternextfunc)dequeiter_next, /* tp_iternext */
882 0,
883};
884
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000885/*********************** Deque Reverse Iterator **************************/
886
887PyTypeObject dequereviter_type;
888
889static PyObject *
890deque_reviter(dequeobject *deque)
891{
892 dequeiterobject *it;
893
894 it = PyObject_New(dequeiterobject, &dequereviter_type);
895 if (it == NULL)
896 return NULL;
897 it->b = deque->rightblock;
898 it->index = deque->rightindex;
899 Py_INCREF(deque);
900 it->deque = deque;
901 it->len = deque->len;
902 it->counter = deque->len;
903 return (PyObject *)it;
904}
905
906static PyObject *
907dequereviter_next(dequeiterobject *it)
908{
909 PyObject *item;
910 if (it->b == it->deque->leftblock && it->index < it->deque->leftindex)
911 return NULL;
912
913 if (it->len != it->deque->len) {
914 it->len = -1; /* Make this state sticky */
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000915 it->counter = 0;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000916 PyErr_SetString(PyExc_RuntimeError,
917 "deque changed size during iteration");
918 return NULL;
919 }
920
921 item = it->b->data[it->index];
922 it->index--;
923 if (it->index == -1 && it->b->leftlink != NULL) {
924 it->b = it->b->leftlink;
925 it->index = BLOCKLEN - 1;
926 }
927 it->counter--;
928 Py_INCREF(item);
929 return item;
930}
931
932PyTypeObject dequereviter_type = {
933 PyObject_HEAD_INIT(NULL)
934 0, /* ob_size */
935 "deque_reverse_iterator", /* tp_name */
936 sizeof(dequeiterobject), /* tp_basicsize */
937 0, /* tp_itemsize */
938 /* methods */
939 (destructor)dequeiter_dealloc, /* tp_dealloc */
940 0, /* tp_print */
941 0, /* tp_getattr */
942 0, /* tp_setattr */
943 0, /* tp_compare */
944 0, /* tp_repr */
945 0, /* tp_as_number */
946 &dequeiter_as_sequence, /* tp_as_sequence */
947 0, /* tp_as_mapping */
948 0, /* tp_hash */
949 0, /* tp_call */
950 0, /* tp_str */
951 PyObject_GenericGetAttr, /* tp_getattro */
952 0, /* tp_setattro */
953 0, /* tp_as_buffer */
954 Py_TPFLAGS_DEFAULT, /* tp_flags */
955 0, /* tp_doc */
956 0, /* tp_traverse */
957 0, /* tp_clear */
958 0, /* tp_richcompare */
959 0, /* tp_weaklistoffset */
960 PyObject_SelfIter, /* tp_iter */
961 (iternextfunc)dequereviter_next, /* tp_iternext */
962 0,
963};
964
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000965/* module level code ********************************************************/
966
967PyDoc_STRVAR(module_doc,
968"High performance data structures\n\
969");
970
971PyMODINIT_FUNC
972initcollections(void)
973{
974 PyObject *m;
975
976 m = Py_InitModule3("collections", NULL, module_doc);
977
978 if (PyType_Ready(&deque_type) < 0)
979 return;
980 Py_INCREF(&deque_type);
981 PyModule_AddObject(m, "deque", (PyObject *)&deque_type);
982
983 if (PyType_Ready(&dequeiter_type) < 0)
Tim Peters1065f752004-10-01 01:03:29 +0000984 return;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000985
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000986 if (PyType_Ready(&dequereviter_type) < 0)
987 return;
988
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000989 return;
990}