The problem/use-case that the feature addresses
Superfast min and max finding.
SET TEMPERATUREMIN -24.5 MIN SET TEMPERATUREMAX 37.8 MAX
Description of the feature
SET TEMPERATUREMIN -24.5 MIN Set only if current value of key is higher than new value
SET TEMPERATUREMAX 37.8 MAX Set only if current value of key is smaller than new value
Alternatives you've considered
Client code: VALUE = GET REDIS.GET(KEY) IF VALUE>NEWVALUE THEN REDIS.SET(KEY,VALUE) END-IF Requires unnecessary communication via network, and is not atomic (other process/thread/connection could possibly corrupt the value).
Lua code (HASH VARIANT): (example: EVAL INSERT-LUA-CODE-HERE 2 KEY FIELD 8) local newv = tonumber(ARGV[1]) local temp = tonumber(redis.call('HGET', KEYS[1], KEYS[2])) if (not temp) or (newv < temp) then redis.call('HSET', KEYS[1], KEYS[2], newv) end
Could be done, needs to be either pre-loaded or evaluated every time.
Feature feels small, but useful and use case general enough to warrant consideration for implementation. SET NX and XX variants provide similar feature (these are all "Only Set If Condition" -features).
Additional information
None.
Comment From: hwware
Hi @tomidotomicode, this looks to be a good addition for set, I can work on this and submit a pull request. @oranagra WDYT?
Comment From: mgravell
This seems like it could already be done today using ZADD with the LT / GT switch, as a workaround. Just trying to offer a "works today" alternative.
ZADD TEMPS LT -24.5 MIN
ZADD TEMPS GT 37.8 MAX
This gives you a sorted set with 2 members with the score as the lowest/highest value recorded, respectively.
If similar was considered for SET, it should probably use the same LT/GT tokens.
Comment From: tomidotomicode
@hwware Thanks! @mgravell Oh wow! I did not know about this one. Indeed, this could work. Seems like I was only thinking of the variable, not if there is something else that could do it.
ZADD TEMPS LT -23.5 MIN ZADD TEMPS GT 28.2 MAX ZSCORE TEMPS MIN ZSCORE TEMPS MAX
I agree with the LT / GT tokens.
Comment From: mgravell
ZMSCORE TEMPS MIN MAX
Comment From: oranagra
i suppose that the same way we have NX/XX and GT/LT in ZADD, we can add them to SET (already has NX/XX, so missing GT/LT). And then figure out how to add a similar feature to HSET (which is variadic, and has a separate HSETNX command). However, i wonder how far we should go with these. I think this is exactly the reason why scripts were introduced, i.e. to avoid the need for a ton of use-case specific variants on commands. So i suppose the question is how common this use case (and for which of these commands, SET and HSET). If there's one case that's very common, we wanna add a built in command, but if there are a ton of different use cases, each requires a different variant, maybe scripts are the right answer.
Comment From: tomidotomicode
@oranagra how far? now that you asked... maybe CAS (Compare And Swap) should be added as well. While in some cases WATCH, MULTI, EXEC could be used to provide CAS-like functionality.
Instead it could be done like this:
[ someValue, casToken ] = GET someKey CAS
then do something, display data in the user interface or something
SET someKey 1234 CAS casToken
If casToken does not match current token, then set must fail. If casToken matches, then set to given value and create new cas token
In simple cases, CAS could be just a value, but given that values can be of any size, maybe token could be a timestamp, or some quickly calculated hash out of value.
This feature can be found in Memcached, Couchbase.
Comment From: oranagra
we have other discussions on CAS (e.g. #8361 and maybe others), but for this one i thought we wanted to focus on something that doesn't require another round-trip to the client, and allows keeping track of minimum and maximum values. can you explain how it is related? would such a feature replace your need for MIN/MAX flags?
Comment From: tomidotomicode
@oranagra That was just a reply to "However, i wonder how far we should go with these."
I assumed that with "these" you meant "Only Set If Condition" -features. CAS is just one example of "Only Set If Condition" -feature, and using it does not require another round-trip to the client (because both values, old and new, are present upon calculation of CAS token).
It was not a replacement to LT/GT (MIN/MAX) or anything, just a general comment about how far these OSIC features could go.
Comment From: tomidotomicode
@oranagra I have submitted another ticket #12485 about CAS features, so any comments about CAS here in this thread may be disregarded.
Comment From: hwware
Thank you for your input @oranagra, Sure I will work and create a PR. Also will check for feasibilty for HSET too.