71 lines
2.5 KiB
Lua
71 lines
2.5 KiB
Lua
--[[
|
|
Function to achieve pagination for a set or hash.
|
|
This function simulates pagination in the most efficient way possible
|
|
for a set using sscan or hscan.
|
|
|
|
The main limitation is that sets are not order preserving, so the
|
|
pagination is not stable. This means that if the set is modified
|
|
between pages, the same element may appear in different pages.
|
|
]] -- Maximum number of elements to be returned by sscan per iteration.
|
|
local maxCount = 100
|
|
|
|
-- Finds the cursor, and returns the first elements available for the requested page.
|
|
local function findPage(key, command, pageStart, pageSize, cursor, offset,
|
|
maxIterations, fetchJobs)
|
|
local items = {}
|
|
local jobs = {}
|
|
local iterations = 0
|
|
|
|
repeat
|
|
-- Iterate over the set using sscan/hscan.
|
|
local result = rcall(command, key, cursor, "COUNT", maxCount)
|
|
|
|
cursor = result[1]
|
|
local members = result[2]
|
|
local step = 1
|
|
if command == "HSCAN" then
|
|
step = 2
|
|
end
|
|
|
|
if #members == 0 then
|
|
-- If the result is empty, we can return the result.
|
|
return cursor, offset, items, jobs
|
|
end
|
|
|
|
local chunkStart = offset
|
|
local chunkEnd = offset + #members / step
|
|
|
|
local pageEnd = pageStart + pageSize
|
|
|
|
if chunkEnd < pageStart then
|
|
-- If the chunk is before the page, we can skip it.
|
|
offset = chunkEnd
|
|
elseif chunkStart > pageEnd then
|
|
-- If the chunk is after the page, we can return the result.
|
|
return cursor, offset, items, jobs
|
|
else
|
|
-- If the chunk is overlapping the page, we need to add the elements to the result.
|
|
for i = 1, #members, step do
|
|
if offset >= pageEnd then
|
|
return cursor, offset, items, jobs
|
|
end
|
|
if offset >= pageStart then
|
|
local index = #items + 1
|
|
if fetchJobs ~= nil then
|
|
jobs[#jobs+1] = rcall("HGETALL", members[i])
|
|
end
|
|
if step == 2 then
|
|
items[index] = {members[i], members[i + 1]}
|
|
else
|
|
items[index] = members[i]
|
|
end
|
|
end
|
|
offset = offset + 1
|
|
end
|
|
end
|
|
iterations = iterations + 1
|
|
until cursor == "0" or iterations >= maxIterations
|
|
|
|
return cursor, offset, items, jobs
|
|
end
|