Skip to content

Commit

Permalink
fix: circular dependency in qlist (#4302)
Browse files Browse the repository at this point in the history
* fix: circular dependency in qlist

fixes #4294

Signed-off-by: Roman Gershman <[email protected]>

* chore: fixes

Signed-off-by: Roman Gershman <[email protected]>

---------

Signed-off-by: Roman Gershman <[email protected]>
  • Loading branch information
romange authored Dec 13, 2024
1 parent f564513 commit 5363779
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 7 deletions.
14 changes: 10 additions & 4 deletions src/core/qlist.cc
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ string QList::Pop(Where where) {

/* The head and tail should never be compressed */
DCHECK(node->encoding != QUICKLIST_NODE_ENCODING_LZF);
DCHECK(head_->prev->next == nullptr);

string res;
if (ABSL_PREDICT_FALSE(QL_NODE_IS_PLAIN(node))) {
Expand All @@ -390,6 +391,7 @@ string QList::Pop(Where where) {
}
DelPackedIndex(node, pos);
}
DCHECK(head_ == nullptr || head_->prev->next == nullptr);
return res;
}

Expand Down Expand Up @@ -479,11 +481,13 @@ bool QList::PushSentinel(string_view value, Where where) {
if (len_ == 1) { // sanity check
DCHECK_EQ(malloc_size_, orig->sz);
}
DCHECK(head_->prev->next == nullptr);
return false;
}

quicklistNode* node = CreateFromSV(QUICKLIST_NODE_CONTAINER_PACKED, value);
InsertNode(orig, node, opt);
DCHECK(head_->prev->next == nullptr);
return true;
}

Expand Down Expand Up @@ -837,13 +841,15 @@ quicklistNode* QList::ListpackMerge(quicklistNode* a, quicklistNode* b) {
void QList::DelNode(quicklistNode* node) {
if (node->next)
node->next->prev = node->prev;
if (node->prev)
node->prev->next = node->next;

if (node == head_) {
head_ = node->next;
} else if (node == head_->prev) { // tail
head_->prev = node->prev;
} else {
// for non-head nodes, update prev->next to point to node->next
// (If node==head, prev is tail and should always point to NULL).
node->prev->next = node->next;
if (node == head_->prev) // tail
head_->prev = node->prev;
}

/* Update len first, so in Compress we know exactly len */
Expand Down
9 changes: 9 additions & 0 deletions src/core/qlist_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,15 @@ TEST_F(QListTest, CompressionPlain) {
EXPECT_EQ(500, i);
}

TEST_F(QListTest, LargeValues) {
string val(100000, 'a');
ql_.Push(val, QList::HEAD);
ql_.Push(val, QList::HEAD);
ql_.Pop(QList::HEAD);
auto items = ToItems();
EXPECT_THAT(items, ElementsAre(val));
}

using FillCompress = tuple<int, unsigned>;

class PrintToFillCompress {
Expand Down
4 changes: 1 addition & 3 deletions tests/dragonfly/seeder/script-genlib.lua
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,7 @@ end

function LG_funcs.add_list(key, keys)
local is_huge = keys[key]
--- TODO -- investigate why second case of replication_test_all fails
--- we somehow create a quicklist that is circular and we deadlock
redis.apcall('LPUSH', key, unpack(randstr_sequence(false)))
redis.apcall('LPUSH', key, unpack(randstr_sequence(is_huge)))
end

function LG_funcs.mod_list(key, keys)
Expand Down

0 comments on commit 5363779

Please sign in to comment.