Initial commit of working RSS Aggregator build
This commit is contained in:
+107
@@ -0,0 +1,107 @@
|
||||
const content = `--[[
|
||||
Paginate a set or hash
|
||||
Input:
|
||||
KEYS[1] key pointing to the set or hash to be paginated.
|
||||
ARGV[1] page start offset
|
||||
ARGV[2] page end offset (-1 for all the elements)
|
||||
ARGV[3] cursor
|
||||
ARGV[4] offset
|
||||
ARGV[5] max iterations
|
||||
ARGV[6] fetch jobs?
|
||||
Output:
|
||||
[cursor, offset, items, numItems]
|
||||
]]
|
||||
local rcall = redis.call
|
||||
-- Includes
|
||||
--[[
|
||||
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
|
||||
local key = KEYS[1]
|
||||
local scanCommand = "SSCAN"
|
||||
local countCommand = "SCARD"
|
||||
local type = rcall("TYPE", key)["ok"]
|
||||
if type == "none" then
|
||||
return {0, 0, {}, 0}
|
||||
elseif type == "hash" then
|
||||
scanCommand = "HSCAN"
|
||||
countCommand = "HLEN"
|
||||
elseif type ~= "set" then
|
||||
return
|
||||
redis.error_reply("Pagination is only supported for sets and hashes.")
|
||||
end
|
||||
local numItems = rcall(countCommand, key)
|
||||
local startOffset = tonumber(ARGV[1])
|
||||
local endOffset = tonumber(ARGV[2])
|
||||
if endOffset == -1 then
|
||||
endOffset = numItems
|
||||
end
|
||||
local pageSize = (endOffset - startOffset) + 1
|
||||
local cursor, offset, items, jobs = findPage(key, scanCommand, startOffset,
|
||||
pageSize, ARGV[3], tonumber(ARGV[4]),
|
||||
tonumber(ARGV[5]), ARGV[6])
|
||||
return {cursor, offset, items, numItems, jobs}
|
||||
`;
|
||||
export const paginate = {
|
||||
name: 'paginate',
|
||||
content,
|
||||
keys: 1,
|
||||
};
|
||||
//# sourceMappingURL=paginate-1.js.map
|
||||
Reference in New Issue
Block a user