Skip to content

Instantly share code, notes, and snippets.

@ensky
Last active June 8, 2020 13:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ensky/087f10049da3b6c2f75934f8d5b260dd to your computer and use it in GitHub Desktop.
Save ensky/087f10049da3b6c2f75934f8d5b260dd to your computer and use it in GitHub Desktop.
redis zpopmin / zpopmax in lua for redis < 5.0.0
-- 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