blob: 196cbe2244abdad18afa010f297b568d3118f2d3 [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
Tim Petersd8768d32004-10-01 01:32:53 +000012/* A `dequeobject` is composed of a doubly-linked list of `block` nodes.
13 * This list is not circular (the leftmost block has leftlink==NULL,
14 * and the rightmost block has rightlink==NULL). A deque d's first
15 * element is at d.leftblock[leftindex] and its last element is at
16 * d.rightblock[rightindex]; note that, unlike as for Python slice
Tim Petersd6e00322004-10-01 01:35:54 +000017 * indices, these indices are inclusive on both ends.
Tim Petersd8768d32004-10-01 01:32:53 +000018 * The list of blocks is never empty. An empty deque d has
19 * d.leftblock == d.rightblock != NULL; d.len == 0; and
20 * d.leftindex > d.rightindex; checking for d.len == 0 is the intended
21 * way to see whether d is empty.
22 * Note that since d.leftindex and d.rightindex may be indices into
Tim Petersd6e00322004-10-01 01:35:54 +000023 * distinct blocks (and certainly are, for any d with len(d) > BLOCKLEN),
Tim Petersd8768d32004-10-01 01:32:53 +000024 * it's not generally true that d.leftindex <= d.rightindex.
25 */
26
Raymond Hettinger756b3f32004-01-29 06:37:52 +000027typedef struct BLOCK {
28 struct BLOCK *leftlink;
29 struct BLOCK *rightlink;
30 PyObject *data[BLOCKLEN];
31} block;
32
Tim Peters6f853562004-10-01 01:04:50 +000033static block *
34newblock(block *leftlink, block *rightlink) {
Raymond Hettinger756b3f32004-01-29 06:37:52 +000035 block *b = PyMem_Malloc(sizeof(block));
36 if (b == NULL) {
37 PyErr_NoMemory();
38 return NULL;
39 }
40 b->leftlink = leftlink;
41 b->rightlink = rightlink;
42 return b;
43}
44
45typedef struct {
46 PyObject_HEAD
47 block *leftblock;
48 block *rightblock;
Tim Petersd8768d32004-10-01 01:32:53 +000049 int leftindex; /* in range(BLOCKLEN) */
50 int rightindex; /* in range(BLOCKLEN) */
Raymond Hettinger756b3f32004-01-29 06:37:52 +000051 int len;
Raymond Hettinger691d8052004-05-30 07:26:47 +000052 PyObject *weakreflist; /* List of weak references */
Raymond Hettinger756b3f32004-01-29 06:37:52 +000053} dequeobject;
54
Neal Norwitz87f10132004-02-29 15:40:53 +000055static PyTypeObject deque_type;
Raymond Hettinger738ec902004-02-29 02:15:56 +000056
Raymond Hettinger756b3f32004-01-29 06:37:52 +000057static PyObject *
58deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
59{
60 dequeobject *deque;
61 block *b;
62
63 /* create dequeobject structure */
64 deque = (dequeobject *)type->tp_alloc(type, 0);
65 if (deque == NULL)
66 return NULL;
Tim Peters1065f752004-10-01 01:03:29 +000067
Raymond Hettinger756b3f32004-01-29 06:37:52 +000068 b = newblock(NULL, NULL);
69 if (b == NULL) {
70 Py_DECREF(deque);
71 return NULL;
72 }
73
74 deque->leftblock = b;
75 deque->rightblock = b;
76 deque->leftindex = BLOCKLEN / 2 + 1;
77 deque->rightindex = BLOCKLEN / 2;
78 deque->len = 0;
Raymond Hettinger691d8052004-05-30 07:26:47 +000079 deque->weakreflist = NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +000080
81 return (PyObject *)deque;
82}
83
84static PyObject *
85deque_append(dequeobject *deque, PyObject *item)
86{
87 deque->rightindex++;
88 deque->len++;
89 if (deque->rightindex == BLOCKLEN) {
90 block *b = newblock(deque->rightblock, NULL);
91 if (b == NULL)
92 return NULL;
93 assert(deque->rightblock->rightlink == NULL);
94 deque->rightblock->rightlink = b;
95 deque->rightblock = b;
96 deque->rightindex = 0;
97 }
98 Py_INCREF(item);
99 deque->rightblock->data[deque->rightindex] = item;
100 Py_RETURN_NONE;
101}
102
103PyDoc_STRVAR(append_doc, "Add an element to the right side of the deque.");
104
105static PyObject *
106deque_appendleft(dequeobject *deque, PyObject *item)
107{
108 deque->leftindex--;
109 deque->len++;
110 if (deque->leftindex == -1) {
111 block *b = newblock(NULL, deque->leftblock);
112 if (b == NULL)
113 return NULL;
114 assert(deque->leftblock->leftlink == NULL);
115 deque->leftblock->leftlink = b;
116 deque->leftblock = b;
117 deque->leftindex = BLOCKLEN - 1;
118 }
119 Py_INCREF(item);
120 deque->leftblock->data[deque->leftindex] = item;
121 Py_RETURN_NONE;
122}
123
124PyDoc_STRVAR(appendleft_doc, "Add an element to the left side of the deque.");
125
126static PyObject *
127deque_pop(dequeobject *deque, PyObject *unused)
128{
129 PyObject *item;
130 block *prevblock;
131
132 if (deque->len == 0) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000133 PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000134 return NULL;
135 }
136 item = deque->rightblock->data[deque->rightindex];
137 deque->rightindex--;
138 deque->len--;
139
140 if (deque->rightindex == -1) {
141 if (deque->len == 0) {
142 assert(deque->leftblock == deque->rightblock);
143 assert(deque->leftindex == deque->rightindex+1);
144 /* re-center instead of freeing a block */
145 deque->leftindex = BLOCKLEN / 2 + 1;
146 deque->rightindex = BLOCKLEN / 2;
147 } else {
148 prevblock = deque->rightblock->leftlink;
149 assert(deque->leftblock != deque->rightblock);
150 PyMem_Free(deque->rightblock);
151 prevblock->rightlink = NULL;
152 deque->rightblock = prevblock;
153 deque->rightindex = BLOCKLEN - 1;
154 }
155 }
156 return item;
157}
158
159PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element.");
160
161static PyObject *
162deque_popleft(dequeobject *deque, PyObject *unused)
163{
164 PyObject *item;
165 block *prevblock;
166
167 if (deque->len == 0) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000168 PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000169 return NULL;
170 }
171 item = deque->leftblock->data[deque->leftindex];
172 deque->leftindex++;
173 deque->len--;
174
175 if (deque->leftindex == BLOCKLEN) {
176 if (deque->len == 0) {
177 assert(deque->leftblock == deque->rightblock);
178 assert(deque->leftindex == deque->rightindex+1);
179 /* re-center instead of freeing a block */
180 deque->leftindex = BLOCKLEN / 2 + 1;
181 deque->rightindex = BLOCKLEN / 2;
182 } else {
183 assert(deque->leftblock != deque->rightblock);
184 prevblock = deque->leftblock->rightlink;
185 assert(deque->leftblock != NULL);
186 PyMem_Free(deque->leftblock);
187 assert(prevblock != NULL);
188 prevblock->leftlink = NULL;
189 deque->leftblock = prevblock;
190 deque->leftindex = 0;
191 }
192 }
193 return item;
194}
195
196PyDoc_STRVAR(popleft_doc, "Remove and return the leftmost element.");
197
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000198static PyObject *
199deque_extend(dequeobject *deque, PyObject *iterable)
200{
201 PyObject *it, *item;
202
203 it = PyObject_GetIter(iterable);
204 if (it == NULL)
205 return NULL;
206
207 while ((item = PyIter_Next(it)) != NULL) {
208 deque->rightindex++;
209 deque->len++;
210 if (deque->rightindex == BLOCKLEN) {
211 block *b = newblock(deque->rightblock, NULL);
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000212 if (b == NULL) {
213 Py_DECREF(item);
214 Py_DECREF(it);
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000215 return NULL;
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000216 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000217 assert(deque->rightblock->rightlink == NULL);
218 deque->rightblock->rightlink = b;
219 deque->rightblock = b;
220 deque->rightindex = 0;
221 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000222 deque->rightblock->data[deque->rightindex] = item;
223 }
224 Py_DECREF(it);
Tim Peters1065f752004-10-01 01:03:29 +0000225 if (PyErr_Occurred())
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000226 return NULL;
227 Py_RETURN_NONE;
228}
229
Tim Peters1065f752004-10-01 01:03:29 +0000230PyDoc_STRVAR(extend_doc,
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000231"Extend the right side of the deque with elements from the iterable");
232
233static PyObject *
234deque_extendleft(dequeobject *deque, PyObject *iterable)
235{
236 PyObject *it, *item;
237
238 it = PyObject_GetIter(iterable);
239 if (it == NULL)
240 return NULL;
241
242 while ((item = PyIter_Next(it)) != NULL) {
243 deque->leftindex--;
244 deque->len++;
245 if (deque->leftindex == -1) {
246 block *b = newblock(NULL, deque->leftblock);
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000247 if (b == NULL) {
248 Py_DECREF(item);
249 Py_DECREF(it);
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000250 return NULL;
Raymond Hettingerc058fd12004-02-07 02:45:22 +0000251 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000252 assert(deque->leftblock->leftlink == NULL);
253 deque->leftblock->leftlink = b;
254 deque->leftblock = b;
255 deque->leftindex = BLOCKLEN - 1;
256 }
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000257 deque->leftblock->data[deque->leftindex] = item;
258 }
259 Py_DECREF(it);
Raymond Hettingera435c532004-07-09 04:10:20 +0000260 if (PyErr_Occurred())
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000261 return NULL;
262 Py_RETURN_NONE;
263}
264
Tim Peters1065f752004-10-01 01:03:29 +0000265PyDoc_STRVAR(extendleft_doc,
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000266"Extend the left side of the deque with elements from the iterable");
267
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000268static PyObject *
269deque_rotate(dequeobject *deque, PyObject *args)
270{
Raymond Hettingeree33b272004-02-08 04:05:26 +0000271 int i, n=1, len=deque->len, halflen=(len+1)>>1;
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000272 PyObject *item, *rv;
273
Raymond Hettingeree33b272004-02-08 04:05:26 +0000274 if (!PyArg_ParseTuple(args, "|i:rotate", &n))
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000275 return NULL;
276
Raymond Hettingeree33b272004-02-08 04:05:26 +0000277 if (len == 0)
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000278 Py_RETURN_NONE;
Raymond Hettingeree33b272004-02-08 04:05:26 +0000279 if (n > halflen || n < -halflen) {
280 n %= len;
281 if (n > halflen)
282 n -= len;
283 else if (n < -halflen)
284 n += len;
285 }
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000286
287 for (i=0 ; i<n ; i++) {
288 item = deque_pop(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000289 assert (item != NULL);
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000290 rv = deque_appendleft(deque, item);
291 Py_DECREF(item);
292 if (rv == NULL)
293 return NULL;
294 Py_DECREF(rv);
295 }
296 for (i=0 ; i>n ; i--) {
297 item = deque_popleft(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000298 assert (item != NULL);
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000299 rv = deque_append(deque, item);
300 Py_DECREF(item);
301 if (rv == NULL)
302 return NULL;
303 Py_DECREF(rv);
304 }
305 Py_RETURN_NONE;
306}
307
Tim Peters1065f752004-10-01 01:03:29 +0000308PyDoc_STRVAR(rotate_doc,
Raymond Hettingeree33b272004-02-08 04:05:26 +0000309"Rotate the deque n steps to the right (default n=1). If n is negative, rotates left.");
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000310
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000311static int
312deque_len(dequeobject *deque)
313{
314 return deque->len;
315}
316
317static int
318deque_clear(dequeobject *deque)
319{
320 PyObject *item;
321
322 while (deque_len(deque)) {
323 item = deque_pop(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000324 assert (item != NULL);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000325 Py_DECREF(item);
326 }
327 assert(deque->leftblock == deque->rightblock &&
328 deque->leftindex > deque->rightindex);
329 return 0;
330}
331
332static PyObject *
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000333deque_item(dequeobject *deque, int i)
334{
335 block *b;
336 PyObject *item;
337 int n;
338
339 if (i < 0 || i >= deque->len) {
340 PyErr_SetString(PyExc_IndexError,
341 "deque index out of range");
342 return NULL;
343 }
344
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000345 if (i == 0) {
346 i = deque->leftindex;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000347 b = deque->leftblock;
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000348 } else if (i == deque->len - 1) {
349 i = deque->rightindex;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000350 b = deque->rightblock;
Raymond Hettinger6c79a512004-03-04 08:00:54 +0000351 } else {
352 i += deque->leftindex;
353 n = i / BLOCKLEN;
354 i %= BLOCKLEN;
355 if (i < (deque->len >> 1)) {
356 b = deque->leftblock;
357 while (n--)
358 b = b->rightlink;
359 } else {
360 n = (deque->leftindex + deque->len - 1) / BLOCKLEN - n;
361 b = deque->rightblock;
362 while (n--)
363 b = b->leftlink;
364 }
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000365 }
366 item = b->data[i];
367 Py_INCREF(item);
368 return item;
369}
370
Raymond Hettinger616f4f62004-06-26 04:42:06 +0000371/* delitem() implemented in terms of rotate for simplicity and reasonable
372 performance near the end points. If for some reason this method becomes
Tim Peters1065f752004-10-01 01:03:29 +0000373 popular, it is not hard to re-implement this using direct data movement
Raymond Hettinger616f4f62004-06-26 04:42:06 +0000374 (similar to code in list slice assignment) and achieve a two or threefold
375 performance boost.
376*/
377
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000378static int
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000379deque_del_item(dequeobject *deque, int i)
380{
381 PyObject *item=NULL, *minus_i=NULL, *plus_i=NULL;
382 int rv = -1;
383
Tim Peters1065f752004-10-01 01:03:29 +0000384 assert (i >= 0 && i < deque->len);
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000385
386 minus_i = Py_BuildValue("(i)", -i);
387 if (minus_i == NULL)
388 goto fail;
389
390 plus_i = Py_BuildValue("(i)", i);
391 if (plus_i == NULL)
392 goto fail;
393
394 item = deque_rotate(deque, minus_i);
Tim Peters1065f752004-10-01 01:03:29 +0000395 if (item == NULL)
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000396 goto fail;
397 Py_DECREF(item);
398
399 item = deque_popleft(deque, NULL);
Raymond Hettingera435c532004-07-09 04:10:20 +0000400 assert (item != NULL);
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000401 Py_DECREF(item);
402
403 item = deque_rotate(deque, plus_i);
Tim Peters1065f752004-10-01 01:03:29 +0000404 if (item == NULL)
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000405 goto fail;
406
407 rv = 0;
408fail:
409 Py_XDECREF(item);
410 Py_XDECREF(minus_i);
411 Py_XDECREF(plus_i);
412 return rv;
413}
414
415static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000416deque_ass_item(dequeobject *deque, int i, PyObject *v)
417{
418 PyObject *old_value;
419 block *b;
Raymond Hettingera435c532004-07-09 04:10:20 +0000420 int n, len=deque->len, halflen=(len+1)>>1, index=i;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000421
Raymond Hettingera435c532004-07-09 04:10:20 +0000422 if (i < 0 || i >= len) {
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000423 PyErr_SetString(PyExc_IndexError,
424 "deque index out of range");
425 return -1;
426 }
Raymond Hettinger0e371f22004-05-12 20:55:56 +0000427 if (v == NULL)
428 return deque_del_item(deque, i);
429
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000430 i += deque->leftindex;
431 n = i / BLOCKLEN;
432 i %= BLOCKLEN;
Raymond Hettingera435c532004-07-09 04:10:20 +0000433 if (index <= halflen) {
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000434 b = deque->leftblock;
435 while (n--)
436 b = b->rightlink;
437 } else {
Raymond Hettingera435c532004-07-09 04:10:20 +0000438 n = (deque->leftindex + len - 1) / BLOCKLEN - n;
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000439 b = deque->rightblock;
440 while (n--)
441 b = b->leftlink;
442 }
443 Py_INCREF(v);
444 old_value = b->data[i];
445 b->data[i] = v;
446 Py_DECREF(old_value);
447 return 0;
448}
449
450static PyObject *
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000451deque_clearmethod(dequeobject *deque)
452{
Raymond Hettingera435c532004-07-09 04:10:20 +0000453 int rv;
454
455 rv = deque_clear(deque);
456 assert (rv != -1);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000457 Py_RETURN_NONE;
458}
459
460PyDoc_STRVAR(clear_doc, "Remove all elements from the deque.");
461
462static void
463deque_dealloc(dequeobject *deque)
464{
465 PyObject_GC_UnTrack(deque);
Raymond Hettinger691d8052004-05-30 07:26:47 +0000466 if (deque->weakreflist != NULL)
467 PyObject_ClearWeakRefs((PyObject *) deque);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000468 if (deque->leftblock != NULL) {
Raymond Hettingere9c89e82004-07-19 00:10:24 +0000469 deque_clear(deque);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000470 assert(deque->leftblock != NULL);
471 PyMem_Free(deque->leftblock);
472 }
473 deque->leftblock = NULL;
474 deque->rightblock = NULL;
475 deque->ob_type->tp_free(deque);
476}
477
478static int
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000479deque_traverse(dequeobject *deque, visitproc visit, void *arg)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000480{
Tim Peters10c7e862004-10-01 02:01:04 +0000481 block *b;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000482 PyObject *item;
Tim Peters10c7e862004-10-01 02:01:04 +0000483 int index;
484 int indexlo = deque->leftindex;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000485
Tim Peters10c7e862004-10-01 02:01:04 +0000486 assert(deque->leftblock != NULL);
487 for (b = deque->leftblock; b != NULL; b = b->rightlink) {
488 const int indexhi = b == deque->rightblock ?
489 deque->rightindex :
490 BLOCKLEN - 1;
491
492 for (index = indexlo; index <= indexhi; ++index) {
493 item = b->data[index];
494 Py_VISIT(item);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000495 }
Tim Peters10c7e862004-10-01 02:01:04 +0000496 indexlo = 0;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000497 }
498 return 0;
499}
500
501static long
502deque_nohash(PyObject *self)
503{
504 PyErr_SetString(PyExc_TypeError, "deque objects are unhashable");
505 return -1;
506}
507
508static PyObject *
509deque_copy(PyObject *deque)
510{
Tim Peters1065f752004-10-01 01:03:29 +0000511 return PyObject_CallFunctionObjArgs((PyObject *)(deque->ob_type),
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000512 deque, NULL);
513}
514
515PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque.");
516
517static PyObject *
518deque_reduce(dequeobject *deque)
519{
520 PyObject *seq, *args, *result;
521
522 seq = PySequence_Tuple((PyObject *)deque);
523 if (seq == NULL)
524 return NULL;
525 args = PyTuple_Pack(1, seq);
526 if (args == NULL) {
527 Py_DECREF(seq);
528 return NULL;
529 }
530 result = PyTuple_Pack(2, deque->ob_type, args);
531 Py_DECREF(seq);
532 Py_DECREF(args);
533 return result;
534}
535
536PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
537
538static PyObject *
539deque_repr(PyObject *deque)
540{
541 PyObject *aslist, *result, *fmt;
542 int i;
543
544 i = Py_ReprEnter(deque);
545 if (i != 0) {
546 if (i < 0)
547 return NULL;
548 return PyString_FromString("[...]");
549 }
550
551 aslist = PySequence_List(deque);
552 if (aslist == NULL) {
553 Py_ReprLeave(deque);
554 return NULL;
555 }
556
557 fmt = PyString_FromString("deque(%r)");
558 if (fmt == NULL) {
559 Py_DECREF(aslist);
560 Py_ReprLeave(deque);
561 return NULL;
562 }
563 result = PyString_Format(fmt, aslist);
564 Py_DECREF(fmt);
565 Py_DECREF(aslist);
566 Py_ReprLeave(deque);
567 return result;
568}
569
570static int
571deque_tp_print(PyObject *deque, FILE *fp, int flags)
572{
573 PyObject *it, *item;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000574 char *emit = ""; /* No separator emitted on first pass */
575 char *separator = ", ";
576 int i;
577
578 i = Py_ReprEnter(deque);
579 if (i != 0) {
580 if (i < 0)
581 return i;
582 fputs("[...]", fp);
583 return 0;
584 }
585
586 it = PyObject_GetIter(deque);
587 if (it == NULL)
588 return -1;
589
590 fputs("deque([", fp);
591 while ((item = PyIter_Next(it)) != NULL) {
592 fputs(emit, fp);
593 emit = separator;
594 if (PyObject_Print(item, fp, 0) != 0) {
595 Py_DECREF(item);
596 Py_DECREF(it);
597 Py_ReprLeave(deque);
598 return -1;
599 }
600 Py_DECREF(item);
601 }
602 Py_ReprLeave(deque);
603 Py_DECREF(it);
Tim Peters1065f752004-10-01 01:03:29 +0000604 if (PyErr_Occurred())
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000605 return -1;
606 fputs("])", fp);
607 return 0;
608}
609
Raymond Hettinger738ec902004-02-29 02:15:56 +0000610static PyObject *
611deque_richcompare(PyObject *v, PyObject *w, int op)
612{
613 PyObject *it1=NULL, *it2=NULL, *x, *y;
614 int i, b, vs, ws, minlen, cmp=-1;
615
Tim Peters1065f752004-10-01 01:03:29 +0000616 if (!PyObject_TypeCheck(v, &deque_type) ||
Raymond Hettinger285cfcc2004-05-18 18:15:03 +0000617 !PyObject_TypeCheck(w, &deque_type)) {
Raymond Hettinger738ec902004-02-29 02:15:56 +0000618 Py_INCREF(Py_NotImplemented);
619 return Py_NotImplemented;
620 }
621
622 /* Shortcuts */
623 vs = ((dequeobject *)v)->len;
624 ws = ((dequeobject *)w)->len;
625 if (op == Py_EQ) {
626 if (v == w)
627 Py_RETURN_TRUE;
628 if (vs != ws)
629 Py_RETURN_FALSE;
630 }
631 if (op == Py_NE) {
632 if (v == w)
633 Py_RETURN_FALSE;
634 if (vs != ws)
635 Py_RETURN_TRUE;
636 }
637
638 /* Search for the first index where items are different */
639 it1 = PyObject_GetIter(v);
640 if (it1 == NULL)
641 goto done;
642 it2 = PyObject_GetIter(w);
643 if (it2 == NULL)
644 goto done;
645 minlen = (vs < ws) ? vs : ws;
646 for (i=0 ; i < minlen ; i++) {
647 x = PyIter_Next(it1);
648 if (x == NULL)
649 goto done;
650 y = PyIter_Next(it2);
651 if (y == NULL) {
652 Py_DECREF(x);
653 goto done;
654 }
655 b = PyObject_RichCompareBool(x, y, Py_EQ);
656 if (b == 0) {
657 cmp = PyObject_RichCompareBool(x, y, op);
658 Py_DECREF(x);
659 Py_DECREF(y);
660 goto done;
661 }
662 Py_DECREF(x);
663 Py_DECREF(y);
664 if (b == -1)
665 goto done;
666 }
667 /* Elements are equal through minlen. The longest input is the greatest */
668 switch (op) {
669 case Py_LT: cmp = vs < ws; break;
670 case Py_LE: cmp = vs <= ws; break;
671 case Py_EQ: cmp = vs == ws; break;
672 case Py_NE: cmp = vs != ws; break;
673 case Py_GT: cmp = vs > ws; break;
674 case Py_GE: cmp = vs >= ws; break;
675 }
Tim Peters1065f752004-10-01 01:03:29 +0000676
Raymond Hettinger738ec902004-02-29 02:15:56 +0000677done:
678 Py_XDECREF(it1);
679 Py_XDECREF(it2);
680 if (cmp == 1)
681 Py_RETURN_TRUE;
682 if (cmp == 0)
683 Py_RETURN_FALSE;
684 return NULL;
685}
686
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000687static int
688deque_init(dequeobject *deque, PyObject *args, PyObject *kwds)
689{
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000690 PyObject *iterable = NULL;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000691
692 if (!PyArg_UnpackTuple(args, "deque", 0, 1, &iterable))
693 return -1;
694
695 if (iterable != NULL) {
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000696 PyObject *rv = deque_extend(deque, iterable);
697 if (rv == NULL)
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000698 return -1;
Raymond Hettinger3ba85c22004-02-06 19:04:56 +0000699 Py_DECREF(rv);
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000700 }
701 return 0;
702}
703
704static PySequenceMethods deque_as_sequence = {
705 (inquiry)deque_len, /* sq_length */
706 0, /* sq_concat */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000707 0, /* sq_repeat */
708 (intargfunc)deque_item, /* sq_item */
709 0, /* sq_slice */
710 (intobjargproc)deque_ass_item, /* sq_ass_item */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000711};
712
713/* deque object ********************************************************/
714
715static PyObject *deque_iter(dequeobject *deque);
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000716static PyObject *deque_reviter(dequeobject *deque);
Tim Peters1065f752004-10-01 01:03:29 +0000717PyDoc_STRVAR(reversed_doc,
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000718 "D.__reversed__() -- return a reverse iterator over the deque");
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000719
720static PyMethodDef deque_methods[] = {
Tim Peters1065f752004-10-01 01:03:29 +0000721 {"append", (PyCFunction)deque_append,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000722 METH_O, append_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000723 {"appendleft", (PyCFunction)deque_appendleft,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000724 METH_O, appendleft_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000725 {"clear", (PyCFunction)deque_clearmethod,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000726 METH_NOARGS, clear_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000727 {"__copy__", (PyCFunction)deque_copy,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000728 METH_NOARGS, copy_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000729 {"extend", (PyCFunction)deque_extend,
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000730 METH_O, extend_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000731 {"extendleft", (PyCFunction)deque_extendleft,
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000732 METH_O, extendleft_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000733 {"pop", (PyCFunction)deque_pop,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000734 METH_NOARGS, pop_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000735 {"popleft", (PyCFunction)deque_popleft,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000736 METH_NOARGS, popleft_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000737 {"__reduce__", (PyCFunction)deque_reduce,
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000738 METH_NOARGS, reduce_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000739 {"__reversed__", (PyCFunction)deque_reviter,
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000740 METH_NOARGS, reversed_doc},
Tim Peters1065f752004-10-01 01:03:29 +0000741 {"rotate", (PyCFunction)deque_rotate,
Raymond Hettinger5c5eb862004-02-07 21:13:00 +0000742 METH_VARARGS, rotate_doc},
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000743 {NULL, NULL} /* sentinel */
744};
745
746PyDoc_STRVAR(deque_doc,
747"deque(iterable) --> deque object\n\
748\n\
749Build an ordered collection accessible from endpoints only.");
750
Neal Norwitz87f10132004-02-29 15:40:53 +0000751static PyTypeObject deque_type = {
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000752 PyObject_HEAD_INIT(NULL)
753 0, /* ob_size */
754 "collections.deque", /* tp_name */
755 sizeof(dequeobject), /* tp_basicsize */
756 0, /* tp_itemsize */
757 /* methods */
758 (destructor)deque_dealloc, /* tp_dealloc */
759 (printfunc)deque_tp_print, /* tp_print */
760 0, /* tp_getattr */
761 0, /* tp_setattr */
762 0, /* tp_compare */
763 (reprfunc)deque_repr, /* tp_repr */
764 0, /* tp_as_number */
765 &deque_as_sequence, /* tp_as_sequence */
766 0, /* tp_as_mapping */
767 deque_nohash, /* tp_hash */
768 0, /* tp_call */
769 0, /* tp_str */
770 PyObject_GenericGetAttr, /* tp_getattro */
771 0, /* tp_setattro */
772 0, /* tp_as_buffer */
Raymond Hettinger691d8052004-05-30 07:26:47 +0000773 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
774 Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000775 deque_doc, /* tp_doc */
Raymond Hettinger0a4977c2004-03-01 23:16:22 +0000776 (traverseproc)deque_traverse, /* tp_traverse */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000777 (inquiry)deque_clear, /* tp_clear */
Raymond Hettinger738ec902004-02-29 02:15:56 +0000778 (richcmpfunc)deque_richcompare, /* tp_richcompare */
Raymond Hettinger691d8052004-05-30 07:26:47 +0000779 offsetof(dequeobject, weakreflist), /* tp_weaklistoffset*/
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000780 (getiterfunc)deque_iter, /* tp_iter */
781 0, /* tp_iternext */
782 deque_methods, /* tp_methods */
783 0, /* tp_members */
784 0, /* tp_getset */
785 0, /* tp_base */
786 0, /* tp_dict */
787 0, /* tp_descr_get */
788 0, /* tp_descr_set */
789 0, /* tp_dictoffset */
790 (initproc)deque_init, /* tp_init */
791 PyType_GenericAlloc, /* tp_alloc */
792 deque_new, /* tp_new */
793 PyObject_GC_Del, /* tp_free */
794};
795
796/*********************** Deque Iterator **************************/
797
798typedef struct {
799 PyObject_HEAD
800 int index;
801 block *b;
802 dequeobject *deque;
803 int len;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000804 int counter;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000805} dequeiterobject;
806
807PyTypeObject dequeiter_type;
808
809static PyObject *
810deque_iter(dequeobject *deque)
811{
812 dequeiterobject *it;
813
814 it = PyObject_New(dequeiterobject, &dequeiter_type);
815 if (it == NULL)
816 return NULL;
817 it->b = deque->leftblock;
818 it->index = deque->leftindex;
819 Py_INCREF(deque);
820 it->deque = deque;
821 it->len = deque->len;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000822 it->counter = deque->len;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000823 return (PyObject *)it;
824}
825
826static void
827dequeiter_dealloc(dequeiterobject *dio)
828{
829 Py_XDECREF(dio->deque);
830 dio->ob_type->tp_free(dio);
831}
832
833static PyObject *
834dequeiter_next(dequeiterobject *it)
835{
836 PyObject *item;
837 if (it->b == it->deque->rightblock && it->index > it->deque->rightindex)
838 return NULL;
839
840 if (it->len != it->deque->len) {
841 it->len = -1; /* Make this state sticky */
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000842 it->counter = 0;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000843 PyErr_SetString(PyExc_RuntimeError,
844 "deque changed size during iteration");
845 return NULL;
846 }
847
848 item = it->b->data[it->index];
849 it->index++;
850 if (it->index == BLOCKLEN && it->b->rightlink != NULL) {
851 it->b = it->b->rightlink;
852 it->index = 0;
853 }
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000854 it->counter--;
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000855 Py_INCREF(item);
856 return item;
857}
858
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000859static int
860dequeiter_len(dequeiterobject *it)
861{
862 return it->counter;
863}
864
865static PySequenceMethods dequeiter_as_sequence = {
866 (inquiry)dequeiter_len, /* sq_length */
867 0, /* sq_concat */
868};
869
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000870PyTypeObject dequeiter_type = {
871 PyObject_HEAD_INIT(NULL)
872 0, /* ob_size */
873 "deque_iterator", /* tp_name */
874 sizeof(dequeiterobject), /* tp_basicsize */
875 0, /* tp_itemsize */
876 /* methods */
877 (destructor)dequeiter_dealloc, /* tp_dealloc */
878 0, /* tp_print */
879 0, /* tp_getattr */
880 0, /* tp_setattr */
881 0, /* tp_compare */
882 0, /* tp_repr */
883 0, /* tp_as_number */
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000884 &dequeiter_as_sequence, /* tp_as_sequence */
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000885 0, /* tp_as_mapping */
886 0, /* tp_hash */
887 0, /* tp_call */
888 0, /* tp_str */
889 PyObject_GenericGetAttr, /* tp_getattro */
890 0, /* tp_setattro */
891 0, /* tp_as_buffer */
892 Py_TPFLAGS_DEFAULT, /* tp_flags */
893 0, /* tp_doc */
894 0, /* tp_traverse */
895 0, /* tp_clear */
896 0, /* tp_richcompare */
897 0, /* tp_weaklistoffset */
898 PyObject_SelfIter, /* tp_iter */
899 (iternextfunc)dequeiter_next, /* tp_iternext */
900 0,
901};
902
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000903/*********************** Deque Reverse Iterator **************************/
904
905PyTypeObject dequereviter_type;
906
907static PyObject *
908deque_reviter(dequeobject *deque)
909{
910 dequeiterobject *it;
911
912 it = PyObject_New(dequeiterobject, &dequereviter_type);
913 if (it == NULL)
914 return NULL;
915 it->b = deque->rightblock;
916 it->index = deque->rightindex;
917 Py_INCREF(deque);
918 it->deque = deque;
919 it->len = deque->len;
920 it->counter = deque->len;
921 return (PyObject *)it;
922}
923
924static PyObject *
925dequereviter_next(dequeiterobject *it)
926{
927 PyObject *item;
928 if (it->b == it->deque->leftblock && it->index < it->deque->leftindex)
929 return NULL;
930
931 if (it->len != it->deque->len) {
932 it->len = -1; /* Make this state sticky */
Raymond Hettinger7892b1c2004-04-12 18:10:01 +0000933 it->counter = 0;
Raymond Hettinger1e5809f2004-03-18 11:04:57 +0000934 PyErr_SetString(PyExc_RuntimeError,
935 "deque changed size during iteration");
936 return NULL;
937 }
938
939 item = it->b->data[it->index];
940 it->index--;
941 if (it->index == -1 && it->b->leftlink != NULL) {
942 it->b = it->b->leftlink;
943 it->index = BLOCKLEN - 1;
944 }
945 it->counter--;
946 Py_INCREF(item);
947 return item;
948}
949
950PyTypeObject dequereviter_type = {
951 PyObject_HEAD_INIT(NULL)
952 0, /* ob_size */
953 "deque_reverse_iterator", /* tp_name */
954 sizeof(dequeiterobject), /* tp_basicsize */
955 0, /* tp_itemsize */
956 /* methods */
957 (destructor)dequeiter_dealloc, /* tp_dealloc */
958 0, /* tp_print */
959 0, /* tp_getattr */
960 0, /* tp_setattr */
961 0, /* tp_compare */
962 0, /* tp_repr */
963 0, /* tp_as_number */
964 &dequeiter_as_sequence, /* tp_as_sequence */
965 0, /* tp_as_mapping */
966 0, /* tp_hash */
967 0, /* tp_call */
968 0, /* tp_str */
969 PyObject_GenericGetAttr, /* tp_getattro */
970 0, /* tp_setattro */
971 0, /* tp_as_buffer */
972 Py_TPFLAGS_DEFAULT, /* tp_flags */
973 0, /* tp_doc */
974 0, /* tp_traverse */
975 0, /* tp_clear */
976 0, /* tp_richcompare */
977 0, /* tp_weaklistoffset */
978 PyObject_SelfIter, /* tp_iter */
979 (iternextfunc)dequereviter_next, /* tp_iternext */
980 0,
981};
982
Raymond Hettinger756b3f32004-01-29 06:37:52 +0000983/* module level code ********************************************************/
984
985PyDoc_STRVAR(module_doc,
986"High performance data structures\n\
987");
988
989PyMODINIT_FUNC
990initcollections(void)
991{
992 PyObject *m;
993
994 m = Py_InitModule3("collections", NULL, module_doc);
995
996 if (PyType_Ready(&deque_type) < 0)
997 return;
998 Py_INCREF(&deque_type);
999 PyModule_AddObject(m, "deque", (PyObject *)&deque_type);
1000
1001 if (PyType_Ready(&dequeiter_type) < 0)
Tim Peters1065f752004-10-01 01:03:29 +00001002 return;
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001003
Raymond Hettinger1e5809f2004-03-18 11:04:57 +00001004 if (PyType_Ready(&dequereviter_type) < 0)
1005 return;
1006
Raymond Hettinger756b3f32004-01-29 06:37:52 +00001007 return;
1008}