Skip to content

Instantly share code, notes, and snippets.

@rufoa
Last active June 5, 2018 16:40
Show Gist options
  • Save rufoa/6672d5a0ef9252c2594b1d69bea62520 to your computer and use it in GitHub Desktop.
Save rufoa/6672d5a0ef9252c2594b1d69bea62520 to your computer and use it in GitHub Desktop.
redis zpopmin/zpopmax in lua
# same behaviour as zpopmax/zpopmin in redis 5.0.0-RC2:
# count arg defaults to 1
# count > 0: return count many items
# count <= 0: return all items
lua_zpopmax = """
assert(#KEYS == 1)
assert(#ARGV <= 1)
local count = 1
if #ARGV == 1 then count = math.max(ARGV[1], 0) end
local range = redis.call('zrevrange', KEYS[1], 0, count - 1, 'WITHSCORES')
local ret = {}
local member
for i, v in ipairs(range) do
if i % 2 == 1 then
member = v
else
table.insert(ret, {member, tonumber(v)})
end
end
redis.call('zremrangebyrank', KEYS[1], -count, -1)
return ret
"""
lua_zpopmin = """
assert(#KEYS == 1)
assert(#ARGV <= 1)
local count = 1
if #ARGV == 1 then count = math.max(ARGV[1], 0) end
local range = redis.call('zrange', KEYS[1], 0, count - 1, 'WITHSCORES')
local ret = {}
local member
for i, v in ipairs(range) do
if i % 2 == 1 then
member = v
else
table.insert(ret, {member, tonumber(v)})
end
end
redis.call('zremrangebyrank', KEYS[1], 0, count - 1)
return ret
"""
zpopmax = r.register_script(lua_zpopmax)
zpopmin = r.register_script(lua_zpopmin)
for score, member in zpopmin(keys=['myzset'], args=[10]):
# etc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment