Priority queues can be used for various tasks, such as for pathfinding (in Dijkstra-like algorithms) or simple decision making (which action to perform next). This implementation aims to be sufficiently fast for such tasks without compromising in useful functionality.
TIP: For heavy tasks, uncomment the line loading
test_perf.luafrominit.luaand runinit.luafrom the command line, preferably with LuaJIT, to check whether the mod performs with adequate speed.
API: 🔗
priority_queue:new(type) 🔗
Returns a priority queue of a specified type:
0: smaller priorities are more important1: larger priorities are more important2: simple version of03: simple version of1
If type is not specified, it defaults to 0.
The behaviour of simple versions is explained below, at the end of the section.
TIP: Internally, types
1and3are using types0and2as a base and wrapping some of their functions to negate priorities. Because of this, it is slighly faster to call the methods of type0and2queues with-priorityas an argument instead of calling the methods of types1and3withpriority. However, in practice the difference in negligible.
instance:insert(value, priority) 🔗
Inserts a value into the queue with the given priority. If the value already exists, its priority is updated instead.
Returns:
trueif thevalueis newfalseif thevaluealready exists
instance:extract() 🔗
Returns the value and priority of the most important element, in that order, removing the element from the queue. If the queue is empty, nil is returned instead.
instance:peek() 🔗
Acts like extract(), with the distinction that the element is not removed.
instance:search(value) 🔗
Tests whether the queue contains an element with the given value. If yes, returns true; otherwise returns false.
instance:delete(value) 🔗
Removes the element with the given value. Returns true on success, and false if the queue does not contain the given value.
instance:clear() 🔗
Removes all stored elements from the queue.
instance:size() 🔗
Returns the number of elements stored in the queue.
TIP: To avoid the overhead of a function call, it is possible to get the size by simply reading
instance._size. However, be careful to never write to it manually.
Simple versions 🔗
The implementation of the default queues comes with some helpful features, such as the ability to update priorities, and the option to remove arbitrary elements after insertion. Such features, however, come with a small performance overhead, which might prove to be a nuisance. For those situations, it is possible to opt out from the more advanced features for performance gains by using the simple versions of the queues. These versions function like their default counterparts, excluding the exceptions listed below:
insert()allows duplicates and will not update priorities.delete()andsearch()methods are disabled.
TIP: For reference, the simple versions seem to be about 13% faster.
Examples 🔗
Basic usage 🔗
local min_queue = priority_queue:new(0)
min_queue:insert("A", 2)
min_queue:insert("B", 1)
min_queue:insert("C", 3)
local value, priority = min_queue:extract()
print(value) -- prints "B"