97 lines
2.0 KiB
Lua

-- Lua queue implementation
-- based on "Queues and Double Queues" from `Programming in Lua`: http://www.lua.org/pil/11.4.html
-- modifications: changed naming conventions, added pop_at(), pop_multi(), iter_left(), iter_right(), and length()
local queue = {}
function queue.new()
return { first = 0, last = -1 }
end
function queue.push_left(tbl, value)
local first = tbl.first - 1
tbl.first = first
tbl[first] = value
end
function queue.push_right(tbl, value)
local last = tbl.last + 1
tbl.last = last
tbl[last] = value
end
function queue.pop_left(tbl)
local first = tbl.first
if first > tbl.last then
error("list is empty")
end
local value = tbl[first]
tbl[first] = nil -- to allow garbage collection
tbl.first = first + 1
return value
end
function queue.pop_right(tbl)
local last = tbl.last
if tbl.first > last then
error("list is empty")
end
local value = tbl[last]
tbl[last] = nil -- to allow garbage collection
tbl.last = last - 1
return value
end
-- use sparingly, has a similar overhead to table.remove()
function queue.pop_at(tbl, index)
local last = tbl.last
local value = tbl[index]
for i = index, last do
tbl[i] = tbl[i + 1]
end
tbl.last = last - 1
return value
end
-- even slower - use sparingly!
function queue.pop_multi(tbl, to_pop)
local lowest
local offset = 0
local values = {}
for id in pairs(to_pop) do
if not lowest or id < lowest then
values[id] = queue.pop_at(tbl, id)
lowest = id
else
values[id] = queue.pop_at(tbl, id - offset)
end
offset = offset + 1
end
return values
end
function queue.iter_left(tbl)
local i = tbl.first - 1
return function()
if i < tbl.last then
i = i + 1
return i, tbl[i]
end
end
end
function queue.iter_right(tbl)
local i = tbl.last + 1
return function()
if i > tbl.first then
i = i - 1
return i, tbl[i]
end
end
end
function queue.length(tbl)
return math.abs(tbl.last - tbl.first + 1)
end
return queue