-
Notifications
You must be signed in to change notification settings - Fork 23.5k
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
Add HSETEX command and expand HSETNX to support multi fields #9058
base: unstable
Are you sure you want to change the base?
Conversation
b98133d
to
e69d7ec
Compare
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 haven't done a very detailed review since i see there's some additional cleanup needed around the in_flags and out_flags (also indicated by the fact it is still marked as draft).
i think we should either model it more like the flags in zsetAdd, and properly expose the flags in server.h.
or we keep this a private implementation detail of t_hash.c (and keep the api used by module.c unchanged).
if we have CH flag, we don't need an UPDATED out flag, or if we have an out flag, we don't need the CH input flag (we can do the counting outside).
i suppose it'll be easier to follow and do any future updates if it's modeled after the zsets one.
let me know if there's something i'm missing, some reason why we can't do that.
other than that, this PR obviously needs some tests, (including propagation tests).
src/help.h
Outdated
{ "HSETEX", | ||
"key [NX|XX] [CH] FIELDS field value [field value ...]", | ||
"for test. Will update from doc", | ||
5, | ||
"2.0.0" }, |
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 file is auto generated from redis-doc repo, no need to edit
"write use-memory fast @hash", | ||
0,NULL,1,1,1,0,0,0}, | ||
|
||
{"hsetnx",hsetnxCommand,-4, |
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.
did we also decide to modify HSETNX?
i don't think so.
i suppose that's ok since it's trivial to implement, and may be more convenient for some users.
but it's not mentioned in the top comment, please update the top comment.
src/server.h
Outdated
@@ -2352,7 +2352,7 @@ void hashTypeCurrentObject(hashTypeIterator *hi, int what, unsigned char **vstr, | |||
sds hashTypeCurrentObjectNewSds(hashTypeIterator *hi, int what); | |||
robj *hashTypeLookupWriteOrCreate(client *c, robj *key); | |||
robj *hashTypeGetValueObject(robj *o, sds field); | |||
int hashTypeSet(robj *o, sds field, sds value, int flags); | |||
int hashTypeSet(robj *o, sds field, sds value, int flags, int in_flags, int *out_flags); |
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.
it's a bit odd to see the prototype and flag args defined in the header, but the flags themselves defined in the C file.
maybe instead the C file should have a hashTypeSetGeneric that takes the flags, and the header file should only expose the old hashTypeSet api which doesn't take any flags.
src/t_hash.c
Outdated
#define HSET_IN_NONE 0 | ||
#define HSET_IN_NX (1<<0) /* Don't touch elements not already existing. */ | ||
#define HSET_IN_XX (1<<1) /* Only touch elements already existing. */ | ||
#define HSET_IN_CH (1<<2) /* CH is an abbreviation of changed. */ |
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.
abbreviation of changed
doesn't say what it actually does. ie:
Modify the return value from the number of new elements added, to the total number of elements changed
src/t_hash.c
Outdated
*/ | ||
#define HASH_SET_TAKE_FIELD (1<<0) | ||
#define HASH_SET_TAKE_VALUE (1<<1) | ||
#define HASH_SET_COPY 0 | ||
int hashTypeSet(robj *o, sds field, sds value, int flags) { | ||
int hashTypeSet(robj *o, sds field, sds value, int flags, int in_flags, int *out_flags) { |
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.
it's odd that this function has both flags
and in_flags
.
why do we need two sets of input flags? i suppose we should combine them into one.
probably either deleting HASH_SET_COPY
(it's clear that 0 is the default for no flags), or renaming it to HASH_SET_DEFAULT
?
actually, i see this is modeled after zsetAdd
, right?
so let's continue on that path, any reason they should not be more similar (only two sets of flags, and use the out_flags instead of a CH in flag)?
src/t_hash.c
Outdated
/* HMSET (deprecated) and HSET return value is different. */ | ||
char *cmdname = c->argv[0]->ptr; | ||
if (cmdname[1] == 's' || cmdname[1] == 'S') { |
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 at this point (calling this function from a 3rd place), we should stop using this trick, and pass an argument)
or alternatively, since HMSET was the odd case, maybe do a full string compare to HMSET
rather than look at the second letter.
We have HSET to support multiple fields, but it can not extend additional parameters such as NX. We have HSETNX support NX, but it does not support multiple fields. We want to implement such as HMSETNX which support multiple fields and also supports NX flag. Improving HSETNX is easy, but we want to do it with a more generic HMSET with flags, it is common pattern. So a new command come up. Syntax for the new HSETEX command: `HSETEX key [NX|XX] [CH] FIELDS field value [field value ...]` Also we decide to extend HSETNX to support multiple fiedls since it is trivial to implement and more convenient for some users. So the new syntax for HSETNX command: `HSETNX key field value [field value ...]`
e69d7ec
to
52439a9
Compare
Sorry for taking so long.. I updated the PR based on the previous suggestions. Please ack if i do it in the right way. Also see #542 (comment), regarding the FIELDS, i may need more suggestions
I will add test cases later, but i have some questions about the propagation tests. |
haven't reviewed the changes yet. |
oh, sorry, I'm just a little confused about the last line of this comment: #9058 (review) |
i'm sorry.. looks like i'm inconsistent with myself (2 months apart). skimmed though the code again, i can't recall why i thought that this PR requires propagation tests (i don't see the code dong anything special that would be at risk). |
for what it's worth, i think the name HSETEX has some expiry connotation, i think i'd prefer using a different name (i even prefer HSET2) |
Agree with @guybe that "EX" usually means "expire", so HSETEX is not a very good name. I think HSETNX should accept multiple fields, since MSET already does that, just like HMSET. There's no reason for HSETNX to be less powerful than it's brothers and sisters. Since we already have HSETNX, I think we can add HSETXX too for symmetry, and let's make it multi-field. Or maybe we shall call it HSETX. We have LPUSHX and RPUSHX for lists. (XX is usually a flag, not part of a command name.) |
We have HSET to support multiple fields, but it can not extend
additional parameters such as NX.
We have HSETNX support NX, but it does not support multiple fields.
We want to implement such as HMSETNX which support multiple fields and
also supports NX flag.
Improving HSETNX is easy, but we want to do it with a more generic HMSET
with flags, it is common pattern. So a new command come up.
Syntax for the new HSETEX command:
HSETEX key [NX|XX] [CH] FIELDS field value [field value ...]
Also we decide to extend HSETNX to support multiple fiedls since it is
trivial to implement and more convenient for some users.
So the new syntax for HSETNX command:
HSETNX key field value [field value ...]
This one inspired from #542 (comment)
Some usage examples