-
Couldn't load subscription status.
- Fork 929
HSETEX: Support NX/XX Flags #2668
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
base: unstable
Are you sure you want to change the base?
HSETEX: Support NX/XX Flags #2668
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## unstable #2668 +/- ##
============================================
- Coverage 72.57% 72.47% -0.10%
============================================
Files 128 128
Lines 71277 70171 -1106
============================================
- Hits 51727 50857 -870
+ Misses 19550 19314 -236
🚀 New features to boost your workflow:
|
|
Thank you @hanxizh9910 ! I am starting a holiday so will try to start review next week (sorry for that) |
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.
left some small test comments.
One thing that I just thought of is the forward compatibility. Since we are adding this in 9.1 it will make it problematic to sync commands withy the new NX/XX arguments as it is persisted on the replication stream.
Before that we kept the FXX/FNX for simplicity, but I think that we should now rewrite the command vector in case either FXX/FNX/NX/XX are included to prevent some weird replication misalignments and support replicating to 9.0.
@zuiderkwast FYI
Technically, NX and XX are new parameters in 9.1, so by starting to use them, the user opts in to the new feature. Using a new feature in the new version means that the possibility to downgrade ends. With this reasoning, it should be OK to just add them and replicate them. That said, I think it's cleaner to rewrite the command and replicate without them. |
Agree, but I think we should take extra care to try and avoid breaking this in minor version. |
|
@hanxizh9910 thank you for spotting the bug in HSETEX with FXX! However I suspect we can fix that in the upcoming 9.0 GA (it is a trivial fix IMO) and it will prevent leaving an empty key which can cause trouble. |
|
here: #2716 |
Signed-off-by: Hanxi Zhang <hanxizh@amazon.com> Generated new commands.def Signed-off-by: Hanxi Zhang <hanxizh@amazon.com> Extended parseExtendedCommandArgumentsOrReply function to handle nx and xx for COMMAND_HSET Signed-off-by: Hanxi Zhang <hanxizh@amazon.com> Added logic in hsetexCommand function to handle NX/XX Signed-off-by: Hanxi Zhang <hanxizh@amazon.com> Fix: removed two spaces to pass the format test' Signed-off-by: Hanxi Zhang <hanxizh@amazon.com> Added tests for nx/xx in hsetex command Signed-off-by: Hanxi Zhang <hanxizh@amazon.com>
Signed-off-by: Hanxi Zhang <hanxizh@amazon.com>
Signed-off-by: Hanxi Zhang <hanxizh@amazon.com>
Signed-off-by: Hanxi Zhang <hanxizh@amazon.com>
Signed-off-by: Hanxi Zhang <hanxizh@amazon.com>
Signed-off-by: Hanxi Zhang <hanxizh@amazon.com>
48584bb to
d8bcc1f
Compare
Signed-off-by: Hanxi Zhang <hanxizh@amazon.com>
Signed-off-by: Hanxi Zhang <hanxizh@amazon.com>
@ranshid , thank you for your feedback! I got the changes you made! |
|
Hi @ranshid, I made a commit to attempt rewriting the command. Could you please let me know if this is what you had in mind. Also, do you want this rewrite change included in this PR? Thank you! |
src/t_hash.c
Outdated
| /* Rewrite command vector for replication */ | ||
| if (flags & (ARGS_SET_NX | ARGS_SET_XX | ARGS_SET_FNX | ARGS_SET_FXX)) { | ||
| int rewrite_argc = 2 + num_fields * 2; // command, hash + field/value pairs | ||
| robj **rewrite_argv = zmalloc(sizeof(robj *) * rewrite_argc); | ||
| int j = 0; | ||
|
|
||
| // First argument: command | ||
| rewrite_argv[j++] = c->argv[0]; | ||
| incrRefCount(c->argv[0]); | ||
|
|
||
| // Second argument: hash | ||
| rewrite_argv[j++] = c->argv[1]; | ||
| incrRefCount(c->argv[1]); | ||
|
|
||
| // Copy all field/value pairs, skipping NX/XX/FNX/FXX flags | ||
| for (int i = fields_index; i < c->argc; i++) { | ||
| // Skip NX/XX/FNX/FXX flags | ||
| if (strcmp(c->argv[i]->ptr, "NX") && | ||
| strcmp(c->argv[i]->ptr, "XX") && | ||
| strcmp(c->argv[i]->ptr, "FNX") && | ||
| strcmp(c->argv[i]->ptr, "FXX")) { | ||
| rewrite_argv[j++] = c->argv[i]; | ||
| incrRefCount(c->argv[i]); | ||
| } | ||
| } | ||
|
|
||
| // Replace client command vector | ||
| replaceClientCommandVector(c, j, rewrite_argv); | ||
| } | ||
|
|
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.
I think this might work, but it is somewhat wasteful. For example, when we are expiring elements (eg expiration time is zero) we already managing a separate argv. I think maybe it would be better to simply use and manage a new_argv when we are doing the hashTypeSet. We can optimize by not adding the parameters when the new_argv is NULL.
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.
Hi @ranshid, thanks for the feedback! I’ve updated the function to use new_argv. Is this what you had in mind?
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.
Hi @ranshid, thanks for the feedback! I’ve updated the function to use new_argv. Is this what you had in mind?
Thank you @hanxizh9910.
Not exactly what I meant is that we might refactor the function to:
- we can set an early mark that we need to use a new argv in case flags & (ARGS_SET_NX | ARGS_SET_XX | ARGS_SET_FNX | ARGS_SET_FXX))
- Then we can allocate the relevant new_argv as an else case for the if condition in line 1263, like:
if (set_expired) {
new_argv = zmalloc(sizeof(robj *) * (num_fields + 2));
new_argv[new_argc++] = shared.hdel;
incrRefCount(shared.hdel);
new_argv[new_argc++] = c->argv[1];
incrRefCount(c->argv[1]);
} else if (flags & (ARGS_SET_NX | ARGS_SET_XX | ARGS_SET_FNX | ARGS_SET_FXX)) ) {
new_argv = zmalloc(sizeof(robj *) * (num_fields + 2));
....
}
- We should extend the code in line 1281 to manage the new_argv:
} else {
hashTypeSet(o, c->argv[i]->ptr, c->argv[i + 1]->ptr, when, set_flags);
changes++;
if (flags & (ARGS_SET_NX | ARGS_SET_XX | ARGS_SET_FNX | ARGS_SET_FXX))) {
new_argv[new_argc++] = c->argv[i];
incrRefCount(c->argv[i]);
}
}
- rewrite the command vector after we notify the keyspace event in line 1296
This might need to also handle the PXAT conversion differently (maybe earlier?) but that was my suggestion.
For your suggestion:
- this if should probably be placed under the previous
elsein line 1225, since when set_expired is true, we already rewrite the command differently without these values. - there is no need to compare each field but only fields in index 2 and up to fields_index
I guess we could also use your suggestion as well (with the 2 fixes I listed before).
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.
Hi @ranshid, thank you for your suggestion! I’ve modified the code accordingly, does this match what you had in mind?
Also, I have a question about the PXAT conversion: if no fields are modified due to NX/XX/FNX/FXX, should we still update the expiration time?
Signed-off-by: Hanxi Zhang <hanxizh@amazon.com>
…w_argc, new_argv) incorrectly before Signed-off-by: Hanxi Zhang <hanxizh@amazon.com>
Signed-off-by: Hanxi Zhang <hanxizh@amazon.com>
Signed-off-by: Hanxi Zhang <hanxizh@amazon.com>
Signed-off-by: Hanxi Zhang <hanxizh@amazon.com>
Signed-off-by: Hanxi Zhang <hanxizh@amazon.com>
Summary
Addresses #2619.
This PR extends the
HSETEXcommand to support optional key-levelNXandXXflags, allowing operations conditional on the existence of the hash key.Changes
hsetex.jsonand regeneratedcommands.def.NX/XXsupport inHSETEX.