Skip to content

Commit b2c6a95

Browse files
authored
Merge pull request #771 from jonas-schulze/priorityqueue-push-popfirst
Deprecate enqueue!, dequeue! and peek for PriorityQueue
2 parents 3ca7420 + ce1dbe4 commit b2c6a95

File tree

6 files changed

+123
-95
lines changed

6 files changed

+123
-95
lines changed

docs/src/priority-queue.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,9 @@ Usage:
1414
```julia
1515
PriorityQueue{K, V}() # construct a new priority queue with keys of type K and priorities of type V (forward ordering by default)
1616
PriorityQueue{K, V}(ord) # construct a new priority queue with the given types and ordering ord (Base.Order.Forward or Base.Order.Reverse)
17-
enqueue!(pq, k, v) # insert the key k into pq with priority v
18-
enqueue!(pq, k=>v) # (same, using Pairs)
19-
dequeue!(pq) # remove and return the lowest priority key
20-
dequeue_pair!(pq) # remove and return the lowest priorty key and value
21-
peek(pq) # return the lowest priority key and value without removing it
17+
push!(pq, k=>v) # insert the key k into pq with priority v
18+
popfirst!(pq) # remove and return the lowest priority key and value
19+
first(pq) # return the lowest priority key and value without removing it
2220
delete!(pq, k) # delete the mapping for the given key in a priority queue, and return the priority queue.
2321
```
2422

@@ -28,8 +26,7 @@ inserted and priorities accessed or changed using indexing notation.
2826
Examples:
2927

3028
```jldoctest
31-
julia> # Julia code
32-
pq = PriorityQueue();
29+
julia> pq = PriorityQueue();
3330
3431
julia> # Insert keys with associated priorities
3532
pq["a"] = 10; pq["b"] = 5; pq["c"] = 15; pq
@@ -45,7 +42,9 @@ PriorityQueue{Any, Any, Base.Order.ForwardOrdering} with 3 entries:
4542
"b" => 5
4643
"c" => 15
4744
```
48-
It is also possible to iterate over the priorities and elements of the queue in sorted order.
45+
46+
It is also possible to iterate over the priorities and elements of the queue in sorted order.
47+
4948
```jldoctest
5049
julia> pq = PriorityQueue("a"=>2, "b"=>1, "c"=>3)
5150
PriorityQueue{String, Int64, Base.Order.ForwardOrdering} with 3 entries:
@@ -67,6 +66,7 @@ b
6766
a
6867
c
6968
```
69+
7070
```@meta
7171
DocTestSetup = nothing
7272
```

src/DataStructures.jl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ module DataStructures
55
isbitsunion, isiterable, dict_with_eltype, KeySet, Callable, _tablesz,
66
findnextnot, unsafe_getindex, unsafe_setindex!, peek
77

8+
# Exports for old version of julia where Base doesn't export this
9+
export peek
10+
export popat!
811

912
using Compat # Provides Base.Order.ReverseOrdering(). May remove this line with julia 1.4
1013
using OrderedCollections
@@ -15,7 +18,6 @@ module DataStructures
1518
export complement, complement!
1619

1720
export Deque, Stack, Queue, CircularDeque
18-
export enqueue!, dequeue!, dequeue_pair!, update!
1921
export capacity, num_blocks, top_with_handle, sizehint!
2022

2123
export Accumulator, counter, reset!, inc!, dec!
@@ -27,6 +29,7 @@ module DataStructures
2729
export MutableBinaryHeap, MutableBinaryMinHeap, MutableBinaryMaxHeap
2830
export heapify!, heapify, heappop!, heappush!, isheap
2931
export BinaryMinMaxHeap, popmin!, popmax!, popall!
32+
export update!
3033

3134
export Trie, subtrie, keys_with_prefix, partial_path, find_prefixes
3235

@@ -100,7 +103,7 @@ module DataStructures
100103
export status
101104
export deref_key, deref_value, deref, advance, regress
102105

103-
export PriorityQueue, peek
106+
export PriorityQueue
104107

105108
include("priorityqueue.jl")
106109
include("sparse_int_set.jl")

src/deprecations.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,16 @@ Base.@deprecate_binding IntDisjointSets IntDisjointSet
99
@deprecate DisjointSets(xs...) DisjointSet(xs)
1010
# Enqueue and dequeue deprecations
1111
@deprecate enqueue!(q::Queue, x) Base.push!(q, x)
12+
@deprecate enqueue!(q::PriorityQueue, x) Base.push!(q, x)
13+
@deprecate enqueue!(q::PriorityQueue, k, v) Base.push!(q, k=>v)
1214
@deprecate dequeue!(q::Queue) Base.popfirst!(q)
15+
@deprecate dequeue!(q::PriorityQueue) Base.popfirst!(q).first # maybe better: `val, _ = popfirst!(pq)`
16+
@deprecate dequeue!(q::PriorityQueue, x) popat!(q, x).first
17+
@deprecate dequeue_pair!(q::PriorityQueue) Base.popfirst!(q)
18+
@deprecate dequeue_pair!(q::PriorityQueue, key) popat!(q, key)
19+
20+
function Base.peek(q::PriorityQueue)
21+
Expr(:meta, :noinline)
22+
Base.depwarn("`peek(q::PriorityQueue)` is deprecated, use `first(q)` instead.", :peek)
23+
first(q)
24+
end

