summaryrefslogtreecommitdiffstats
path: root/Modules/_collectionsmodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_collectionsmodule.c')
-rw-r--r--Modules/_collectionsmodule.c103
1 files changed, 63 insertions, 40 deletions
diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c
index f450f25..087f8e5 100644
--- a/Modules/_collectionsmodule.c
+++ b/Modules/_collectionsmodule.c
@@ -539,32 +539,6 @@ deque_concat(dequeobject *deque, PyObject *other)
static void deque_clear(dequeobject *deque);
static PyObject *
-deque_repeat(dequeobject *deque, Py_ssize_t n)
-{
- dequeobject *new_deque;
- PyObject *result;
-
- /* XXX add a special case for when maxlen is defined */
- if (n < 0)
- n = 0;
- else if (n > 0 && Py_SIZE(deque) > MAX_DEQUE_LEN / n)
- return PyErr_NoMemory();
-
- new_deque = (dequeobject *)deque_new(&deque_type, (PyObject *)NULL, (PyObject *)NULL);
- new_deque->maxlen = deque->maxlen;
-
- for ( ; n ; n--) {
- result = deque_extend(new_deque, (PyObject *)deque);
- if (result == NULL) {
- Py_DECREF(new_deque);
- return NULL;
- }
- Py_DECREF(result);
- }
- return (PyObject *)new_deque;
-}
-
-static PyObject *
deque_inplace_repeat(dequeobject *deque, Py_ssize_t n)
{
Py_ssize_t i, size;
@@ -583,10 +557,6 @@ deque_inplace_repeat(dequeobject *deque, Py_ssize_t n)
return (PyObject *)deque;
}
- if (size > MAX_DEQUE_LEN / n) {
- return PyErr_NoMemory();
- }
-
if (size == 1) {
/* common case, repeating a single element */
PyObject *item = deque->leftblock->data[deque->leftindex];
@@ -594,16 +564,39 @@ deque_inplace_repeat(dequeobject *deque, Py_ssize_t n)
if (deque->maxlen != -1 && n > deque->maxlen)
n = deque->maxlen;
- for (i = 0 ; i < n-1 ; i++) {
- rv = deque_append(deque, item);
- if (rv == NULL)
- return NULL;
- Py_DECREF(rv);
+ if (n > MAX_DEQUE_LEN)
+ return PyErr_NoMemory();
+
+ deque->state++;
+ for (i = 0 ; i < n-1 ; ) {
+ if (deque->rightindex == BLOCKLEN - 1) {
+ block *b = newblock(Py_SIZE(deque) + i);
+ if (b == NULL) {
+ Py_SIZE(deque) += i;
+ return NULL;
+ }
+ b->leftlink = deque->rightblock;
+ CHECK_END(deque->rightblock->rightlink);
+ deque->rightblock->rightlink = b;
+ deque->rightblock = b;
+ MARK_END(b->rightlink);
+ deque->rightindex = -1;
+ }
+ for ( ; i < n-1 && deque->rightindex != BLOCKLEN - 1 ; i++) {
+ deque->rightindex++;
+ Py_INCREF(item);
+ deque->rightblock->data[deque->rightindex] = item;
+ }
}
+ Py_SIZE(deque) += i;
Py_INCREF(deque);
return (PyObject *)deque;
}
+ if ((size_t)size > MAX_DEQUE_LEN / (size_t)n) {
+ return PyErr_NoMemory();
+ }
+
seq = PySequence_List((PyObject *)deque);
if (seq == NULL)
return seq;
@@ -621,6 +614,20 @@ deque_inplace_repeat(dequeobject *deque, Py_ssize_t n)
return (PyObject *)deque;
}
+static PyObject *
+deque_repeat(dequeobject *deque, Py_ssize_t n)
+{
+ dequeobject *new_deque;
+ PyObject *rv;
+
+ new_deque = (dequeobject *)deque_copy((PyObject *) deque);
+ if (new_deque == NULL)
+ return NULL;
+ rv = deque_inplace_repeat(new_deque, n);
+ Py_DECREF(new_deque);
+ return rv;
+}
+
/* The rotate() method is part of the public API and is used internally
as a primitive for other methods.
@@ -792,7 +799,7 @@ deque_reverse(dequeobject *deque, PyObject *unused)
block *rightblock = deque->rightblock;
Py_ssize_t leftindex = deque->leftindex;
Py_ssize_t rightindex = deque->rightindex;
- Py_ssize_t n = Py_SIZE(deque) / 2;
+ Py_ssize_t n = Py_SIZE(deque) >> 1;
Py_ssize_t i;
PyObject *tmp;
@@ -1053,7 +1060,7 @@ deque_clear(dequeobject *deque)
static int
valid_index(Py_ssize_t i, Py_ssize_t limit)
{
- /* The cast to size_t let us use just a single comparison
+ /* The cast to size_t lets us use just a single comparison
to check whether i is in the range: 0 <= i < limit */
return (size_t) i < (size_t) limit;
}
@@ -1200,6 +1207,22 @@ deque_traverse(dequeobject *deque, visitproc visit, void *arg)
static PyObject *
deque_copy(PyObject *deque)
{
+ if (Py_TYPE(deque) == &deque_type) {
+ dequeobject *new_deque;
+ PyObject *rv;
+
+ new_deque = (dequeobject *)deque_new(&deque_type, (PyObject *)NULL, (PyObject *)NULL);
+ if (new_deque == NULL)
+ return NULL;
+ new_deque->maxlen = ((dequeobject *)deque)->maxlen;
+ rv = deque_extend(new_deque, deque);
+ if (rv != NULL) {
+ Py_DECREF(rv);
+ return (PyObject *)new_deque;
+ }
+ Py_DECREF(new_deque);
+ return NULL;
+ }
if (((dequeobject *)deque)->maxlen == -1)
return PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "O", deque, NULL);
else
@@ -2173,13 +2196,13 @@ _count_elements(PyObject *self, PyObject *args)
oldval = _PyDict_GetItem_KnownHash(mapping, key, hash);
if (oldval == NULL) {
- if (_PyDict_SetItem_KnownHash(mapping, key, one, hash) == -1)
+ if (_PyDict_SetItem_KnownHash(mapping, key, one, hash) < 0)
goto done;
} else {
newval = PyNumber_Add(oldval, one);
if (newval == NULL)
goto done;
- if (_PyDict_SetItem_KnownHash(mapping, key, newval, hash) == -1)
+ if (_PyDict_SetItem_KnownHash(mapping, key, newval, hash) < 0)
goto done;
Py_CLEAR(newval);
}
@@ -2205,7 +2228,7 @@ _count_elements(PyObject *self, PyObject *args)
Py_DECREF(oldval);
if (newval == NULL)
break;
- if (PyObject_SetItem(mapping, key, newval) == -1)
+ if (PyObject_SetItem(mapping, key, newval) < 0)
break;
Py_CLEAR(newval);
Py_DECREF(key);