-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathqueue.lua
84 lines (75 loc) · 2.19 KB
/
queue.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
--- Fixed-size queue implemented as a circular buffer
local queue = {}
--- Create a new fixed-size queue
-- @param capacity The limit on the number of items that may be added
-- to the queue. Once this limit is hit, adding a new
-- item will drop the oldest in the queue.
function queue:new(capacity)
return setmetatable(
{
_data = {},
_capacity = capacity,
_head = 0
}, {
__index = function(t, k)
if type(k) == "number" then
return t:get(k)
else
return self[k]
end
end
})
end
--- Return the number of items in the queue.
function queue:getn()
return #self._data
end
--- Fetch an item in the queue by index.
-- You can also index the queue itself. If no item exists at the
-- given index, returns nil.
-- @param i The integer index in the queue, starting at 1.
-- @return The element at index `i`, or nil.
function queue:get(i)
local q_i = (self._head - i) % self._capacity
return self._data[q_i+1]
end
--- Add a new item to the head of the queue.
-- When the queue has reached capacity, this will remove the oldest
-- queued item.
-- @param item The item to be added.
function queue:put(item)
self._data[self._head+1] = item
self._head = (self._head + 1) % self._capacity
end
--- Queue iterator.
-- Iterates over the queue, from newest to oldest.
-- Note: modification of the queue during iteration can lead to
-- undefined behavior.
-- @return An iterator over the elements of this queue.
function queue:elements()
local start
local idx = (self._head - 1) % self._capacity
local function it(t)
if idx == start then
return nil
end
start = start or idx
local value = t[idx+1]
idx = (idx - 1) % self._capacity
return value
end
return it, self._data
end
--- Build an array representation of the queue.
-- @return A new array with the elements of the queue.
function queue:as_array()
local arr = {}
for el in self:elements() do
arr[#arr+1] = el
end
return arr
end
function queue:to_string()
return string.format('{ %s }', table.concat(self:as_array(), ', '))
end
return queue