common/consumer_table_pops.lua (83 lines of code) (raw):

local rets = {} -- pop Key, Value and OP together. local popsize = ARGV[1] * 3 local keys = redis.call('LRANGE', KEYS[1], -popsize, -1) redis.call('LTRIM', KEYS[1], 0, -popsize-1) local n = table.getn(keys) for i = n, 1, -3 do local op = keys[i-2] local value = keys[i-1] local key = keys[i] local dbop = op:sub(1,1) op = op:sub(2) local ret = {key, op} local jj = cjson.decode(value) local size = #jj for idx=1,size,2 do table.insert(ret, jj[idx]) table.insert(ret, jj[idx+1]) end table.insert(rets, ret) if ARGV[2] == "0" then -- do nothing, we don't want to modify redis during pop elseif op == 'bulkset' or op == 'bulkcreate' or op == 'bulkremove' then -- key is "OBJECT_TYPE:num", extract object type from key key = key:sub(1, string.find(key, ':') - 1) local len = #ret local st = 3 -- since 1 and 2 is key/op while st <= len do local field = ret[st] -- keyname is ASIC_STATE : OBJECT_TYPE : OBJECT_ID local keyname = KEYS[2] .. ':' .. key .. ':' .. field if op == 'bulkremove' then redis.call('DEL', keyname) else -- value can be multiple a=v|a=v|... we need to split using gmatch local vars = ret[st+1] for value in string.gmatch(vars,'([^|]+)') do local attr = value:sub(1, string.find(value, '=') - 1) local val = value.sub(value, string.find(value, '=') + 1) redis.call('HSET', keyname, attr, val) end end st = st + 2 end elseif op == 'set' or op == 'SET' or op == 'create' or op == 'remove' or op == 'DEL' then -- put entries into REDIS hash only when operations are this types -- in case of delete command, remove entries local keyname = KEYS[2] .. ':' .. key if key == '' then keyname = KEYS[2] end if dbop == 'D' then redis.call('DEL', keyname) else local st = 3 local len = #ret while st <= len do redis.call('HSET', keyname, ret[st], ret[st+1]) st = st + 2 end end elseif op == 'flush' or op == 'flushresponse' or op == 'get' or op == 'bulkget' or op == 'getresponse' or op == 'notify' or op == 'get_stats' or op == 'clear_stats' or op == 'attribute_capability_query' or op == 'attribute_capability_response' or op == 'attr_enum_values_capability_query' or op == 'attr_enum_values_capability_response' or op == 'object_type_get_availability_query' or op == 'object_type_get_availability_response' or op == 'stats_capability_query' or op == 'stats_capability_response' or op == 'stats_st_capability_query' or op == 'stats_st_capability_response' then -- do not modify db entries when spotted those commands, they are used to -- trigger actions or get data synchronously from database -- also force to allow only those commands, so when new command will be -- added it will force programmer to support this command also here in -- right way else -- notify redis that this command is not supported and require handling error("unsupported operation command: " .. op .. ", FIXME") end end return rets