--[[******************************************************************************]] --[[* Project ib_win_core *]] --[[* Copyright 2024 Incredibuild Software Ltd. *]] --[[* All rights reserved *]] --[[******************************************************************************]] local function get_times(timestamp) local times = redis.call('KEYS', '*') if #times == 0 then return times, 1 end table.sort(times) local first, last = 1, #times if times[last] < timestamp then return times, #times + 1 end while times[first] < timestamp do local mid = math.floor((first + last) / 2) if times[mid] == timestamp then return times, mid elseif times[mid] < timestamp then first = mid + 1 else last = mid - 1 end end return times, first end local function get_items(batch, times, first) local items = {} for i = first, #times do local time, cursor = times[i], '0' if #items >= batch then return time, items end repeat local hscan cursor, hscan = unpack(redis.call('HSCAN', time, cursor)) for j = 1, #hscan, 2 do items[#items + 1] = hscan[j] end until cursor == '0' end return 0, items end local function main(infoDB, usageDB, timestamp, batch) redis.call('SELECT', usageDB) local times, first = get_times(timestamp) local next_timestamp, items = get_items(tonumber(batch), times, first) redis.call('SELECT', infoDB) return next_timestamp, table.concat(items, " ") end local ok, next_timestamp, items = pcall(main, unpack(ARGV)) if not ok then return '-1\n' .. next_timestamp end return next_timestamp .. '\n' .. items