-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpqueue.lua
More file actions
92 lines (82 loc) · 1.55 KB
/
pqueue.lua
File metadata and controls
92 lines (82 loc) · 1.55 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
local ti = table.insert
local tr = table.remove
local tr2 = function(t, v)
for i=1,#t do
if t[i]==v then
tr(t, i)
break
end
end
end
return function ()
local t = {}
-- a set of elements
local set = {}
-- a set of priorities paired with a elements
local r_set = {}
-- sorted list of priorities
local keys = {}
-- add element into storage and set its priority and sort keys
local function addKV(k, v)
set[k] = v
if not r_set[v] then
ti(keys, v)
table.sort(keys)
local k0 = {k}
r_set[v] = k0
setmetatable(k0, {
__mode = 'v'
})
else
ti(r_set[v], k)
end
end
-- remove element from storage and sort keys
local remove = function(k)
local v = set[k]
local prioritySet = r_set[v]
tr2(prioritySet, k)
if #prioritySet < 1 then
tr2(keys, v)
r_set[v] = nil
table.sort(keys)
set[k] = nil
end
end; t.remove = remove
-- returns an element with the lowest priority
t.min = function()
local priority = keys[1]
if priority then
return r_set[priority] or {}
else
return {}
end
end
-- returns an element with the highest priority
t.max = function()
local priority = keys[#keys]
if priority then
return r_set[priority] or {}
else
return {}
end
end
-- is this queue empty?
t.empty = function()
return #keys < 1
end
setmetatable(t, {
__index = set,
__newindex = function(t, k, v)
if not set[k] then
-- new item
addKV(k, v)
else
-- existing item
remove(k)
addKV(k, v)
end
end,
})
return t
end