Move the freeblock() call outside the main loop to speed-up and simplify the block re-use logic.

This commit is contained in:
Raymond Hettinger 2013-07-13 02:34:08 -07:00
parent ae13ff1c5f
commit 3959af9b2a
1 changed files with 15 additions and 9 deletions

View File

@ -454,12 +454,13 @@ deque_inplace_concat(dequeobject *deque, PyObject *other)
static int static int
_deque_rotate(dequeobject *deque, Py_ssize_t n) _deque_rotate(dequeobject *deque, Py_ssize_t n)
{ {
block *b = NULL;
block *leftblock = deque->leftblock; block *leftblock = deque->leftblock;
block *rightblock = deque->rightblock; block *rightblock = deque->rightblock;
Py_ssize_t leftindex = deque->leftindex; Py_ssize_t leftindex = deque->leftindex;
Py_ssize_t rightindex = deque->rightindex; Py_ssize_t rightindex = deque->rightindex;
Py_ssize_t len=Py_SIZE(deque), halflen=len>>1; Py_ssize_t len=Py_SIZE(deque), halflen=len>>1;
int rv = 0; int rv = -1;
if (len <= 1) if (len <= 1)
return 0; return 0;
@ -476,10 +477,10 @@ _deque_rotate(dequeobject *deque, Py_ssize_t n)
deque->state++; deque->state++;
while (n > 0) { while (n > 0) {
if (leftindex == 0) { if (leftindex == 0) {
block *b = newblock(len);
if (b == NULL) { if (b == NULL) {
rv = -1; b = newblock(len);
goto done; if (b == NULL)
goto done;
} }
b->rightlink = leftblock; b->rightlink = leftblock;
CHECK_END(leftblock->leftlink); CHECK_END(leftblock->leftlink);
@ -487,6 +488,7 @@ _deque_rotate(dequeobject *deque, Py_ssize_t n)
leftblock = b; leftblock = b;
MARK_END(b->leftlink); MARK_END(b->leftlink);
leftindex = BLOCKLEN; leftindex = BLOCKLEN;
b = NULL;
} }
assert(leftindex > 0); assert(leftindex > 0);
@ -511,7 +513,7 @@ _deque_rotate(dequeobject *deque, Py_ssize_t n)
if (rightindex == -1) { if (rightindex == -1) {
block *prevblock = rightblock->leftlink; block *prevblock = rightblock->leftlink;
assert(leftblock != rightblock); assert(leftblock != rightblock);
freeblock(rightblock); b = rightblock;
CHECK_NOT_END(prevblock); CHECK_NOT_END(prevblock);
MARK_END(prevblock->rightlink); MARK_END(prevblock->rightlink);
rightblock = prevblock; rightblock = prevblock;
@ -520,10 +522,10 @@ _deque_rotate(dequeobject *deque, Py_ssize_t n)
} }
while (n < 0) { while (n < 0) {
if (rightindex == BLOCKLEN - 1) { if (rightindex == BLOCKLEN - 1) {
block *b = newblock(len);
if (b == NULL) { if (b == NULL) {
rv = -1; b = newblock(len);
goto done; if (b == NULL)
goto done;
} }
b->leftlink = rightblock; b->leftlink = rightblock;
CHECK_END(rightblock->rightlink); CHECK_END(rightblock->rightlink);
@ -531,6 +533,7 @@ _deque_rotate(dequeobject *deque, Py_ssize_t n)
rightblock = b; rightblock = b;
MARK_END(b->rightlink); MARK_END(b->rightlink);
rightindex = -1; rightindex = -1;
b = NULL;
} }
assert (rightindex < BLOCKLEN - 1); assert (rightindex < BLOCKLEN - 1);
@ -555,14 +558,17 @@ _deque_rotate(dequeobject *deque, Py_ssize_t n)
if (leftindex == BLOCKLEN) { if (leftindex == BLOCKLEN) {
block *nextblock = leftblock->rightlink; block *nextblock = leftblock->rightlink;
assert(leftblock != rightblock); assert(leftblock != rightblock);
freeblock(leftblock); b = leftblock;
CHECK_NOT_END(nextblock); CHECK_NOT_END(nextblock);
MARK_END(nextblock->leftlink); MARK_END(nextblock->leftlink);
leftblock = nextblock; leftblock = nextblock;
leftindex = 0; leftindex = 0;
} }
} }
rv = 0;
done: done:
if (b != NULL)
freeblock(b);
deque->leftblock = leftblock; deque->leftblock = leftblock;
deque->rightblock = rightblock; deque->rightblock = rightblock;
deque->leftindex = leftindex; deque->leftindex = leftindex;