-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathqueue.lua
More file actions
126 lines (103 loc) · 2.26 KB
/
Copy pathqueue.lua
File metadata and controls
126 lines (103 loc) · 2.26 KB
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
-- utils
local function mk_arr(n)
local arr = {}
for i = 0, n do table.insert(arr, 0) end
return arr
end
local function inc_mod(n, m)
return (n + 1) % m
end
local function log (fmt, ...)
print (string.format(fmt, ...))
end
local list = require 'list'
-- fixed queue
-- circular queues intensively use modulo arithmetic, so 0 based
-- indexing is more natural fit here
local function fq_new(size)
local size = size + 1
return { buff_ = mk_arr(size)
; beg_ = 0
; end_ = 0
; sz_ = size
}
end
local function fq_is_empty(q)
return q.beg_ == q.end_
end
local function fq_is_full(q)
return inc_mod(q.end_, q.sz_) == q.beg_
end
local function fq_front(q)
assert(not fq_is_empty(q), 'queue is empty')
return q.buff_[q.beg_]
end
local function fq_enqueue(q, val)
assert(not fq_is_full(q), 'queue is full')
q.buff_[q.end_] = val
q.end_ = inc_mod(q.end_, q.sz_)
end
local function fq_dequeue(q)
assert(not fq_is_empty(q), 'queue is empty')
local ret = fq_front(q)
q.beg_ = inc_mod(q.beg_, q.sz_)
return ret
end
-- queue
local function q_new()
return { beg_ = nil
; end_ = nil
}
end
local function q_is_empty(q)
return not q.end_
end
local function q_front(q)
assert(not q_is_empty(q), 'set queue is empty')
return list.first(q.end_)
end
local function q_enqueue(q, val)
local new_beg_ = list.new(val)
if q.beg_ then
list.rest_set(q.beg_, new_beg_);
q.beg_ = new_beg_
else
q.beg_ = new_beg_
q.end_ = new_beg_
end
end
local function q_dequeue(q)
assert(not q_is_empty(q), 'set queue is empty')
local ret = q_front(q)
q.end_ = list.rest(q.end_)
if not q.end_ then q.beg_ = nil end
return ret
end
-- iface
local fq_mtds = {
is_empty = fq_is_empty,
is_full = fq_is_full,
front = fq_front,
enqueue = fq_enqueue,
dequeue = fq_dequeue,
}
local q_mtds = {
is_empty = q_is_empty,
front = q_front,
enqueue = q_enqueue,
dequeue = q_dequeue
}
return {
fixed_queue_new = function(size)
size = size or 1
local q = fq_new(size)
setmetatable(q, { __index = fq_mtds })
return q
end
;
queue_new = function()
local q = q_new()
setmetatable(q, { __index = q_mtds })
return q
end
}