New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix some bug about sds and quicklist #4674
base: unstable
Are you sure you want to change the base?
Conversation
@yebaoshan I see that there is a lot of commented code in the code, can you improve it? |
@@ -854,7 +857,7 @@ REDIS_STATIC void _quicklistInsert(quicklist *quicklist, quicklistEntry *entry, | |||
full = 1; | |||
} | |||
|
|||
if (after && (entry->offset == node->count)) { | |||
if (full && after && (entry->offset == node->count - 1)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new_node->count++; | ||
quicklistNodeUpdateSz(new_node); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is also a minor error, but it's dead code, maybe we can delete it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here the size of the new quicklistNode inserted will be 0.
This PR is a bit sloppy (it hurts my eyes 😃). so @yebaoshan if you're still here, i invite you to improve, but it looks like you moved away by now. @sundb thank you for looking into it 💯 |
@oranagra These two pr do not overlap, but the result is the same. In my two comments above, I think these two changes are OK, the changes to the sds I feel are unnecessary, they are just optimization and not bugs. |
@@ -841,8 +843,9 @@ REDIS_STATIC void _quicklistInsert(quicklist *quicklist, quicklistEntry *entry, | |||
D("No node given!"); | |||
new_node = quicklistCreateNode(); | |||
new_node->zl = ziplistPush(ziplistNew(), value, sz, ZIPLIST_HEAD); | |||
__quicklistInsertNode(quicklist, NULL, new_node, after); | |||
__quicklistInsertNode(quicklist, quicklist->tail, new_node, after); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the old code, this line of code would create a wild pointer.
new_node->count++; | ||
quicklistNodeUpdateSz(new_node); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here the size of the new quicklistNode inserted will be 0.
@@ -378,6 +378,8 @@ REDIS_STATIC void __quicklistInsertNode(quicklist *quicklist, | |||
quicklist->head = quicklist->tail = new_node; | |||
} | |||
|
|||
/* Should try to compress new_node, it may be not at head or tail */ | |||
quicklistCompress(quicklist, new_node); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the existing code, old_node
will never be NULL, so new_node
will be compressed in the following quicklistCompress(quicklist, old_node);
code, so this change is not necessary.
Some background: This fixes a problem that used to be dead code till now, but became alive (only in the unit tests, not in redis) when #9113 got merged. The problem it fixes doesn't actually cause any significant harm, but that PR also added a test that fails verification because of that. This test was merged with that problem due to human error, we didn't run it on the last modified version before merging. The fix in this PR existed in #8641 (closed because it's just dead code) and #4674 (still pending but has other changes in it). Now to the actual fix: On quicklist insertion, if the insertion offset is -1 or `-(quicklist->count)`, we can insert into the head of the next node rather than the tail of the current node. this is especially important when the current node is full, and adding anything to it will cause it to be split (or be over it's fill limit setting). The bug was that the code attempted to determine that we're adding to the tail of the current node by matching `offset == node->count` when in fact it should have been `offset == node->count-1` (so it never entered that `if`). and also that since we take negative offsets too, we can also match `-1`. same applies for the head, i.e. `0` and `-count`. The bug will cause the code to attempt inserting into the current node (thinking we have to insert into the middle of the node rather than head or tail), and in case the current node is full it'll have to be split (something that also happens in valid cases). On top of that, since it calls _quicklistSplitNode with an edge case, it'll actually split the node in a way that all the entries fall into one split, and 0 into the other, and then still insert the new entry into the first one, causing it to be populated beyond it's intended fill limit. This problem does not create any bug in redis, because the existing code does not iterate from tail to head, and the offset never has a negative value when insert. The other change this PR makes in the test code is just for some coverage, insertion at index 0 is tested a lot, so it's nice to test some negative offsets too.
…is#9311) Some background: This fixes a problem that used to be dead code till now, but became alive (only in the unit tests, not in redis) when redis#9113 got merged. The problem it fixes doesn't actually cause any significant harm, but that PR also added a test that fails verification because of that. This test was merged with that problem due to human error, we didn't run it on the last modified version before merging. The fix in this PR existed in redis#8641 (closed because it's just dead code) and redis#4674 (still pending but has other changes in it). Now to the actual fix: On quicklist insertion, if the insertion offset is -1 or `-(quicklist->count)`, we can insert into the head of the next node rather than the tail of the current node. this is especially important when the current node is full, and adding anything to it will cause it to be split (or be over it's fill limit setting). The bug was that the code attempted to determine that we're adding to the tail of the current node by matching `offset == node->count` when in fact it should have been `offset == node->count-1` (so it never entered that `if`). and also that since we take negative offsets too, we can also match `-1`. same applies for the head, i.e. `0` and `-count`. The bug will cause the code to attempt inserting into the current node (thinking we have to insert into the middle of the node rather than head or tail), and in case the current node is full it'll have to be split (something that also happens in valid cases). On top of that, since it calls _quicklistSplitNode with an edge case, it'll actually split the node in a way that all the entries fall into one split, and 0 into the other, and then still insert the new entry into the first one, causing it to be populated beyond it's intended fill limit. This problem does not create any bug in redis, because the existing code does not iterate from tail to head, and the offset never has a negative value when insert. The other change this PR makes in the test code is just for some coverage, insertion at index 0 is tested a lot, so it's nice to test some negative offsets too.
yebaoshan seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
No description provided.