Last active
June 8, 2020 13:10
-
-
Save ensky/087f10049da3b6c2f75934f8d5b260dd to your computer and use it in GitHub Desktop.
redis zpopmin / zpopmax in lua for redis < 5.0.0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- redis-priority-queue | |
-- Author: Ensky Lin | |
-- Version: 1.0.0 | |
-- (can only be used in 3.2+) | |
-- Get mandatory vars | |
local action = ARGV[1]; | |
local key = ARGV[2]; | |
local count = ARGV[3]; | |
-- returns true if empty or null | |
-- http://stackoverflow.com/a/19667498/50501 | |
local function isempty(s) | |
return s == nil or s == '' or type(s) == 'userdata' | |
end | |
-- Making sure required fields are not nil | |
assert(not isempty(action), 'ERR1: Action is missing') | |
assert(not isempty(key), 'ERR2: Queue name is missing') | |
assert(not isempty(count), 'ERR3: Count is missing') | |
if action == 'zpopmin' or action == 'zpopmax' | |
then | |
-- debug | |
redis.debug(action..' executed with count '..count); | |
if action == 'zpopmin' -- asc sorting | |
then | |
rangeMethod = 'ZRANGEBYSCORE'; | |
fromMin = '-inf'; | |
toMax ='+inf'; | |
else -- desc sorting | |
rangeMethod = 'ZREVRANGEBYSCORE'; | |
fromMin = '+inf'; | |
toMax ='-inf'; | |
end | |
-- Retrieve items | |
local popped = redis.call(rangeMethod, key, fromMin, toMax, 'LIMIT', 0, count) | |
-- If items are popped from the list | |
-- Rotate thru popped items | |
if popped then | |
for _,item in ipairs(popped) do | |
-- debug | |
redis.debug('...popped item -> '..item); | |
-- Remove item | |
redis.call('ZREM', key, item) | |
end | |
end | |
return popped; | |
else | |
error('ERR3: Invalid action.') | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment