1POE::Queue(3) User Contributed Perl Documentation POE::Queue(3)
2
3
4
6 POE::Queue - a flexible, generic priority queue API
7
9 POE::Queue specifies additional methods not illustrated here.
10
11 #!perl
12
13 use warnings;
14 use strict;
15 use POE::Queue::Array;
16
17 my $pqa = POE::Queue::Array->new();
18
19 # Enqueue a few items.
20
21 foreach my $priority (505, 404, 303, 202, 101) {
22 $pqa->enqueue($priority, "payload $priority");
23 }
24
25 # Dequeue until the queue is drained.
26
27 while (1) {
28 my ($priority, $queue_id, $payload) = $pqa->dequeue_next();
29 last unless defined $priority;
30
31 print(
32 "dequeued id($queue_id) ",
33 "priority($priority) ",
34 "payload($payload)\n",
35 );
36 }
37
38 Sample output:
39
40 dequeued id(5) priority(101) payload(payload 101)
41 dequeued id(4) priority(202) payload(payload 202)
42 dequeued id(3) priority(303) payload(payload 303)
43 dequeued id(2) priority(404) payload(payload 404)
44 dequeued id(1) priority(505) payload(payload 505)
45
47 Priority queues may be implemented a number of ways, but they tend to
48 behave similar to lists that are kept in order by some kind of
49 "priority". Enqueued items are stored such that the "next" item to be
50 retrieved is the one with the highest priority. Subsequent fetches
51 return the next lowest priority, and so on, until the queue is emptied.
52
53 Priority queues (also known as priority heaps) attempt to do this while
54 consuming the fewest resources. Go read about it! It's fascinating
55 stuff!
56
57 POE::Queue Items
58 POE::Queue items consist of three fields: A priority, a unique ID
59 assigned at enqueue time, and a payload. The priority and payload are
60 specified by the caller, and the unique ID is generated by POE::Queue
61 when an item is enqueued.
62
63 POE::Queue imposes two limitations on priorities: Priorities must be
64 numeric, and lower numbers indicate higher priorities. Aside from
65 that, POE::Queue doesn't care what the numbers mean.
66
67 Unique IDs are handles into the queue. POE::Queue generates and
68 returns them as new items are enqueued. Some methods manipulate items,
69 and they take IDs to identify the items to alter.
70
71 Item payloads are arbitrary application data. POE::Queue does not
72 examine or alter payloads itself. Any methods that need to examine
73 payloads will accept a filter function (see "Filter Functions").
74 Filter functions examine payloads so POE::Queue need not.
75
77 POE::Queue is an API specification. Subclasses like POE::Queue::Array
78 provide actual implementations.
79
80 new
81 Creates a new priority queue. Returns a reference to the queue.
82
83 my $queue = POE::Queue::Array->new();
84
85 enqueue PRIORITY, PAYLOAD
86 Enqueues a PAYLOAD, which can be just about anything that will fit into
87 a Perl scalar, at a particular PRIORITY level. enqueue() returns a
88 unique ID which can be used to manipulate the payload or its priority
89 directly.
90
91 Following the UNIX tradition, lower priority numbers indicate higher
92 priorities. The payload with the lowest priority number will be
93 dequeued first. If two payloads have the same PRIORITY, then they will
94 be dequeued in the order in which they were enqueued.
95
96 In this example, a queue is used to manage a number of alarms. The
97 "next" alarm will be the one due soonest.
98
99 my $payload_id = $queue->enqueue($alarm_time, [ "stuff" ]);
100
101 dequeue_next
102 Removes the next item from the queue, returning it as three fields:
103 priority, ID and payload.
104
105 The "next" item is the one with the lowest priority number. If
106 multiple items exist with the same priority, dequeue_next() will return
107 the one that was given the priority first.
108
109 ITEM: while (1) {
110 my ($priority, $id, $payload) = $queue->dequeue_next();
111 last ITEM unless defined $priority;
112 ...;
113 }
114
115 get_next_priority
116 Returns the priority of the item at the head of the queue. This is the
117 lowest numeric priority in the queue.
118
119 get_next_priority() can be useful for checking the queue to see if it's
120 time to dequeue some items. In this case, the queue manages multiple
121 alarms, and there's nothing to do if the next alarm isn't due yet.
122
123 ALARM: while (1) {
124 my $next_alarm_time = $queue->get_next_priority();
125 last ALARM unless defined $next_alarm_time;
126
127 if ($next_alarm_time - time() > 0) {
128 sleep($next_alarm_time - time());
129 }
130
131 my ($priority, $id, $payload) = $queue->dequeue_next();
132 ...;
133 }
134
135 get_item_count
136 Returns the number of items in the queue. It's another way to tell
137 whether the queue has been fully drained. Here's an alternative
138 version of the example for get_next_priority().
139
140 ALARM: while ($queue->get_item_count()) {
141 my $next_alarm_time = $queue->get_next_priority();
142 if ($next_alarm_time - time() > 0) {
143 sleep($next_alarm_time - time());
144 }
145
146 my ($priority, $id, $payload) = $queue->dequeue_next();
147 ...;
148 }
149
150 remove_item ITEM_ID, FILTER_FUNCTION
151 Removes a single item by its ID, but only if a FILTER_FUNCTION approves
152 of the item's payload.
153
154 If a payload is found with the given ITEM_ID, it is passed to
155 FILTER_FUNCTION for examination. If FILTER_FUNCTION returns true, the
156 item is removed from the queue and is returned as three fields.
157
158 my ($priority, $id, $payload) = $queue->remove_item(
159 $target_id, \&monkeys
160 );
161
162 sub monkeys {
163 my $payload = shift;
164 $payload->{type} eq "monkey";
165 }
166
167 The returned $priority will be undef on failure, and $! will be set to
168 the reason why the item couldn't be removed. That will be ESRCH if the
169 ITEM_ID was not found in the queue, or EPERM if the filter function
170 returned false.
171
172 remove_items FILTER_FUNCTION [, MAX_ITEM_COUNT ]
173 Removes and returns items from the queue that match a FILTER_FUNCTION.
174 remove_items() will return immediately if MAX_ITEM_COUNT items is
175 specified and that many items have been removed from the queue.
176 MAX_ITEM_COUNT is a bit of optimization if the application knows in
177 advance how many items will match the FILTER_FUNCTION.
178
179 Returns a list of items that were removed. Each item is an array
180 reference containing a priority, item ID, and payload. Returns nothing
181 if FILTER_FUNCTION matched nothing.
182
183 # Remove up to 12 monkeys.
184 my @monkeys = $queue->remove_items(\&monkeys, 12);
185 foreach my $monkey (@monkeys) {
186 my ($priority, $id, $payload) = @$monkey;
187 print(
188 "Removed monkey:\n",
189 " priority = $priority\n",
190 " queue id = $id\n",
191 " payload = $payload\n",
192 );
193 }
194
195 There is no guarantee which items will be removed if MAX_ITEM_COUNT is
196 specified too low.
197
198 See "Filter Functions" for more details about filter functions.
199
200 peek_items FILTER_FUNCTION [, MAX_ITEM_COUNT ]
201 peek_items() returns up to MAX_ITEM_COUNT items that match a given
202 FILTER_FUNCTION without removing them from the queue.
203
204 my @entire_queue = $queue->peek_items(sub { 1 });
205 foreach my $item (@entire_queue) {
206 my ($priority, $id, $payload) = @$item;
207 print(
208 "Item:\n",
209 " priority = $priority\n",
210 " queue id = $id\n",
211 " payload = $payload\n",
212 );
213 }
214
215 adjust_priority ITEM_ID, FILTER_FUNCTION, DELTA
216 Changes the priority of an item by DELTA. The item is identified by
217 its ITEM_ID, and the change will only happen if the item's payload
218 satisfies a FILTER_FUNCTION. Returns the new priority, which is the
219 previous priority + DELTA. DELTA may be negative.
220
221 my $new_priority = $queue->adjust_priority(
222 $item_id, \&one_of_mine, 100
223 );
224
225 sub one_of_mine {
226 my $payload = shift;
227 return $payload->{owner} == $me;
228 }
229
230 Returns undef if the item's priority could not be adjusted, and sets $!
231 to explain why: ESRCH means that the ITEM_ID could not be found, and
232 EPERM means that the FILTER_FUNCTION was not satisfied.
233
234 set_priority ITEM_ID, FILTER_FUNCTION, ABSOLUTE_PRIORITY
235 Sets an item's priority to a new ABSOLUTE_PRIORITY. The item is
236 identified by its ITEM_ID, and the change will only be allowed to
237 happen if the item's payload satisfies a FILTER_FUNCTION. Returns the
238 new priority, which should match ABSOLUTE_PRIORITY.
239
240 Returns undef if the item's priority could not be set, and sets $! to
241 explain why: ESRCH means that the ITEM_ID could not be found, and EPERM
242 means that the FILTER_FUNCTION was not satisfied.
243
244 my $new_priority = $queue->set_priority(
245 $item_id, \&one_of_mine, time() + 60
246 );
247
248 unless (defined $new_priority) {
249 die "one of our submarines is missing: $item_id" if $! == ESRCH;
250 die "set_priority disallowed for item $item_id" if $! == EPERM;
251 die $!;
252 }
253
254 sub one_of_mine {
255 $_[0]{owner} == $me;
256 }
257
259 POE, POE::Queue::Array
260
262 None known.
263
264 TODO - Should set_priority return the old priority instead of the new
265 one?
266
267 TODO - Rename and repackage as its own distribution.
268
270 Please see POE for more information about authors, contributors, and
271 POE's licensing.
272
273
274
275perl v5.12.1 2010-04-03 POE::Queue(3)