This bug is about a node should be compressed witch is not. The following code can create that node.

TEST("limit")
{
        quicklist *ql = quicklistNew(2, 1);
        quicklistPushHead(ql, "0", 1);
        quicklistPushHead(ql, "1", 1);
        quicklistPushHead(ql, "2", 1);
        quicklistPushHead(ql, "3", 1);
        quicklistPushHead(ql, "4", 1);
        quicklistPushHead(ql, "5", 1);

        assert(ql->len == 3);
        assert(ql->head->next->encoding == QUICKLIST_NODE_ENCODING_RAW);

        size_t sz = (1 << 12);
        unsigned char *s = zmalloc(sz);
        randstring(s, sz);
        quicklistEntry entry;
        quicklistIter *iter = quicklistGetIteratorEntryAtIdx(ql, 2, &entry);
        quicklistDelEntry(iter, &entry);
        quicklistInsertAfter(iter, &entry, s, sz);
        quicklistReleaseIterator(iter);
        assert(ql->len == 3);
        /* ql->head->next is not compressed */
        assert(ql->head->next->encoding == QUICKLIST_NODE_ENCODING_RAW);

        /* ql->head->next should be compressed */
        __quicklistCompress(ql, ql->head->next);
        assert(ql->head->next->encoding == QUICKLIST_NODE_ENCODING_LZF);

        zfree(s);
        quicklistRelease(ql);
}

This bug is related with the member recompress in struct quicklistNode. A node will not be compressed if it's not compress small enough. And it will remain uncompressed after insert, because 'recompress' is 0 and will prevent compression。

Comment From: sundb

do you forget to release iterator which will compress the node?

Comment From: imchuncai

@sundb I have edited the code, release iterator won't work, cause quicklistInsertAfter() will reset the iterator .

Comment From: sundb

@imchuncai Thanks for pointing it out. This is a regression of #9849. The following cases are where we need to reset the iterator 1) node->entry was changed, whereas node->zi will be invalidated. 2) node changed, e.g. merges, deletes.

I was thinking that we could modify the way we reset the iterator. 1) When node->entry changed, we just reset node->zi. 2) When node changed, we will reset the whole iterator, and then the node compression will be handled by the business.