Hi dudes I'm actually implementing this operating right now. It's on
my todo list since ages and I think there are a few ways to implement
it in a fast way.
Let's pick MAGIC=2 (but the right value will be chosen with
redis-benchmark in an empirical way).
Command is SRANDMEMBERS <count>
First observation: if there is no count a bulk reply is returned. With
count a multi-bulk reply is returned (even if count is == 1 of
course).
Ok, so:
1) If SET_SIZE < count ---> Just serve the request with SMEMBERS as
the user asked for all the elements.
2) if SETSIZE < count * MAGIC ---> Serve the request populating a
dictionary with all the Set members, than remove elements one after
one with dictGetRandomKey() + dictDel(), so that the dictionary has
count elmenets at the end.
3) If SETSIZE >= count * MAGIC ---> Serve the request adding random
elements obtained with dictGetRandomKey() to a dictionary, not
counting duplicated elements.
In this way we always avoid pathological behaviour, making sure the
operation is reasonably fast in all the circumstances.
I think it's worth adding since:
1) We have a semantically free third argument to exploit.
2) There is no return type change for the vanilla request.
3) This is the kind of stuff that sucks done client side and it is
easy to do the wrong way.
4) Lua scripting is surely an alternative from this point of view, but
because of the "random" behaviour of the command and the subtleness
needed to implement it efficiently, it's worth a few C lines of code.
5) It is an *extremely* general operation asked by the community for
years at this point.
Exect it to it 2.6 / unstable branches in a few hours at max. An
announcement will follow.
Cheers,
Salvatore
--
Salvatore 'antirez' Sanfilippo
open source developer - VMware
http://invece.org
Beauty is more important in computing than anywhere else in technology
because software is so complicated. Beauty is the ultimate defence
against complexity.
— David Gelernter