Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

priority queue using RBTree

61 views
Skip to first unread message

Joel VanderWerf

unread,
Mar 9, 2005, 1:47:56 AM3/9/05
to
I couldn't find a nice PriorityQueue in ruby, so I patched one together
using Queue and RBTree. Here it is. Hope someone will find it useful. A
test of the priority ordering property is included. You can find RBTree
using RAA or rpa, but not gem.

require 'rbtree'
require 'thread'

class PriorityQueue < Queue
module MakeMultiRBTreeLikePriorityQueue
# Push object with priority specified by +pri+ or the object's
# #queue_priority method.
def push(obj, pri = obj.queue_priority)
store(pri, obj)
end

# Return oldest item among those with highest key.
def shift
last && delete(last[0])
end
end

def initialize(*)
super
@que = MultiRBTree.new
@que.extend MakeMultiRBTreeLikePriorityQueue
end

# Push +obj+ with priority equal to +pri+ if given or, otherwise,
# the result of sending #queue_priority to +obj+. Objects are
# dequeued in priority order, and first-in-first-out among objects
# with equal priorities. Implementation is the same as the std lib,
# except for the priority arg.
def push(obj, pri = obj.queue_priority)
Thread.critical = true
@que.push obj, pri
begin
t = @waiting.shift
t.wakeup if t
rescue ThreadError
retry
ensure
Thread.critical = false
end
begin
t.run if t
rescue ThreadError
end
end
end

__END__

Thread.abort_on_exception = true

pq = PriorityQueue.new

n = 100

t1 = Thread.new do
n.times do |i|
pri = rand(5)
pq.push([pri, i], pri)
end
end

result = []

t2 = Thread.new do
n.times do
result << pq.pop
end
end

t1.join
t2.join

#puts result.map {|a| a.inspect}.join("\n")

sorted_result = result.sort do |(pri1,i1),(pri2,i2)|
[pri2,i1] <=> [pri1,i2]
end

#puts sorted_result.map {|a| a.inspect}.join("\n")

raise unless result == sorted_result


Joel VanderWerf

unread,
Mar 9, 2005, 5:15:22 PM3/9/05
to
Ara.T....@noaa.gov wrote:
> On Wed, 9 Mar 2005, Joel VanderWerf wrote:
>
> very cool joel - i'm pasting this one into my personal lib. i use
> rbtree all
> the time and think it's one of the most underrated libs on the raa - i'd be
> great to see it in the core...

>
>> I couldn't find a nice PriorityQueue in ruby, so I patched one together
>> using Queue and RBTree. Here it is. Hope someone will find it useful. A
>> test of the priority ordering property is included. You can find RBTree
>> using RAA or rpa, but not gem.

Thanks! (And thanks for mailing directly--the gateway seems to be
list->ng only these days.)

I would also like rbtree in the stdlib... anyone else?

Btw, these aliases should be added to PriorityQueue for completeness, in
case you use << or enq:

alias << push
alias enq push


itsme213

unread,
Mar 10, 2005, 5:21:33 PM3/10/05
to

"Joel VanderWerf" <vj...@PATH.Berkeley.EDU> wrote

> I would also like rbtree in the stdlib... anyone else?

+1

Martin DeMello

unread,
Mar 11, 2005, 1:43:51 AM3/11/05
to
Joel VanderWerf <vj...@path.berkeley.edu> wrote:
>
> I would also like rbtree in the stdlib... anyone else?
+1

In fact, having a priority queue in there would be a nice idea too.

martin

0 new messages