Skip to content

Commit 663fe73

Browse files
authored
Merge pull request #905 from andrykonchin/fix-priority-queue
Fix RubyNonConcurrentPriorityQueue#delete method
2 parents 19e1926 + cb2191f commit 663fe73

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

lib/concurrent-ruby/concurrent/collection/ruby_non_concurrent_priority_queue.rb

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def delete(item)
3030
if @queue[k] == item
3131
swap(k, @length)
3232
@length -= 1
33-
sink(k)
33+
sink(k) || swim(k)
3434
@queue.pop
3535
else
3636
k += 1
@@ -126,12 +126,17 @@ def ordered?(x, y)
126126
#
127127
# @!visibility private
128128
def sink(k)
129+
success = false
130+
129131
while (j = (2 * k)) <= @length do
130132
j += 1 if j < @length && ! ordered?(j, j+1)
131133
break if ordered?(k, j)
132134
swap(k, j)
135+
success = true
133136
k = j
134137
end
138+
139+
success
135140
end
136141

137142
# Percolate up to maintain heap invariant.
@@ -140,10 +145,15 @@ def sink(k)
140145
#
141146
# @!visibility private
142147
def swim(k)
148+
success = false
149+
143150
while k > 1 && ! ordered?(k/2, k) do
144151
swap(k, k/2)
145152
k = k/2
153+
success = true
146154
end
155+
156+
success
147157
end
148158
end
149159
end

spec/concurrent/collection/non_concurrent_priority_queue_spec.rb

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,41 @@
125125
it 'returns false when called on an empty queue' do
126126
expect(subject.delete(:foo)).to be_falsey
127127
end
128+
129+
def dequeue_all(queue)
130+
queue.size.times.inject([]) do |acc, _|
131+
acc << queue.pop
132+
end
133+
end
134+
135+
it 'deletes the requested item when it is "smaller" than the last element' do
136+
[
137+
100,
138+
9, 90,
139+
7, 8, 70, 80,
140+
3, 4, 5, 6, 30, 40, 50, 60
141+
].each do |item|
142+
subject << item
143+
end
144+
145+
subject.delete(8)
146+
147+
expect(subject.length).to eq 14
148+
expect(subject.pop).to eq 100
149+
expect(subject.pop).to eq 90
150+
expect(subject.pop).to eq 80
151+
expect(subject.pop).to eq 70
152+
expect(subject.pop).to eq 60
153+
expect(subject.pop).to eq 50
154+
expect(subject.pop).to eq 40
155+
expect(subject.pop).to eq 30
156+
expect(subject.pop).to eq 9
157+
expect(subject.pop).to eq 7
158+
expect(subject.pop).to eq 6
159+
expect(subject.pop).to eq 5
160+
expect(subject.pop).to eq 4
161+
expect(subject.pop).to eq 3
162+
end
128163
end
129164

130165
context '#empty?' do

0 commit comments

Comments
 (0)