src/priorityqueue.jl

Lines changed: 27 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
PriorityQueue{K, V}([ord])
88
99
Construct a new [`PriorityQueue`](@ref), with keys of type
10-
`K` and values/priorites of type `V`.
10+
`K` and values/priorities of type `V`.
1111
If an order is not given, the priority queue is min-ordered using
1212
the default comparison for `V`.
1313
1414
A `PriorityQueue` acts like a `Dict`, mapping values to their
15-
priorities, with the addition of a `dequeue!` function to remove the
16-
lowest priority element.
15+
priorities. New elements are added using `push!` and retrieved
16+
using `popfirst!` or `popat!` based on their priority.
1717
1818
```jldoctest
1919
julia> PriorityQueue(Base.Order.Forward, "a" => 2, "b" => 3, "c" => 1)
@@ -117,12 +117,12 @@ Base.isempty(pq::PriorityQueue) = isempty(pq.xs)
117117
Base.haskey(pq::PriorityQueue, key) = haskey(pq.index, key)
118118

119119
"""
120-
peek(pq)
120+
first(pq)
121121
122122
Return the lowest priority key and value from a priority queue without removing that
123-
key from the queue.
123+
pair from the queue.
124124
"""
125-
Base.peek(pq::PriorityQueue) = pq.xs[1]
125+
Base.first(pq::PriorityQueue) = first(pq.xs)
126126

127127
function percolate_down!(pq::PriorityQueue, i::Integer)
128128
x = pq.xs[i]
@@ -183,14 +183,14 @@ end
183183
function Base.get!(pq::PriorityQueue, key, default)
184184
i = get(pq.index, key, 0)
185185
if i == 0
186-
enqueue!(pq, key, default)
186+
push!(pq, key=>default)
187187
return default
188188
else
189189
return pq.xs[i].second
190190
end
191191
end
192192

193-
# Change the priority of an existing element, or equeue it if it isn't present.
193+
# Change the priority of an existing element, or enqueue it if it isn't present.
194194
function Base.setindex!(pq::PriorityQueue{K, V}, value, key) where {K,V}
195195
i = get(pq.index, key, 0)
196196
if i != 0
@@ -202,32 +202,32 @@ function Base.setindex!(pq::PriorityQueue{K, V}, value, key) where {K,V}
202202
percolate_up!(pq, i)
203203
end
204204
else
205-
enqueue!(pq, key, value)
205+
push!(pq, key=>value)
206206
end
207207
return value
208208
end
209209

210210
"""
211-
enqueue!(pq, k=>v)
211+
push!(pq, k=>v)
212212
213213
Insert the a key `k` into a priority queue `pq` with priority `v`.
214214
215215
```jldoctest
216-
julia> a = PriorityQueue(PriorityQueue("a"=>1, "b"=>2, "c"=>3))
216+
julia> a = PriorityQueue("a"=>1, "b"=>2, "c"=>3)
217217
PriorityQueue{String, Int64, Base.Order.ForwardOrdering} with 3 entries:
218218
"a" => 1
219219
"b" => 2
220220
"c" => 3
221221
222-
julia> enqueue!(a, "d"=>4)
222+
julia> push!(a, "d"=>4)
223223
PriorityQueue{String, Int64, Base.Order.ForwardOrdering} with 4 entries:
224224
"a" => 1
225225
"b" => 2
226226
"c" => 3
227227
"d" => 4
228228
```
229229
"""
230-
function enqueue!(pq::PriorityQueue{K,V}, pair::Pair{K,V}) where {K,V}
230+
function Base.push!(pq::PriorityQueue{K,V}, pair::Pair{K,V}) where {K,V}
231231
key = pair.first
232232
if haskey(pq, key)
233233
throw(ArgumentError("PriorityQueue keys must be unique"))
@@ -239,44 +239,12 @@ function enqueue!(pq::PriorityQueue{K,V}, pair::Pair{K,V}) where {K,V}
239239
return pq
240240
end
241241

242-
"""
243-
enqueue!(pq, k, v)
244-
245-
Insert the a key `k` into a priority queue `pq` with priority `v`.
242+
Base.push!(pq::PriorityQueue{K,V}, kv::Pair) where {K,V} = push!(pq, Pair{K,V}(kv.first, kv.second))
246243

247244
"""
248-
enqueue!(pq::PriorityQueue, key, value) = enqueue!(pq, key=>value)
249-
enqueue!(pq::PriorityQueue{K,V}, kv) where {K,V} = enqueue!(pq, Pair{K,V}(kv.first, kv.second))
245+
popfirst!(pq)
250246
251-
"""
252-
dequeue!(pq)
253-
254-
Remove and return the lowest priority key from a priority queue.
255-
256-
```jldoctest
257-
julia> a = PriorityQueue(Base.Order.Forward, ["a" => 2, "b" => 3, "c" => 1])
258-
PriorityQueue{String, Int64, Base.Order.ForwardOrdering} with 3 entries:
259-
"c" => 1
260-
"a" => 2
261-
"b" => 3
262-
263-
julia> dequeue!(a)
264-
"c"
265-
266-
julia> a
267-
PriorityQueue{String, Int64, Base.Order.ForwardOrdering} with 2 entries:
268-
"a" => 2
269-
"b" => 3
270-
```
271-
"""
272-
dequeue!(pq::PriorityQueue) = dequeue_pair!(pq).first
273-
274-
dequeue!(pq::PriorityQueue, key) = dequeue_pair!(pq, key).first
275-
276-
"""
277-
dequeue_pair!(pq)
278-
279-
Remove and return a the lowest priority key and value from a priority queue as a pair.
247+
Remove and return the lowest priority key and value from a priority queue as a pair.
280248
281249
```jldoctest
282250
julia> a = PriorityQueue(Base.Order.Forward, "a" => 2, "b" => 3, "c" => 1)
@@ -285,7 +253,7 @@ PriorityQueue{String, Int64, Base.Order.ForwardOrdering} with 3 entries:
285253
"a" => 2
286254
"b" => 3
287255
288-
julia> dequeue_pair!(a)
256+
julia> popfirst!(a)
289257
"c" => 1
290258
291259
julia> a
@@ -294,7 +262,7 @@ PriorityQueue{String, Int64, Base.Order.ForwardOrdering} with 2 entries:
294262
"b" => 3
295263
```
296264
"""
297-
function dequeue_pair!(pq::PriorityQueue)
265+
function Base.popfirst!(pq::PriorityQueue)
298266
x = pq.xs[1]
299267
y = pop!(pq.xs)
300268
if !isempty(pq)
@@ -306,10 +274,14 @@ function dequeue_pair!(pq::PriorityQueue)
306274
return x
307275
end
308276

309-
function dequeue_pair!(pq::PriorityQueue, key)
277+
if isdefined(Base, :popat!) # We will overload if it is defined, else we define on our own
278+
import Base: popat!
279+
end
280+
281+
function popat!(pq::PriorityQueue, key)
310282
idx = pq.index[key]
311283
force_up!(pq, idx)
312-
dequeue_pair!(pq)
284+
popfirst!(pq)
313285
end
314286

315287
"""
@@ -330,7 +302,7 @@ PriorityQueue{String, Int64, Base.Order.ForwardOrdering} with 2 entries:
330302
```
331303
"""
332304
function Base.delete!(pq::PriorityQueue, key)
333-
dequeue_pair!(pq, key)
305+
popat!(pq, key)
334306
return pq
335307
end
336308

@@ -386,15 +358,15 @@ function Base.iterate(pq::PriorityQueue, ordered::Bool=true)
386358
if ordered
387359
isempty(pq) && return nothing
388360
state = _PQIteratorState(PriorityQueue(copy(pq.xs), pq.o, copy(pq.index)))
389-
return dequeue_pair!(state.pq), state
361+
return popfirst!(state.pq), state
390362
else
391363
_iterate(pq, iterate(pq.index))
392364
end
393365
end
394366

395367
function Base.iterate(pq::PriorityQueue, state::_PQIteratorState)
396368
isempty(state.pq) && return nothing
397-
return dequeue_pair!(state.pq), state
369+
return popfirst!(state.pq), state
398370
end
399371

400372
Base.iterate(pq::PriorityQueue, i) = _iterate(pq, iterate(pq.index, i))

test/test_deprecations.jl

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ end
4242
end
4343
end
4444

45-
@testset "enqueue! dequeue!" begin
45+
@testset "Queue enqueue! dequeue!" begin
4646
s = Queue{Int}(5)
4747
n = 100
4848

@@ -76,3 +76,43 @@ end
7676
@test length(s) == n - i
7777
end
7878
end
79+
80+
@testset "PriorityQueue enqueue! dequeue!" begin
81+
s = PriorityQueue{Int,Int}()
82+
n = 100
83+
84+
@test length(s) == 0
85+
@test isempty(s)
86+
@test_throws BoundsError first(s)
87+
@test_throws BoundsError dequeue!(s)
88+
89+
for i = 1 : n
90+
enqueue!(s, i=>i)
91+
@test first(s) == (1=>1)
92+
@test !isempty(s)
93+
@test length(s) == i
94+
end
95+
96+
for i = 1 : n
97+
x = dequeue!(s)
98+
@test x == i
99+
if i < n
100+
@test first(s) == (i+1 => i+1)
101+
else
102+
@test_throws BoundsError first(s)
103+
end
104+
@test isempty(s) == (i == n)
105+
@test length(s) == n - i
106+
end
107+
end
108+
109+
@testset "peek" begin
110+
pq = PriorityQueue{Int,Int}()
111+
push!(pq, 1 => 1)
112+
push!(pq, 2 => 2)
113+
@test peek(pq) == (1=>1)
114+
pq = PriorityQueue{Int,Int}()
115+
push!(pq, 2 => 2)
116+
push!(pq, 1 => 1)
117+
@test peek(pq) == (1=>1)
118+
end

0 commit comments

Comments
 (0)